Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .nextchanges/air/7640.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* `air convert-to-dabs` now suggests the `--output-dir` that converts a workload whose `code_source.root_path` is outside the bundle directory, instead of suggesting `sync.paths`. ([#7640](https://github.com/databricks/cli/pull/7640))
8 changes: 7 additions & 1 deletion cmd/air/convert_to_dabs.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,13 @@ func bundleCodeSourcePath(ctx context.Context, cfg *runConfig, configPath, bundl
}
rel, err := filepath.Rel(bundleAbs, root)
if err != nil || !filepath.IsLocal(rel) {
return "", fmt.Errorf("code_source root_path %q is not inside the bundle directory %q; bundle deploy can only upload files under the bundle's sync root. Move the code inside the bundle, or set sync.paths in databricks.yml to a directory that contains both (note that widens what gets synced)", snap.RootPath, bundleDir)
remedy := "move the code inside the bundle directory"
// As in codeArtifactFor, only a working-tree snapshot can be bundled from a
// parent directory of the code.
if snap.Git == nil {
remedy = fmt.Sprintf("pass --output-dir %s to write the bundle to the code directory's parent, or %s", filepath.Dir(root), remedy)
}
return "", fmt.Errorf("code_source root_path %q (%s) is not inside the bundle directory %q, and bundle deploy only packages code inside the bundle; %s", snap.RootPath, root, bundleDir, remedy)
}
return localBundlePath(filepath.ToSlash(rel)), nil
}
Expand Down
46 changes: 46 additions & 0 deletions cmd/air/convert_to_dabs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -729,3 +729,49 @@ func TestConvertToDabsRejectsUnsupported(t *testing.T) {
require.ErrorContains(t, err, "usage_policy_name is not yet supported")
})
}

// The getting-started Ray layout: the workload in ray/core snapshots its parent so it
// can include the shared ray/ray_bootstrap.sh. The error names an --output-dir that
// converts, and does not suggest editing a databricks.yml that was never written.
func TestConvertToDabsCodeOutsideBundleSuggestsOutputDir(t *testing.T) {
dir := t.TempDir()
recipe := filepath.Join(dir, "ray", "core")
require.NoError(t, os.MkdirAll(recipe, 0o700))
require.NoError(t, os.WriteFile(filepath.Join(dir, "ray", "ray_bootstrap.sh"), []byte("#!/bin/bash\n"), 0o600))
cfg := "experiment_name: ray-core\ncommand: bash ray_bootstrap.sh\n" +
"compute: {accelerator_type: GPU_1xA10, num_accelerators: 2}\n" +
"code_source:\n root_path: ..\n include_paths: [ray_bootstrap.sh, core]\n"
path := filepath.Join(recipe, "workload.yaml")
require.NoError(t, os.WriteFile(path, []byte(cfg), 0o600))
loaded, err := loadRunConfig(path)
require.NoError(t, err)

_, _, err = convertToDabs(t.Context(), loaded, path, recipe)
require.ErrorContains(t, err, "not inside the bundle")
assert.Contains(t, err.Error(), "--output-dir "+dir+" ")
assert.NotContains(t, err.Error(), "sync.paths")

root, _, err := convertToDabs(t.Context(), loaded, path, dir)
require.NoError(t, err)
inc := get(t, root, "artifacts."+codeSourceArtifactKey+".include").MustSequence()
require.Len(t, inc, 2)
assert.Equal(t, "ray/ray_bootstrap.sh", inc[0].MustString())
assert.Equal(t, "ray/core", inc[1].MustString())
}

// A git-pinned snapshot is archived from the bundle root, so a parent directory is
// not offered as the bundle root.
func TestConvertToDabsGitPinOutsideBundleDoesNotSuggestOutputDir(t *testing.T) {
outside := t.TempDir()
require.NoError(t, os.MkdirAll(filepath.Join(outside, "src"), 0o700))
cfg := "experiment_name: outside\ncommand: python train.py\n" +
"compute: {accelerator_type: GPU_1xH100, num_accelerators: 1}\n" +
"code_source:\n root_path: " + filepath.Join(outside, "src") + "\n git:\n commit: abc123\n"
path := writeConfigFile(t, "run.yaml", cfg)
loaded, err := loadRunConfig(path)
require.NoError(t, err)

_, _, err = convertToDabs(t.Context(), loaded, path, filepath.Dir(path))
require.ErrorContains(t, err, "not inside the bundle")
assert.NotContains(t, err.Error(), "--output-dir")
}
Loading