Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Source-linked deployments for bundles in the workspace #1884

Merged
merged 37 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
6b22fde
Prototype for in-place deployments in DEV mode
ilyakuz-db Nov 5, 2024
ae26bea
Merge branch 'main' of github.com:databricks/cli into tmp/in-place-pr…
ilyakuz-db Nov 5, 2024
fbb9be9
fix: Add SyncRoot mock to tests
ilyakuz-db Nov 5, 2024
086dfbc
Merge branch 'main' of github.com:databricks/cli into tmp/in-place-pr…
ilyakuz-db Nov 11, 2024
a43f7dd
feat: Use global FilePath instead of locally overriden paths
ilyakuz-db Nov 11, 2024
5a22151
feat: Move FilePath update to apply preset step
ilyakuz-db Nov 12, 2024
6c12308
Merge branch 'main' of github.com:databricks/cli into tmp/in-place-pr…
ilyakuz-db Nov 12, 2024
b2164c0
fix: Use SyncRootPath to allow using parent directories
ilyakuz-db Nov 12, 2024
0004ed2
Merge branch 'main' of github.com:databricks/cli into tmp/in-place-pr…
ilyakuz-db Nov 14, 2024
26f2453
feat: Use dbr package for runtime check
ilyakuz-db Nov 14, 2024
51c8ef5
fix: Applies autoformat
ilyakuz-db Nov 14, 2024
4cf6929
fix: Missing root variable
ilyakuz-db Nov 14, 2024
8cd95eb
test: Apply presets unit test
ilyakuz-db Nov 15, 2024
e9b7289
test: Process target mode
ilyakuz-db Nov 15, 2024
a3c6d57
fix: Use SyncRootPath
ilyakuz-db Nov 18, 2024
80ea3a0
fix: Move SyncRoot field to the top og the struct
ilyakuz-db Nov 18, 2024
e7165ec
feat: Add Databricks Workspace conditions to dev mode setting. Add wa…
ilyakuz-db Nov 18, 2024
49f6bc9
fix: Skipping in-place tests on Windows
ilyakuz-db Nov 18, 2024
e65b50c
fix: Wrong condition
ilyakuz-db Nov 18, 2024
53e1f6d
fix: Skip permissions set and check for in-place
ilyakuz-db Nov 18, 2024
00bb683
fix: Remove unnecessary fields in apply presets test
ilyakuz-db Nov 18, 2024
e8825d5
fix: Reuse existing `root` variable
ilyakuz-db Nov 18, 2024
1d7b27e
feat: Rename "in-place" to "source-linked"
ilyakuz-db Nov 18, 2024
55f715d
fix: Broken test
ilyakuz-db Nov 18, 2024
518aa14
Revert "fix: Skip permissions set and check for in-place"
ilyakuz-db Nov 18, 2024
aeb9813
feat: Use path translations instead of overriding config
ilyakuz-db Nov 19, 2024
8c8fb35
fix: Add explicit warning when using python wheel wrappers with sourc…
ilyakuz-db Nov 19, 2024
234d971
fix: Cleanup in test
ilyakuz-db Nov 19, 2024
5d09070
fix: Cleanup
ilyakuz-db Nov 19, 2024
8ee8de5
test: Added path translation test cases for source-linked
ilyakuz-db Nov 19, 2024
5d04569
fix: Windows tests
ilyakuz-db Nov 19, 2024
530a2a9
fix: Skipping path translation tests for windows
ilyakuz-db Nov 19, 2024
aba35ae
fix: Replaced diag warning message with logger and removed unnecessar…
ilyakuz-db Nov 19, 2024
ddb68a7
fix: Update skip uploading log entry with more clear message
ilyakuz-db Nov 20, 2024
eede522
Update bundle/config/presets.go
ilyakuz-db Nov 20, 2024
6a036d1
Merge branch 'tmp/in-place-prototype' of github.com:databricks/cli in…
ilyakuz-db Nov 20, 2024
66bf5f3
fix: Use warning instead of log in python wheel wrapper message
ilyakuz-db Nov 20, 2024
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
10 changes: 10 additions & 0 deletions bundle/config/mutator/apply_presets.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/databricks/cli/bundle"
"github.com/databricks/cli/bundle/config"
"github.com/databricks/cli/libs/dbr"
"github.com/databricks/cli/libs/diag"
"github.com/databricks/cli/libs/dyn"
"github.com/databricks/cli/libs/textutil"
Expand Down Expand Up @@ -221,6 +222,15 @@ func (m *applyPresets) Apply(ctx context.Context, b *bundle.Bundle) diag.Diagnos
dashboard.DisplayName = prefix + dashboard.DisplayName
}

if config.IsExplicitlyEnabled((b.Config.Presets.SourceLinkedDeployment)) {
isDatabricksWorkspace := dbr.RunsOnRuntime(ctx) && strings.HasPrefix(b.SyncRootPath, "/Workspace/")
if !isDatabricksWorkspace {
disabled := false
b.Config.Presets.SourceLinkedDeployment = &disabled
diags = diags.Extend(diag.Warningf("source-linked deployment is available only in the Databricks Workspace"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warnings should include position/file/line information where possible.

This condition triggers only if the user explicitly configured the setting, so we should have this information. You can call b.Config.GetLocations() with the path to the setting to get these.

Not blocking for this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have this setting in targets.[target].presets.source_linked_deployment and this should be in the config indeed in that case, but we have nil in b.Config.Targets which makes location lookup not possible

It is assigned here

b.Config.Targets = nil

I can try to remove this nil assingment from there, not sure why it is needed. If I remove this line locations are available

Also we can show something like this without locations
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should just be able to use the locations from top-level presets.source_linked_deployment. That should include the target override locations as well IIRC.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That works indeed, thanks!

image

Will make another PR later

}
}

return diags
}

Expand Down
85 changes: 85 additions & 0 deletions bundle/config/mutator/apply_presets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package mutator_test

import (
"context"
"runtime"
"testing"

"github.com/databricks/cli/bundle"
"github.com/databricks/cli/bundle/config"
"github.com/databricks/cli/bundle/config/mutator"
"github.com/databricks/cli/bundle/config/resources"
"github.com/databricks/cli/libs/dbr"
"github.com/databricks/databricks-sdk-go/service/catalog"
"github.com/databricks/databricks-sdk-go/service/jobs"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -364,3 +366,86 @@ func TestApplyPresetsResourceNotDefined(t *testing.T) {
})
}
}

func TestApplyPresetsSourceLinkedDeployment(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("this test is not applicable on Windows because source-linked mode works only in the Databricks Workspace")
}

testContext := context.Background()
enabled := true
disabled := false
workspacePath := "/Workspace/[email protected]"

tests := []struct {
bundlePath string
ctx context.Context
name string
initialValue *bool
expectedValue *bool
expectedWarning string
}{
{
name: "preset enabled, bundle in Workspace, databricks runtime",
bundlePath: workspacePath,
ctx: dbr.MockRuntime(testContext, true),
initialValue: &enabled,
expectedValue: &enabled,
},
{
name: "preset enabled, bundle not in Workspace, databricks runtime",
bundlePath: "/Users/[email protected]",
ctx: dbr.MockRuntime(testContext, true),
initialValue: &enabled,
expectedValue: &disabled,
expectedWarning: "source-linked deployment is available only in the Databricks Workspace",
},
{
name: "preset enabled, bundle in Workspace, not databricks runtime",
bundlePath: workspacePath,
ctx: dbr.MockRuntime(testContext, false),
initialValue: &enabled,
expectedValue: &disabled,
expectedWarning: "source-linked deployment is available only in the Databricks Workspace",
},
{
name: "preset disabled, bundle in Workspace, databricks runtime",
bundlePath: workspacePath,
ctx: dbr.MockRuntime(testContext, true),
initialValue: &disabled,
expectedValue: &disabled,
},
{
name: "preset nil, bundle in Workspace, databricks runtime",
bundlePath: workspacePath,
ctx: dbr.MockRuntime(testContext, true),
initialValue: nil,
expectedValue: nil,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b := &bundle.Bundle{
SyncRootPath: tt.bundlePath,
Config: config.Root{
Presets: config.Presets{
SourceLinkedDeployment: tt.initialValue,
},
},
}

diags := bundle.Apply(tt.ctx, b, mutator.ApplyPresets())
if diags.HasError() {
t.Fatalf("unexpected error: %v", diags)
}

if tt.expectedWarning != "" {
require.Equal(t, tt.expectedWarning, diags[0].Summary)
}

require.Equal(t, tt.expectedValue, b.Config.Presets.SourceLinkedDeployment)
})
}

}
9 changes: 9 additions & 0 deletions bundle/config/mutator/process_target_mode.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/databricks/cli/bundle"
"github.com/databricks/cli/bundle/config"
"github.com/databricks/cli/libs/dbr"
"github.com/databricks/cli/libs/diag"
"github.com/databricks/cli/libs/dyn"
"github.com/databricks/cli/libs/iamutil"
Expand Down Expand Up @@ -57,6 +58,14 @@ func transformDevelopmentMode(ctx context.Context, b *bundle.Bundle) {
t.TriggerPauseStatus = config.Paused
}

if !config.IsExplicitlyDisabled(t.SourceLinkedDeployment) {
isInWorkspace := strings.HasPrefix(b.SyncRootPath, "/Workspace/")
if isInWorkspace && dbr.RunsOnRuntime(ctx) {
enabled := true
t.SourceLinkedDeployment = &enabled
}
}

pietern marked this conversation as resolved.
Show resolved Hide resolved
if !config.IsExplicitlyDisabled(t.PipelinesDevelopment) {
enabled := true
t.PipelinesDevelopment = &enabled
Expand Down
33 changes: 33 additions & 0 deletions bundle/config/mutator/process_target_mode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ package mutator
import (
"context"
"reflect"
"runtime"
"strings"
"testing"

"github.com/databricks/cli/bundle"
"github.com/databricks/cli/bundle/config"
"github.com/databricks/cli/bundle/config/resources"
"github.com/databricks/cli/libs/dbr"
"github.com/databricks/cli/libs/diag"
"github.com/databricks/cli/libs/tags"
"github.com/databricks/cli/libs/vfs"
sdkconfig "github.com/databricks/databricks-sdk-go/config"
"github.com/databricks/databricks-sdk-go/service/catalog"
"github.com/databricks/databricks-sdk-go/service/compute"
Expand Down Expand Up @@ -133,6 +136,7 @@ func mockBundle(mode config.Mode) *bundle.Bundle {
},
},
},
SyncRoot: vfs.MustNew("/Users/[email protected]"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably fails on Windows.

Copy link
Contributor Author

@ilyakuz-db ilyakuz-db Nov 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added skipping for windows since we don't need to test the behavior there (unless I'm missing something)

// Use AWS implementation for testing.
Tagging: tags.ForCloud(&sdkconfig.Config{
Host: "https://company.cloud.databricks.com",
Expand Down Expand Up @@ -515,3 +519,32 @@ func TestPipelinesDevelopmentDisabled(t *testing.T) {

assert.False(t, b.Config.Resources.Pipelines["pipeline1"].PipelineSpec.Development)
}

func TestSourceLinkedDeploymentEnabled(t *testing.T) {
b, diags := processSourceLinkedBundle(t, true)
require.NoError(t, diags.Error())
assert.True(t, *b.Config.Presets.SourceLinkedDeployment)
}

func TestSourceLinkedDeploymentDisabled(t *testing.T) {
b, diags := processSourceLinkedBundle(t, false)
require.NoError(t, diags.Error())
assert.False(t, *b.Config.Presets.SourceLinkedDeployment)
}

func processSourceLinkedBundle(t *testing.T, presetEnabled bool) (*bundle.Bundle, diag.Diagnostics) {
if runtime.GOOS == "windows" {
t.Skip("this test is not applicable on Windows because source-linked mode works only in the Databricks Workspace")
}

b := mockBundle(config.Development)

workspacePath := "/Workspace/[email protected]/"
b.SyncRootPath = workspacePath
b.Config.Presets.SourceLinkedDeployment = &presetEnabled

ctx := dbr.MockRuntime(context.Background(), true)
m := bundle.Seq(ProcessTargetMode(), ApplyPresets())
diags := bundle.Apply(ctx, b, m)
return b, diags
}
10 changes: 8 additions & 2 deletions bundle/config/mutator/translate_paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"strings"

"github.com/databricks/cli/bundle"
"github.com/databricks/cli/bundle/config"
"github.com/databricks/cli/libs/diag"
"github.com/databricks/cli/libs/dyn"
"github.com/databricks/cli/libs/notebook"
Expand Down Expand Up @@ -103,8 +104,13 @@ func (t *translateContext) rewritePath(
return fmt.Errorf("path %s is not contained in sync root path", localPath)
}

// Prefix remote path with its remote root path.
remotePath := path.Join(t.b.Config.Workspace.FilePath, filepath.ToSlash(localRelPath))
var workspacePath string
if config.IsExplicitlyEnabled(t.b.Config.Presets.SourceLinkedDeployment) {
workspacePath = t.b.SyncRootPath
} else {
workspacePath = t.b.Config.Workspace.FilePath
}
remotePath := path.Join(workspacePath, filepath.ToSlash(localRelPath))

// Convert local path into workspace path via specified function.
interp, err := fn(*p, localPath, localRelPath, remotePath)
Expand Down
Loading
Loading