diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 88f45aac96..3185d4733b 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -10,5 +10,6 @@ ### Bundles * Add validation that served_models and served_entities are not used at the same time. Add client side translation logic. ([#3880](https://github.com/databricks/cli/pull/3880)) +* Allow `file://` URIs in job libraries to reference runtime filesystem paths (e.g., JARs pre-installed on clusters via init scripts). These paths are no longer treated as local files to upload. ([#3884](https://github.com/databricks/cli/pull/3884)) ### API Changes diff --git a/bundle/libraries/local_path.go b/bundle/libraries/local_path.go index 543c8d2d68..c05df2bcb6 100644 --- a/bundle/libraries/local_path.go +++ b/bundle/libraries/local_path.go @@ -16,17 +16,18 @@ import ( // - myfile.txt // - ./myfile.txt // - ../myfile.txt -// - file:///foo/bar/myfile.txt // // The following paths are considered remote: // +// - file:///opt/spark/jars/myfile.jar // - dbfs:/mnt/myfile.txt // - s3:/mybucket/myfile.txt // - /Users/jane@doe.com/myfile.txt func IsLocalPath(p string) bool { - // If the path has the explicit file scheme, it's a local path. + // If the path has the file:// scheme, it's a runtime path (remote). + // Users should use relative paths without scheme for local files to upload. if strings.HasPrefix(p, "file://") { - return true + return false } // If the path has another scheme, it's a remote path. diff --git a/bundle/libraries/local_path_test.go b/bundle/libraries/local_path_test.go index bca8d7ad9f..5c90472944 100644 --- a/bundle/libraries/local_path_test.go +++ b/bundle/libraries/local_path_test.go @@ -8,22 +8,30 @@ import ( ) func TestIsLocalPath(t *testing.T) { - // Relative paths, paths with the file scheme, and Windows paths. + // Relative paths and Windows paths (local files to upload). assert.True(t, IsLocalPath("some/local/path")) assert.True(t, IsLocalPath("./some/local/path")) - assert.True(t, IsLocalPath("file://path/to/package")) assert.True(t, IsLocalPath("C:\\path\\to\\package")) assert.True(t, IsLocalPath("myfile.txt")) assert.True(t, IsLocalPath("./myfile.txt")) assert.True(t, IsLocalPath("../myfile.txt")) - assert.True(t, IsLocalPath("file:///foo/bar/myfile.txt")) - // Absolute paths. + // Absolute paths without scheme (remote). assert.False(t, IsLocalPath("/some/full/path")) assert.False(t, IsLocalPath("/Workspace/path/to/package")) assert.False(t, IsLocalPath("/Users/path/to/package")) - // Paths with schemes. + // file:// URIs are runtime paths (remote - not uploaded). + assert.False(t, IsLocalPath("file:///foo/bar/myfile.txt")) + assert.False(t, IsLocalPath("file:///opt/spark/jars/driver.jar")) + assert.False(t, IsLocalPath("file:///")) + assert.False(t, IsLocalPath("file:///absolute/path")) + assert.False(t, IsLocalPath("file://path/to/package")) + assert.False(t, IsLocalPath("file://foo/bar/myfile.txt")) + assert.False(t, IsLocalPath("file://./relative.jar")) + assert.False(t, IsLocalPath("file://../lib/package.whl")) + + // Paths with other schemes (remote). assert.False(t, IsLocalPath("dbfs://path/to/package")) assert.False(t, IsLocalPath("dbfs:/path/to/package")) assert.False(t, IsLocalPath("s3://path/to/package")) @@ -47,7 +55,6 @@ func TestIsLibraryLocal(t *testing.T) { {path: ".\\..\\local\\*.whl", expected: true}, {path: "../../local/*.whl", expected: true}, {path: "..\\..\\local\\*.whl", expected: true}, - {path: "file://path/to/package/whl.whl", expected: true}, {path: "local/foo-bar.whl", expected: true}, {path: "", expected: false},