From 8814c7a43495aa311a5bc42a6a1fb1034b5fa8fe Mon Sep 17 00:00:00 2001 From: Ilia Babanov Date: Tue, 22 Oct 2024 13:36:58 +0200 Subject: [PATCH] Use bundle sync instead of deploy before remote run commands Also changes Sync logic to use the bundle sync command. Depends on the CLI PR: https://github.com/databricks/cli/pull/1853 --- .../bundle/models/BundleRemoteStateModel.ts | 19 ++++++++++ .../src/cli/CliWrapper.test.ts | 20 ++--------- .../databricks-vscode/src/cli/CliWrapper.ts | 35 +++++++++++++++---- .../databricks-vscode/src/cli/SyncTasks.ts | 17 +++------ .../src/run/DatabricksRuntime.ts | 4 +-- .../src/run/WorkflowRunner.ts | 4 +-- .../BundleCommands.ts | 27 ++++++++++++++ 7 files changed, 85 insertions(+), 41 deletions(-) diff --git a/packages/databricks-vscode/src/bundle/models/BundleRemoteStateModel.ts b/packages/databricks-vscode/src/bundle/models/BundleRemoteStateModel.ts index 2171587d9..1a479f69e 100644 --- a/packages/databricks-vscode/src/bundle/models/BundleRemoteStateModel.ts +++ b/packages/databricks-vscode/src/bundle/models/BundleRemoteStateModel.ts @@ -103,6 +103,25 @@ export class BundleRemoteStateModel extends BaseModelWithStateCache { const logFilePath = getTempLogFilePath(); const cli = createCliWrapper(logFilePath); - const mapper = new SyncDestinationMapper( - new LocalUri(Uri.file("/user/project")), - new RemoteUri( - Uri.from({ - scheme: "wsfs", - path: "/Repos/user@databricks.com/project", - }) - ) - ); const syncCommand = `${cliPath} sync . /Repos/user@databricks.com/project --watch --output json`; const loggingArgs = `--log-level debug --log-file ${logFilePath} --log-format json`; - let {command, args} = cli.getSyncCommand(mapper, "incremental"); + let {command, args} = cli.getSyncCommand("incremental"); assert.equal( [command, ...args].join(" "), [syncCommand, loggingArgs].join(" ") ); - ({command, args} = cli.getSyncCommand(mapper, "full")); + ({command, args} = cli.getSyncCommand("full")); assert.equal( [command, ...args].join(" "), [syncCommand, loggingArgs, "--full"].join(" ") @@ -106,7 +92,7 @@ describe(__filename, function () { const configsSpy = spy(workspaceConfigs); mocks.push(configsSpy); when(configsSpy.loggingEnabled).thenReturn(false); - ({command, args} = cli.getSyncCommand(mapper, "incremental")); + ({command, args} = cli.getSyncCommand("incremental")); assert.equal([command, ...args].join(" "), syncCommand); }); diff --git a/packages/databricks-vscode/src/cli/CliWrapper.ts b/packages/databricks-vscode/src/cli/CliWrapper.ts index 50aa329af..422adf676 100644 --- a/packages/databricks-vscode/src/cli/CliWrapper.ts +++ b/packages/databricks-vscode/src/cli/CliWrapper.ts @@ -11,7 +11,6 @@ import { commands, CancellationToken, } from "vscode"; -import {SyncDestinationMapper} from "../sync/SyncDestination"; import {workspaceConfigs} from "../vscode-objs/WorkspaceConfigs"; import {promisify} from "node:util"; import {logging} from "@databricks/databricks-sdk"; @@ -335,14 +334,10 @@ export class CliWrapper { /** * Constructs the databricks sync command */ - getSyncCommand( - syncDestination: SyncDestinationMapper, - syncType: SyncType - ): Command { + getSyncCommand(syncType: SyncType): Command { const args = [ + "bundle", "sync", - ".", - syncDestination.remoteUri.path, "--watch", "--output", "json", @@ -664,6 +659,32 @@ export class CliWrapper { ); } + async bundleSync( + target: string, + authProvider: AuthProvider, + workspaceFolder: Uri, + configfilePath?: string, + logger?: logging.NamedLogger, + token?: CancellationToken + ) { + await commands.executeCommand("databricks.bundle.showLogs"); + return await runBundleCommand( + "sync", + this.cliPath, + ["bundle", "sync", "--target", target, "--output", "text"], + workspaceFolder, + { + start: `Uploading bundle assets for target ${target}...`, + end: "Bundle assets uploaded successfully.", + error: "Failed to upload bundle assets.", + }, + await this.getBundleCommandEnvVars(authProvider, configfilePath), + logger, + {}, + token + ); + } + async getBundleRunCommand( target: string, authProvider: AuthProvider, diff --git a/packages/databricks-vscode/src/cli/SyncTasks.ts b/packages/databricks-vscode/src/cli/SyncTasks.ts index 9c94d44f4..21c13c0f6 100644 --- a/packages/databricks-vscode/src/cli/SyncTasks.ts +++ b/packages/databricks-vscode/src/cli/SyncTasks.ts @@ -249,12 +249,12 @@ export class LazyCustomSyncTerminal extends CustomSyncTerminal { Object.defineProperties(this, { cmd: { get: () => { - return this.getSyncCommand(ctx).command; + return this.getSyncCommand().command; }, }, args: { get: () => { - return this.getSyncCommand(ctx).args; + return this.getSyncCommand().args; }, }, options: { @@ -311,21 +311,12 @@ export class LazyCustomSyncTerminal extends CustomSyncTerminal { } as SpawnOptions; } - @withLogContext(Loggers.Extension) - getSyncCommand(@context ctx?: Context): Command { + getSyncCommand(): Command { if (this.command) { return this.command; } - const syncDestination = this.connection.syncDestinationMapper; - - if (!syncDestination) { - throw this.showErrorAndKillThis( - "Can't start sync: Databricks synchronization destination not configured!", - ctx - ); - } - this.command = this.cli.getSyncCommand(syncDestination, this.syncType); + this.command = this.cli.getSyncCommand(this.syncType); return this.command; } diff --git a/packages/databricks-vscode/src/run/DatabricksRuntime.ts b/packages/databricks-vscode/src/run/DatabricksRuntime.ts index 001068705..31f353bb7 100644 --- a/packages/databricks-vscode/src/run/DatabricksRuntime.ts +++ b/packages/databricks-vscode/src/run/DatabricksRuntime.ts @@ -137,9 +137,9 @@ export class DatabricksRuntime implements Disposable { throw new Error("No sync destination found"); } - log("Deploying assets to databricks workspace..."); + log("Uploading assets to databricks workspace..."); this.state = "SYNCING"; - await this.bundleCommands.deploy(); + await this.bundleCommands.sync(); await commands.executeCommand("workbench.panel.repl.view.focus"); diff --git a/packages/databricks-vscode/src/run/WorkflowRunner.ts b/packages/databricks-vscode/src/run/WorkflowRunner.ts index 1d65ae2b6..f2511ba39 100644 --- a/packages/databricks-vscode/src/run/WorkflowRunner.ts +++ b/packages/databricks-vscode/src/run/WorkflowRunner.ts @@ -89,11 +89,11 @@ export class WorkflowRunner implements Disposable { } try { - await this.bundleCommands.deploy(); + await this.bundleCommands.sync(); } catch (e: unknown) { if (e instanceof Error) { panel.showError({ - message: `Can't deploy assets to databricks workspace. \nReason: ${e.message}`, + message: `Can't upload assets to databricks workspace. \nReason: ${e.message}`, }); } return; diff --git a/packages/databricks-vscode/src/ui/bundle-resource-explorer/BundleCommands.ts b/packages/databricks-vscode/src/ui/bundle-resource-explorer/BundleCommands.ts index c5cf7abcb..ef9226a98 100644 --- a/packages/databricks-vscode/src/ui/bundle-resource-explorer/BundleCommands.ts +++ b/packages/databricks-vscode/src/ui/bundle-resource-explorer/BundleCommands.ts @@ -85,6 +85,33 @@ export class BundleCommands implements Disposable { private deployMutex = new Mutex(); + @Mutex.synchronise("deployMutex") + async sync() { + try { + this.whenContext.setDeploymentState("deploying"); + await window.withProgress( + { + location: ProgressLocation.Notification, + title: "Synchronising bundle assets", + cancellable: true, + }, + async (progress, token) => { + await this.bundleRemoteStateModel.sync(token); + } + ); + } catch (e) { + if (!(e instanceof Error)) { + throw e; + } + if (e instanceof ProcessError) { + e.showErrorMessage("Error synchronising bundle assets."); + } + throw e; + } finally { + this.whenContext.setDeploymentState("idle"); + } + } + @Mutex.synchronise("deployMutex") async deploy(force = false) { try {