mirror of https://github.com/databricks/cli.git
Mutators to define current user and default artifact path (#112)
This commit is contained in:
parent
230811031f
commit
34af98a8c3
|
@ -65,13 +65,13 @@ func (m *build) Apply(_ context.Context, b *bundle.Bundle) ([]bundle.Mutator, er
|
||||||
|
|
||||||
// Check that an artifact path is defined.
|
// Check that an artifact path is defined.
|
||||||
remotePath := b.Config.Workspace.ArtifactPath.Workspace
|
remotePath := b.Config.Workspace.ArtifactPath.Workspace
|
||||||
if remotePath == nil {
|
if remotePath == "" {
|
||||||
return nil, fmt.Errorf("remote artifact path not configured")
|
return nil, fmt.Errorf("remote artifact path not configured")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store absolute paths.
|
// Store absolute paths.
|
||||||
artifact.LocalPath = filepath.Join(b.Config.Path, artifact.Path)
|
artifact.LocalPath = filepath.Join(b.Config.Path, artifact.Path)
|
||||||
artifact.RemotePath = path.Join(*remotePath, stripExtension(artifact.Path))
|
artifact.RemotePath = path.Join(remotePath, stripExtension(artifact.Path))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package mutator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"github.com/databricks/bricks/bundle"
|
||||||
|
)
|
||||||
|
|
||||||
|
type defaultArtifactPath struct{}
|
||||||
|
|
||||||
|
// DefaultArtifactPath configures the artifact path if it isn't already set.
|
||||||
|
func DefaultArtifactPath() bundle.Mutator {
|
||||||
|
return &defaultArtifactPath{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultArtifactPath) Name() string {
|
||||||
|
return "DefaultArtifactPath"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultArtifactPath) Apply(ctx context.Context, b *bundle.Bundle) ([]bundle.Mutator, error) {
|
||||||
|
if b.Config.Workspace.ArtifactPath.IsSet() {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
me := b.Config.Workspace.CurrentUser
|
||||||
|
if me == nil {
|
||||||
|
return nil, fmt.Errorf("cannot configured default artifact path if current user isn't set")
|
||||||
|
}
|
||||||
|
|
||||||
|
// We assume we deal with notebooks only for the time being.
|
||||||
|
// When we need to upload wheel files or other non-notebook files,
|
||||||
|
// the workspace must support "Files in Workspace".
|
||||||
|
// If it doesn't, we need to resort to storing artifacts on DBFS.
|
||||||
|
home := fmt.Sprintf("/Users/%s", me.UserName)
|
||||||
|
root := path.Join(home, ".bundle", b.Config.Bundle.Name, b.Config.Bundle.Environment, "artifacts")
|
||||||
|
b.Config.Workspace.ArtifactPath.Workspace = root
|
||||||
|
return nil, nil
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package mutator_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/databricks/bricks/bundle"
|
||||||
|
"github.com/databricks/bricks/bundle/config"
|
||||||
|
"github.com/databricks/bricks/bundle/config/mutator"
|
||||||
|
"github.com/databricks/databricks-sdk-go/service/scim"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDefaultArtifactPath(t *testing.T) {
|
||||||
|
bundle := &bundle.Bundle{
|
||||||
|
Config: config.Root{
|
||||||
|
Bundle: config.Bundle{
|
||||||
|
Name: "name",
|
||||||
|
Environment: "environment",
|
||||||
|
},
|
||||||
|
Workspace: config.Workspace{
|
||||||
|
CurrentUser: &scim.User{
|
||||||
|
UserName: "foo@bar.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, err := mutator.DefaultArtifactPath().Apply(context.Background(), bundle)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "/Users/foo@bar.com/.bundle/name/environment/artifacts", bundle.Config.Workspace.ArtifactPath.Workspace)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDefaultArtifactPathAlreadySet(t *testing.T) {
|
||||||
|
bundle := &bundle.Bundle{
|
||||||
|
Config: config.Root{
|
||||||
|
Workspace: config.Workspace{
|
||||||
|
ArtifactPath: config.PathLike{
|
||||||
|
Workspace: "/foo/bar",
|
||||||
|
},
|
||||||
|
CurrentUser: &scim.User{
|
||||||
|
UserName: "foo@bar.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, err := mutator.DefaultArtifactPath().Apply(context.Background(), bundle)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "/foo/bar", bundle.Config.Workspace.ArtifactPath.Workspace)
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package mutator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/databricks/bricks/bundle"
|
||||||
|
)
|
||||||
|
|
||||||
|
type populateCurrentUser struct{}
|
||||||
|
|
||||||
|
// PopulateCurrentUser sets the `current_user` property on the workspace.
|
||||||
|
func PopulateCurrentUser() bundle.Mutator {
|
||||||
|
return &populateCurrentUser{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *populateCurrentUser) Name() string {
|
||||||
|
return "PopulateCurrentUser"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *populateCurrentUser) Apply(ctx context.Context, b *bundle.Bundle) ([]bundle.Mutator, error) {
|
||||||
|
w := b.WorkspaceClient()
|
||||||
|
me, err := w.CurrentUser.Me(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
b.Config.Workspace.CurrentUser = me
|
||||||
|
return nil, nil
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package mutator
|
||||||
|
|
||||||
|
// We need to implement workspace client mocking to implement this test.
|
|
@ -2,14 +2,20 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/databricks/databricks-sdk-go"
|
"github.com/databricks/databricks-sdk-go"
|
||||||
|
"github.com/databricks/databricks-sdk-go/service/scim"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PathLike struct {
|
type PathLike struct {
|
||||||
// Workspace contains a WSFS path.
|
// Workspace contains a WSFS path.
|
||||||
Workspace *string `json:"workspace,omitempty"`
|
Workspace string `json:"workspace,omitempty"`
|
||||||
|
|
||||||
// DBFS contains a DBFS path.
|
// DBFS contains a DBFS path.
|
||||||
DBFS *string `json:"dbfs,omitempty"`
|
DBFS string `json:"dbfs,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSet returns whether either path is non-nil.
|
||||||
|
func (p PathLike) IsSet() bool {
|
||||||
|
return p.Workspace != "" || p.DBFS != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workspace defines configurables at the workspace level.
|
// Workspace defines configurables at the workspace level.
|
||||||
|
@ -37,6 +43,10 @@ type Workspace struct {
|
||||||
AzureEnvironment string `json:"azure_environment,omitempty"`
|
AzureEnvironment string `json:"azure_environment,omitempty"`
|
||||||
AzureLoginAppID string `json:"azure_login_app_id,omitempty"`
|
AzureLoginAppID string `json:"azure_login_app_id,omitempty"`
|
||||||
|
|
||||||
|
// CurrentUser holds the current user.
|
||||||
|
// This is set after configuration initialization.
|
||||||
|
CurrentUser *scim.User `json:"current_user,omitempty"`
|
||||||
|
|
||||||
// Remote path for artifacts.
|
// Remote path for artifacts.
|
||||||
// This can specify a workspace path, a DBFS path, or both.
|
// This can specify a workspace path, a DBFS path, or both.
|
||||||
// Some artifacts must be stored in the workspace (e.g. notebooks).
|
// Some artifacts must be stored in the workspace (e.g. notebooks).
|
||||||
|
|
Loading…
Reference in New Issue