Skip to content
Merged
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
12 changes: 12 additions & 0 deletions cmd/lakebox/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,18 @@ func (a *lakeboxAPI) stop(ctx context.Context, id string) (*sandboxEntry, error)
return &resp, nil
}

// start calls POST /api/2.0/lakebox/sandboxes/{id}/start and returns the
// refreshed sandbox. Mirror of `stop`; same body shape per `body: "*"`.
func (a *lakeboxAPI) start(ctx context.Context, id string) (*sandboxEntry, error) {
body := map[string]string{"sandbox_id": id}
var resp sandboxEntry
err := a.c.Do(ctx, http.MethodPost, lakeboxAPIPath+"/"+id+"/start", a.headers(), nil, body, &resp)
if err != nil {
return nil, err
}
return &resp, nil
}

// registerKey calls POST /api/2.0/lakebox/ssh-keys. An empty `name` is
// omitted from the wire payload so the server records "unset" rather than
// an explicit empty string.
Expand Down
1 change: 1 addition & 0 deletions cmd/lakebox/lakebox.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Common workflows:
cmd.AddCommand(newCreateCommand())
cmd.AddCommand(newDeleteCommand())
cmd.AddCommand(newStopCommand())
cmd.AddCommand(newStartCommand())
cmd.AddCommand(newStatusCommand())
cmd.AddCommand(newConfigCommand())

Expand Down
22 changes: 16 additions & 6 deletions cmd/lakebox/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/databricks/cli/libs/cmdctx"
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/cli/libs/execv"
"github.com/databricks/databricks-sdk-go/apierr"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -131,13 +132,22 @@ Examples:
warn(ctx, fmt.Sprintf("Could not save default: %v", err))
}
}
} else if getGatewayHost(ctx, profile) == "" {
// Explicit-id ssh on a profile we have no cached gateway for:
// one-time `get` to learn it. Subsequent invocations hit the
// cache and skip the round-trip. Failure here is non-fatal —
// we fall through to the workspace-host heuristic.
if sb, err := api.get(ctx, lakeboxID); err == nil {
} else {
// Validate the explicit ID against the server. Two reasons:
// 1. Surface `lakebox ssh fake-id` as a clear 404 instead of
// letting the user wade through `Permission denied` from
// ssh when the gateway can't route an unknown sandbox.
// 2. Capture `gateway_host` to drive the resolution below.
// Non-NotFound errors fall through so transient API hiccups
// don't block a connection the gateway can still route.
sb, err := api.get(ctx, lakeboxID)
switch {
case err == nil:
sandboxGatewayHost = sb.GatewayHost
case errors.Is(err, apierr.ErrNotFound):
return fmt.Errorf("no lakebox named %q — `databricks lakebox list` shows available IDs", lakeboxID)
default:
warn(ctx, fmt.Sprintf("could not validate lakebox %s: %v", lakeboxID, err))
}
}

Expand Down
59 changes: 59 additions & 0 deletions cmd/lakebox/start.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package lakebox

import (
"fmt"

"github.com/databricks/cli/cmd/root"
"github.com/databricks/cli/libs/cmdctx"
"github.com/databricks/cli/libs/cmdio"
"github.com/spf13/cobra"
)

func newStartCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "start <lakebox-id>",
Short: "Start a stopped Lakebox environment",
Long: `Start a stopped Lakebox environment.

Boots the backing microVM and brings the sandbox to Running.
'databricks lakebox ssh' already auto-starts a stopped sandbox on
connection, so this command is mostly useful for pre-warming an
environment without immediately connecting.

Starting an already-running sandbox is a no-op.

Example:
databricks lakebox start happy-panda-1234`,
Args: cobra.ExactArgs(1),
PreRunE: root.MustWorkspaceClient,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
w := cmdctx.WorkspaceClient(ctx)
api, err := newLakeboxAPI(w)
if err != nil {
return err
}

lakeboxID := args[0]
s := spin(ctx, "Starting "+lakeboxID+"…")
defer s.Close()

updated, err := api.start(ctx, lakeboxID)
if err != nil {
s.fail("Failed to start " + lakeboxID)
return fmt.Errorf("failed to start lakebox %s: %w", lakeboxID, err)
}

profile := w.Config.Profile
if profile == "" {
profile = w.Config.Host
}
_ = setGatewayHost(ctx, profile, updated.GatewayHost)

s.ok("Started " + cmdio.Bold(ctx, updated.SandboxID))
return nil
},
}

return cmd
}
Loading