Skip to content

Commit ee860e8

Browse files
bundle/deploy/lock: replace DeploymentManager interface with concrete DeploymentLock
Remove the DeploymentManager interface and CreateVersion/CompleteVersion methods. Replace with a concrete DeploymentLock type backed by the workspace-filesystem lock, with Acquire/Release methods. DMS version tracking will be added additively alongside the file lock in a follow-up — no interface needed since both operations happen inside Acquire/Release on the same type. Co-authored-by: Shreyas Goenka <shreyas.goenka@databricks.com>
1 parent a9c1407 commit ee860e8

5 files changed

Lines changed: 53 additions & 60 deletions

File tree

bundle/deploy/lock/lock.go

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,43 +26,43 @@ const (
2626
DeploymentFailure
2727
)
2828

29-
// DeploymentManager controls the versioned lifecycle of deployment operations.
30-
//
31-
// DMS semantics: CreateVersion atomically succeeds only if no other deployment
32-
// is in progress and the returned version is exactly +1 to the latest closed
33-
// version, providing serialized optimistic concurrency control. CompleteVersion
34-
// records the outcome.
35-
//
36-
// Workspace-filesystem semantics: CreateVersion acquires the workspace lock
37-
// file; CompleteVersion releases it. The returned version number is a placeholder
38-
// (the lock file does not track a monotonic counter today).
39-
type DeploymentManager interface {
40-
// CreateVersion begins a new deployment for the given goal.
41-
// Returns the version number assigned by the backend.
42-
CreateVersion(ctx context.Context, goal Goal) (int64, error)
43-
44-
// CompleteVersion finalizes the deployment version created by CreateVersion.
45-
CompleteVersion(ctx context.Context, version int64, status DeploymentStatus) error
29+
// DeploymentLock manages the lifecycle of a bundle deployment.
30+
// The workspace-filesystem lock serializes concurrent deployments.
31+
// DMS version tracking will be added additively — see deployment_metadata_service.go.
32+
type DeploymentLock struct {
33+
wfs workspaceFilesystemLock
4634
}
4735

48-
// NewDeploymentManager returns a DeploymentManager backed by the workspace
49-
// filesystem. Captures everything it needs from the bundle at construction time
50-
// so the implementation does not retain a *bundle.Bundle reference. The
51-
// workspace client is only initialized when locking is enabled to match the
52-
// original lazy-init behavior.
53-
func NewDeploymentManager(ctx context.Context, b *bundle.Bundle) DeploymentManager {
36+
// NewDeploymentLock returns a DeploymentLock for the bundle.
37+
// Captures everything it needs from the bundle at construction time
38+
// so the lock does not retain a *bundle.Bundle reference. The
39+
// workspace client is only initialized when locking is enabled.
40+
func NewDeploymentLock(ctx context.Context, b *bundle.Bundle, goal Goal) *DeploymentLock {
5441
enabled := b.Config.Bundle.Deployment.Lock.IsEnabled()
55-
l := &workspaceFilesystemLock{
56-
user: b.Config.Workspace.CurrentUser.UserName,
57-
statePath: b.Config.Workspace.StatePath,
58-
enabled: enabled,
59-
force: b.Config.Bundle.Deployment.Lock.Force,
60-
reportPermissionError: func(ctx context.Context, path string) diag.Diagnostics {
61-
return permissions.ReportPossiblePermissionDenied(ctx, b, path)
42+
l := &DeploymentLock{
43+
wfs: workspaceFilesystemLock{
44+
user: b.Config.Workspace.CurrentUser.UserName,
45+
statePath: b.Config.Workspace.StatePath,
46+
enabled: enabled,
47+
force: b.Config.Bundle.Deployment.Lock.Force,
48+
goal: goal,
49+
reportPermissionError: func(ctx context.Context, path string) diag.Diagnostics {
50+
return permissions.ReportPossiblePermissionDenied(ctx, b, path)
51+
},
6252
},
6353
}
6454
if enabled {
65-
l.client = b.WorkspaceClient(ctx)
55+
l.wfs.client = b.WorkspaceClient(ctx)
6656
}
6757
return l
6858
}
59+
60+
// Acquire acquires the deployment lock.
61+
func (l *DeploymentLock) Acquire(ctx context.Context) error {
62+
return l.wfs.acquire(ctx)
63+
}
64+
65+
// Release releases the deployment lock.
66+
func (l *DeploymentLock) Release(ctx context.Context, status DeploymentStatus) error {
67+
return l.wfs.release(ctx, status)
68+
}

bundle/deploy/lock/workspace_filesystem.go

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ import (
1111
"github.com/databricks/databricks-sdk-go"
1212
)
1313

14-
// workspaceFilesystemLock implements DeploymentManager using a lock file in the
15-
// bundle's workspace state path. Holds only the primitives it needs from the
16-
// bundle.
14+
// workspaceFilesystemLock holds the state for the workspace-filesystem lock.
15+
// Methods are unexported; callers use DeploymentLock.Acquire / DeploymentLock.Release.
1716
type workspaceFilesystemLock struct {
1817
client *databricks.WorkspaceClient
1918
user string
@@ -30,18 +29,16 @@ type workspaceFilesystemLock struct {
3029
goal Goal
3130
}
3231

33-
func (l *workspaceFilesystemLock) CreateVersion(ctx context.Context, goal Goal) (int64, error) {
34-
l.goal = goal
35-
32+
func (l *workspaceFilesystemLock) acquire(ctx context.Context) error {
3633
// Return early if locking is disabled.
3734
if !l.enabled {
3835
log.Infof(ctx, "Skipping; locking is disabled")
39-
return 0, nil
36+
return nil
4037
}
4138

4239
lk, err := locker.CreateLocker(l.user, l.statePath, l.client)
4340
if err != nil {
44-
return 0, err
41+
return err
4542
}
4643

4744
l.locker = lk
@@ -54,16 +51,16 @@ func (l *workspaceFilesystemLock) CreateVersion(ctx context.Context, goal Goal)
5451
// If we get a permission or "doesn't exist" error from the API this
5552
// indicates we either don't have permissions or the path is invalid.
5653
if errors.Is(err, fs.ErrPermission) || errors.Is(err, fs.ErrNotExist) {
57-
return 0, l.reportPermissionError(ctx, l.statePath).Error()
54+
return l.reportPermissionError(ctx, l.statePath).Error()
5855
}
5956

60-
return 0, err
57+
return err
6158
}
6259

63-
return 0, nil
60+
return nil
6461
}
6562

66-
func (l *workspaceFilesystemLock) CompleteVersion(ctx context.Context, _ int64, _ DeploymentStatus) error {
63+
func (l *workspaceFilesystemLock) release(ctx context.Context, _ DeploymentStatus) error {
6764
// Return early if locking is disabled.
6865
if !l.enabled {
6966
log.Infof(ctx, "Skipping; locking is disabled")

bundle/phases/bind.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ import (
2323
func Bind(ctx context.Context, b *bundle.Bundle, opts *terraform.BindOptions, engine engine.EngineType) {
2424
log.Info(ctx, "Phase: bind")
2525

26-
dm := lock.NewDeploymentManager(ctx, b)
27-
version, err := dm.CreateVersion(ctx, lock.GoalBind)
28-
if err != nil {
26+
dl := lock.NewDeploymentLock(ctx, b, lock.GoalBind)
27+
if err := dl.Acquire(ctx); err != nil {
2928
logdiag.LogError(ctx, err)
3029
return
3130
}
@@ -35,7 +34,7 @@ func Bind(ctx context.Context, b *bundle.Bundle, opts *terraform.BindOptions, en
3534
if logdiag.HasError(ctx) {
3635
status = lock.DeploymentFailure
3736
}
38-
if err := dm.CompleteVersion(ctx, version, status); err != nil {
37+
if err := dl.Release(ctx, status); err != nil {
3938
logdiag.LogError(ctx, err)
4039
}
4140
}()
@@ -127,9 +126,8 @@ func jsonDump(ctx context.Context, v any, field string) string {
127126
func Unbind(ctx context.Context, b *bundle.Bundle, bundleType, tfResourceType, resourceKey string, engine engine.EngineType) {
128127
log.Info(ctx, "Phase: unbind")
129128

130-
dm := lock.NewDeploymentManager(ctx, b)
131-
version, err := dm.CreateVersion(ctx, lock.GoalUnbind)
132-
if err != nil {
129+
dl := lock.NewDeploymentLock(ctx, b, lock.GoalUnbind)
130+
if err := dl.Acquire(ctx); err != nil {
133131
logdiag.LogError(ctx, err)
134132
return
135133
}
@@ -139,7 +137,7 @@ func Unbind(ctx context.Context, b *bundle.Bundle, bundleType, tfResourceType, r
139137
if logdiag.HasError(ctx) {
140138
status = lock.DeploymentFailure
141139
}
142-
if err := dm.CompleteVersion(ctx, version, status); err != nil {
140+
if err := dl.Release(ctx, status); err != nil {
143141
logdiag.LogError(ctx, err)
144142
}
145143
}()

bundle/phases/deploy.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,12 @@ func Deploy(ctx context.Context, b *bundle.Bundle, outputHandler sync.OutputHand
128128
// mutators need informed consent if they are potentially destructive.
129129
bundle.ApplyContext(ctx, b, scripts.Execute(config.ScriptPreDeploy))
130130
if logdiag.HasError(ctx) {
131-
// deployment version not yet created
131+
// lock not yet acquired
132132
return
133133
}
134134

135-
dm := lock.NewDeploymentManager(ctx, b)
136-
version, err := dm.CreateVersion(ctx, lock.GoalDeploy)
137-
if err != nil {
135+
dl := lock.NewDeploymentLock(ctx, b, lock.GoalDeploy)
136+
if err := dl.Acquire(ctx); err != nil {
138137
logdiag.LogError(ctx, err)
139138
return
140139
}
@@ -144,7 +143,7 @@ func Deploy(ctx context.Context, b *bundle.Bundle, outputHandler sync.OutputHand
144143
if logdiag.HasError(ctx) {
145144
status = lock.DeploymentFailure
146145
}
147-
if err := dm.CompleteVersion(ctx, version, status); err != nil {
146+
if err := dl.Release(ctx, status); err != nil {
148147
logdiag.LogError(ctx, err)
149148
}
150149
}()

bundle/phases/destroy.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,8 @@ func Destroy(ctx context.Context, b *bundle.Bundle, engine engine.EngineType) {
120120
return
121121
}
122122

123-
dm := lock.NewDeploymentManager(ctx, b)
124-
version, err := dm.CreateVersion(ctx, lock.GoalDestroy)
125-
if err != nil {
123+
dl := lock.NewDeploymentLock(ctx, b, lock.GoalDestroy)
124+
if err := dl.Acquire(ctx); err != nil {
126125
logdiag.LogError(ctx, err)
127126
return
128127
}
@@ -132,7 +131,7 @@ func Destroy(ctx context.Context, b *bundle.Bundle, engine engine.EngineType) {
132131
if logdiag.HasError(ctx) {
133132
status = lock.DeploymentFailure
134133
}
135-
if err := dm.CompleteVersion(ctx, version, status); err != nil {
134+
if err := dl.Release(ctx, status); err != nil {
136135
logdiag.LogError(ctx, err)
137136
}
138137
}()

0 commit comments

Comments
 (0)