Skip to content

Commit 3542987

Browse files
authored
Auto update IDE settings for serverless ssh mode (#4559)
## Changes In serverless ssh mode (ssh connect command without cluster flag and with the ide flag set), we need to set up the desired server ports (or socket connection mode) for the connection to go through (as the majority of the localhost ports on the remote side are blocked by iptable rules). Plus the platform (always linux), and extensions (python and jupyter), to make the initial experience smoother. This is done by checking the IDE settings file and updating it if necessary, prompting the user for confirmation before doing so. If the settings file is not found (fresh IDE install), we create one with the recommended configuration. If there are any other issues during the update process, we log the error and print the manual instructions for the user, proceeding with the connection anyway. ## Tests New unit tests, plus manual tests on all platforms (WIP) <!-- If your PR needs to be included in the release notes for next release, add a separate entry in NEXT_CHANGELOG.md as part of your PR. -->
1 parent 4684f06 commit 3542987

File tree

6 files changed

+963
-0
lines changed

6 files changed

+963
-0
lines changed

experimental/ssh/cmd/connect.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ the SSH server and handling the connection proxy.
3535
var autoStartCluster bool
3636
var userKnownHostsFile string
3737
var liteswap string
38+
var skipSettingsCheck bool
3839

3940
cmd.Flags().StringVar(&clusterID, "cluster", "", "Databricks cluster ID (for dedicated clusters)")
4041
cmd.Flags().DurationVar(&shutdownDelay, "shutdown-delay", defaultShutdownDelay, "Delay before shutting down the server after the last client disconnects")
@@ -64,6 +65,9 @@ the SSH server and handling the connection proxy.
6465
cmd.Flags().StringVar(&liteswap, "liteswap", "", "Liteswap header value for traffic routing (dev/test only)")
6566
cmd.Flags().MarkHidden("liteswap")
6667

68+
cmd.Flags().BoolVar(&skipSettingsCheck, "skip-settings-check", false, "Skip checking and updating IDE settings")
69+
cmd.Flags().MarkHidden("skip-settings-check")
70+
6771
cmd.PreRunE = func(cmd *cobra.Command, args []string) error {
6872
// CLI in the proxy mode is executed by the ssh client and can't prompt for input
6973
if proxyMode {
@@ -113,6 +117,7 @@ the SSH server and handling the connection proxy.
113117
ClientPrivateKeyName: clientPrivateKeyName,
114118
UserKnownHostsFile: userKnownHostsFile,
115119
Liteswap: liteswap,
120+
SkipSettingsCheck: skipSettingsCheck,
116121
AdditionalArgs: args,
117122
}
118123
return client.Run(ctx, wsClient, opts)

experimental/ssh/internal/client/client.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/databricks/cli/experimental/ssh/internal/keys"
2121
"github.com/databricks/cli/experimental/ssh/internal/proxy"
2222
"github.com/databricks/cli/experimental/ssh/internal/sshconfig"
23+
"github.com/databricks/cli/experimental/ssh/internal/vscode"
2324
sshWorkspace "github.com/databricks/cli/experimental/ssh/internal/workspace"
2425
"github.com/databricks/cli/internal/build"
2526
"github.com/databricks/cli/libs/cmdio"
@@ -92,6 +93,8 @@ type ClientOptions struct {
9293
UserKnownHostsFile string
9394
// Liteswap header value for traffic routing (dev/test only).
9495
Liteswap string
96+
// If true, skip checking and updating IDE settings.
97+
SkipSettingsCheck bool
9598
}
9699

97100
func (o *ClientOptions) IsServerlessMode() bool {
@@ -206,6 +209,26 @@ func Run(ctx context.Context, client *databricks.WorkspaceClient, opts ClientOpt
206209
cmdio.LogString(ctx, "Using SSH key: "+keyPath)
207210
cmdio.LogString(ctx, fmt.Sprintf("Secrets scope: %s, key name: %s", secretScopeName, opts.ClientPublicKeyName))
208211

212+
// Check and update IDE settings for serverless mode, where we must set up
213+
// desired server ports (or socket connection mode) for the connection to go through
214+
// (as the majority of the localhost ports on the remote side are blocked by iptable rules).
215+
// Plus the platform (always linux), and extensions (python and jupyter), to make the initial experience smoother.
216+
if opts.IDE != "" && opts.IsServerlessMode() && !opts.ProxyMode && !opts.SkipSettingsCheck && cmdio.IsPromptSupported(ctx) {
217+
err = vscode.CheckAndUpdateSettings(ctx, opts.IDE, opts.ConnectionName)
218+
if err != nil {
219+
cmdio.LogString(ctx, fmt.Sprintf("Failed to update IDE settings: %v", err))
220+
cmdio.LogString(ctx, vscode.GetManualInstructions(opts.IDE, opts.ConnectionName))
221+
cmdio.LogString(ctx, "Use --skip-settings-check to bypass IDE settings verification.")
222+
shouldProceed, promptErr := cmdio.AskYesOrNo(ctx, "Do you want to proceed with the connection?")
223+
if promptErr != nil {
224+
return fmt.Errorf("failed to prompt user: %w", promptErr)
225+
}
226+
if !shouldProceed {
227+
return errors.New("aborted: IDE settings need to be updated manually, user declined to proceed")
228+
}
229+
}
230+
}
231+
209232
var userName string
210233
var serverPort int
211234
var clusterID string

0 commit comments

Comments
 (0)