Skip to content
Open
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
6 changes: 3 additions & 3 deletions packages/databricks-vscode/DATABRICKS.quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ The Databricks extension for Visual Studio Code enables you to connect to your r

If your folder has multiple [Declarative Automation Bundles](#dabs), you can select which one to use by clicking "Open Existing Databricks project" button and selecting the desired project.

## <a id="select-cluster"></a>Select a cluster
## <a id="select-cluster"></a>Select a compute

The extension uses an interactive cluster to run code. To select an interactive cluster:
The extension uses an interactive compute to run code. To select an interactive compute:

1. Open the Databricks panel by clicking on the Databricks icon on the left
2. Click on the "Select Cluster" button.
2. Click on the "Select Compute" button.
- If you wish to change the selected cluster, click on the "Configure Cluster" gear icon, next to the name of the selected cluster.

## <a id="running-code"></a>Run Python code
Expand Down
30 changes: 21 additions & 9 deletions packages/databricks-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@
"types": "out/extension.d.ts",
"contributes": {
"commands": [
{
"command": "databricks.ssh.startTunnel",
"title": "Start SSH Tunnel",
"category": "Databricks",
"icon": "$(remote)",
"enablement": "databricks.context.activated && databricks.context.loggedIn && !databricks.context.remoteMode"
},
{
"command": "databricks.connection.logout",
"title": "Logout",
Expand All @@ -73,20 +80,20 @@
},
{
"command": "databricks.connection.attachCluster",
"title": "Attach cluster",
"title": "Attach compute",
"enablement": "databricks.context.activated && databricks.context.loggedIn && !databricks.context.remoteMode",
"icon": "$(plug)"
},
{
"command": "databricks.connection.attachClusterQuickPick",
"title": "Configure cluster",
"title": "Configure compute",
"category": "Databricks",
"enablement": "databricks.context.activated && databricks.context.loggedIn && !databricks.context.remoteMode",
"icon": "$(gear)"
},
{
"command": "databricks.connection.detachCluster",
"title": "Detach cluster",
"title": "Detach compute",
"category": "Databricks",
"enablement": "databricks.context.activated && databricks.context.loggedIn && !databricks.context.remoteMode",
"icon": "$(debug-disconnect)"
Expand Down Expand Up @@ -151,14 +158,14 @@
},
{
"command": "databricks.cluster.start",
"title": "Start Cluster",
"title": "Start Compute",
"icon": "$(debug-start)",
"enablement": "databricks.context.activated && databricks.context.loggedIn && !databricks.context.remoteMode",
"category": "Databricks"
},
{
"command": "databricks.cluster.stop",
"title": "Stop Cluster",
"title": "Stop Compute",
"icon": "$(stop-circle)",
"enablement": "databricks.context.activated && databricks.context.loggedIn && !databricks.context.remoteMode",
"category": "Databricks"
Expand Down Expand Up @@ -542,7 +549,7 @@
{
"id": "clusterView",
"when": "databricks.feature.views.cluster && !databricks.context.remoteMode",
"name": "Clusters"
"name": "Computes"
},
{
"id": "dabsResourceExplorerView",
Expand Down Expand Up @@ -1101,6 +1108,11 @@
"command": "databricks.sync.stop",
"when": "view == configurationView && viewItem =~ /^databricks.*sync.*is-running.*$/ && databricks.context.bundle.isDevTarget",
"group": "navigation@0"
},
{
"command": "databricks.ssh.startTunnel",
"when": "view == configurationView && viewItem == databricks.configuration.sshTunnel",
"group": "navigation@0"
}
],
"editor/title": [
Expand Down Expand Up @@ -1233,7 +1245,7 @@
"submenus": [
{
"id": "databricks.cluster.filter",
"label": "Filter clusters ...",
"label": "Filter compute ...",
"icon": "$(filter)"
},
{
Expand Down Expand Up @@ -1439,7 +1451,7 @@
"databricks.clusters.onlyShowAccessibleClusters": {
"type": "boolean",
"default": false,
"description": "Enable/disable filtering for only accessible clusters (clusters on which the current user can run code)"
"description": "Enable/disable filtering for only accessible computes (computes on which the current user can run code)"
},
"databricks.overrideDatabricksConfigFile": {
"type": "string",
Expand All @@ -1455,7 +1467,7 @@
"views.workspace"
],
"enumDescriptions": [
"Show cluster view in the explorer.",
"Show compute view in the explorer.",
"Show workspace browser in the explorer."
],
"type": "string"
Expand Down
42 changes: 42 additions & 0 deletions packages/databricks-vscode/src/cli/CliWrapper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,48 @@ describe(__filename, function () {
assert.equal([command, ...args].join(" "), syncCommand);
});

it("should create ssh connect commands", () => {
const logFilePath = getTempLogFilePath();
const cli = createCliWrapper(logFilePath);

// Logging is configured via env vars, not CLI flags, so no --log-*
// args appear on the ssh connect command line.

// Serverless: no --cluster / --auto-start-cluster.
let {args} = cli.getSshConnectCommand({compute: {type: "serverless"}});
assert.deepStrictEqual(args, [
"ssh",
"connect",
"--ide=vscode",
"--auto-approve",
]);

// Serverless GPU: --accelerator, no --cluster / --auto-start-cluster.
({args} = cli.getSshConnectCommand({
compute: {type: "serverless", accelerator: "GPU_1xA10"},
}));
assert.deepStrictEqual(args, [
"ssh",
"connect",
"--ide=vscode",
"--auto-approve",
"--accelerator=GPU_1xA10",
]);

// Dedicated cluster: --cluster and --auto-start-cluster.
({args} = cli.getSshConnectCommand({
compute: {type: "cluster", clusterId: "1234-clusterid"},
}));
assert.deepStrictEqual(args, [
"ssh",
"connect",
"--ide=vscode",
"--auto-approve",
"--cluster=1234-clusterid",
"--auto-start-cluster",
]);
});

it("should list profiles when no config file exists", async () => {
const logFilePath = getTempLogFilePath();
const cli = createCliWrapper(logFilePath);
Expand Down
48 changes: 48 additions & 0 deletions packages/databricks-vscode/src/cli/CliWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Uri,
commands,
CancellationToken,
env,
} from "vscode";
import {workspaceConfigs} from "../vscode-objs/WorkspaceConfigs";
import {promisify} from "node:util";
Expand Down Expand Up @@ -574,6 +575,53 @@ export class CliWrapper {
});
}

/**
* Env vars for interactive CLI commands run in a terminal (e.g. `ssh
* connect`). Auth is forwarded via env vars, matching the bundle init flow.
*/
getSshConnectEnvVars(authProvider: AuthProvider) {
return removeUndefinedKeys({
...EnvVarGenerators.getEnvVarsForCli(
this.extensionContext,
workspaceConfigs.databrickscfgLocation
),
...EnvVarGenerators.getProxyEnvVars(),
...this.getLogginEnvVars(),
...authProvider.toEnv(),
// eslint-disable-next-line @typescript-eslint/naming-convention
DATABRICKS_OUTPUT_FORMAT: "text",
});
}

/**
* Constructs the `databricks ssh connect` command args for opening a remote
* IDE window. Serverless is the default when no cluster is given.
*
* The --ide flag matches the host editor so the CLI opens the right remote
* window: Cursor identifies itself via env.uriScheme === "cursor",
* everything else (VS Code, Insiders) uses vscode.
*
* Logging is configured out of band via the DATABRICKS_LOG_* env vars (see
* getSshConnectEnvVars), so we do not pass --log-* flags here.
*/
getSshConnectCommand(opts: {
compute:
| {type: "serverless"; accelerator?: string}
| {type: "cluster"; clusterId: string};
}): {args: string[]} {
const ide = env.uriScheme === "cursor" ? "cursor" : "vscode";
const args = ["ssh", "connect", `--ide=${ide}`, "--auto-approve"];
if (opts.compute.type === "cluster") {
// Start a stopped single-user cluster when connecting.
args.push(`--cluster=${opts.compute.clusterId}`);
args.push("--auto-start-cluster");
} else if (opts.compute.accelerator) {
// Serverless GPU: request a specific accelerator type.
args.push(`--accelerator=${opts.compute.accelerator}`);
}
return {args};
}

async bundleInit(
templateDirPath: string,
outputDirPath: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export class ConnectionCommands implements Disposable {
ClusterItem | QuickPickItem
>();
quickPick.title =
typeof title === "string" ? title : "Select Cluster";
typeof title === "string" ? title : "Select Compute";
quickPick.keepScrollPosition = true;
quickPick.busy = true;
quickPick.canSelectMany = false;
Expand Down
12 changes: 12 additions & 0 deletions packages/databricks-vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import {Events, Metadata} from "./telemetry/constants";
import {EnvironmentDependenciesInstaller} from "./language/EnvironmentDependenciesInstaller";
import {setDbnbCellLimits} from "./language/notebooks/DatabricksNbCellLimits";
import {DbConnectStatusBarButton} from "./language/DbConnectStatusBarButton";
import {SshCommands} from "./ssh/SshCommands";
import {NotebookInitScriptManager} from "./language/notebooks/NotebookInitScriptManager";
import {showRestartNotebookDialogue} from "./language/notebooks/restartNotebookDialogue";
import {
Expand Down Expand Up @@ -825,6 +826,17 @@ export async function activate(
)
);

// SSH tunnel (remote development) group
const sshCommands = new SshCommands(connectionManager, clusterModel, cli);
context.subscriptions.push(
sshCommands,
telemetry.registerCommand(
"databricks.ssh.startTunnel",
sshCommands.startTunnelCommand,
sshCommands
)
);

// Cluster group
const clusterTreeDataProvider = new ClusterListDataProvider(clusterModel);
const clusterCommands = new ClusterCommands(
Expand Down
Loading
Loading