Skip to content

Commit e29e38c

Browse files
committed
Add gitpod.remote.useLocalApp setting and more analitycs events
1 parent d27873a commit e29e38c

File tree

3 files changed

+56
-27
lines changed

3 files changed

+56
-27
lines changed

extensions/gitpod/package.json

+6
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@
4848
"description": "Gitpod Service URL. Update this if you are using a Gitpod self-hosted installation.",
4949
"default": "https://gitpod.io/",
5050
"scope": "application"
51+
},
52+
"gitpod.remote.useLocalApp":{
53+
"type":"boolean",
54+
"description": "Use the local companion app to connect to a remote workspace.\nWarning: Connecting to a remote workspace using local companion app will be removed in the near future.",
55+
"default": false,
56+
"scope": "application"
5157
}
5258
}
5359
},

extensions/gitpod/src/extension.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ import { exportLogs } from './exportLogs';
1313

1414
const EXTENSION_ID = 'gitpod.gitpod-desktop';
1515
const FIRST_INSTALL_KEY = 'gitpod-desktop.firstInstall';
16-
const ANALITYCS_KEY = 'bUY8IRdJ42KjLOBS9LoIHMYFBD8rSzjU';
16+
17+
// const ANALITYCS_KEY = 'YErmvd89wPsrCuGcVnF2XAl846W9WIGl'; // For development
18+
const ANALITYCS_KEY = 'bUY8IRdJ42KjLOBS9LoIHMYFBD8rSzjU'; // For release
1719

1820
let telemetry: TelemetryReporter;
1921

@@ -68,7 +70,7 @@ export async function activate(context: vscode.ExtensionContext) {
6870
}));
6971

7072
const authProvider = new GitpodAuthenticationProvider(context, logger, telemetry);
71-
const remoteConnector = new RemoteConnector(context, logger);
73+
const remoteConnector = new RemoteConnector(context, logger, telemetry);
7274
context.subscriptions.push(authProvider);
7375
context.subscriptions.push(remoteConnector);
7476
context.subscriptions.push(vscode.window.registerUriHandler({

extensions/gitpod/src/remoteConnector.ts

+46-25
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import * as vscode from 'vscode';
1414
import Log from './common/logger';
1515
import { Disposable } from './common/dispose';
1616
import { withServerApi } from './internalApi';
17+
import TelemetryReporter from './telemetryReporter';
1718

1819
interface SSHConnectionParams {
1920
workspaceId: string;
@@ -84,7 +85,7 @@ export default class RemoteConnector extends Disposable {
8485
public static AUTH_COMPLETE_PATH = '/auth-complete';
8586
private static LOCK_COUNT = 0;
8687

87-
constructor(private readonly context: vscode.ExtensionContext, private readonly logger: Log) {
88+
constructor(private readonly context: vscode.ExtensionContext, private readonly logger: Log, private readonly telemetry: TelemetryReporter) {
8889
super();
8990

9091
this.releaseStaleLocks();
@@ -451,7 +452,9 @@ export default class RemoteConnector extends Disposable {
451452
}
452453
},
453454
hostVerifier(hashedKey) {
454-
return (hashedKey as any as Buffer).toString('base64') === sshHostKeys[0].host_key;
455+
// We didn't specify `hostHash` so `hashedKey` is a Buffer object
456+
const encodedKey = (hashedKey as any as Buffer).toString('base64');
457+
return sshHostKeys.some(keyData => keyData.host_key === encodedKey);
455458
}
456459
});
457460
});
@@ -548,8 +551,10 @@ export default class RemoteConnector extends Disposable {
548551
return;
549552
}
550553

551-
const params: SSHConnectionParams = JSON.parse(uri.query);
552554
const gitpodHost = vscode.workspace.getConfiguration('gitpod').get<string>('host')!;
555+
const forceUseLocalApp = vscode.workspace.getConfiguration('gitpod').get<boolean>('remote.useLocalApp')!;
556+
557+
const params: SSHConnectionParams = JSON.parse(uri.query);
553558
if (new URL(params.gitpodHost).host !== new URL(gitpodHost).host) {
554559
const yes = 'Yes';
555560
const cancel = 'Cancel';
@@ -565,41 +570,56 @@ export default class RemoteConnector extends Disposable {
565570
this.logger.info('Opening remote workspace', uri.toString());
566571

567572
let sshDestination: string | undefined;
568-
try {
569-
sshDestination = await this.getWorkspaceSSHDestination(params.workspaceId, params.gitpodHost);
570-
} catch (e) {
571-
if (e instanceof SSHError) {
572-
this.logger.error('SSH test connection error', e.cause);
573-
vscode.window.showWarningMessage(`There was an error connecting to ${params.workspaceId} through SSH, connecting via the deprecated SSH tunnel over WebSocket.`);
574-
// Do nothing and continue execution
575-
} else if (e instanceof Error && e.message === 'no_ssh_gateway') {
576-
this.logger.error(`SSH gateway not configured for this Gitpod Host ${params.gitpodHost}`);
577-
vscode.window.showWarningMessage(`${params.gitpodHost} does not support [direct SSH access](https://github.com/gitpod-io/gitpod/blob/main/install/installer/docs/workspace-ssh-access.md), connecting via the deprecated SSH tunnel over WebSocket.`);
578-
// Do nothing and continue execution
579-
} else if (e instanceof Error && e.message === 'no_running_instance') {
580-
this.logger.error(`No running instance for this workspaceId ${params.workspaceId}`);
581-
vscode.window.showErrorMessage(`Failed to connect to remote workspace: No running instance for '${params.workspaceId}'`);
582-
return;
583-
} else {
584-
this.logger.error(`Failed to connect to remote workspace ${params.workspaceId}`, e);
585-
const seeLogs = 'See Logs';
586-
const action = await vscode.window.showErrorMessage(`Failed to connect to remote workspace ${params.workspaceId}`, seeLogs);
587-
if (action === seeLogs) {
588-
this.logger.show();
573+
if (!forceUseLocalApp) {
574+
try {
575+
this.telemetry.sendTelemetryEvent('gitpod_desktop_ssh', { kind: 'gateway', status: 'connecting' });
576+
577+
sshDestination = await this.getWorkspaceSSHDestination(params.workspaceId, params.gitpodHost);
578+
579+
this.telemetry.sendTelemetryEvent('gitpod_desktop_ssh', { kind: 'gateway', status: 'connected' });
580+
} catch (e) {
581+
if (e instanceof Error && e.message === 'no_ssh_gateway') {
582+
this.logger.error(`SSH gateway not configured for this Gitpod Host ${params.gitpodHost}`);
583+
vscode.window.showWarningMessage(`${params.gitpodHost} does not support [direct SSH access](https://github.com/gitpod-io/gitpod/blob/main/install/installer/docs/workspace-ssh-access.md), connecting via the deprecated SSH tunnel over WebSocket.`);
584+
this.telemetry.sendTelemetryEvent('gitpod_desktop_ssh', { kind: 'gateway', status: 'failed', reason: 'no-ssh-gateway' });
585+
// Do nothing and continue execution
586+
} else if (e instanceof Error && e.message === 'no_running_instance') {
587+
this.logger.error(`No running instance for this workspaceId ${params.workspaceId}`);
588+
vscode.window.showErrorMessage(`Failed to connect to remote workspace: No running instance for '${params.workspaceId}'`);
589+
this.telemetry.sendTelemetryEvent('gitpod_desktop_ssh', { kind: 'gateway', status: 'failed', reason: 'ws-not-running' });
590+
return;
591+
} else {
592+
if (e instanceof SSHError) {
593+
this.logger.error('SSH test connection error', e.cause);
594+
this.telemetry.sendTelemetryEvent('gitpod_desktop_ssh', { kind: 'gateway', status: 'failed', reason: 'ssh-blocked' });
595+
} else {
596+
this.logger.error(`Failed to connect to remote workspace ${params.workspaceId}`, e);
597+
this.telemetry.sendTelemetryEvent('gitpod_desktop_ssh', { kind: 'gateway', status: 'failed', reason: 'other-error' });
598+
}
599+
const seeLogs = 'See Logs';
600+
const action = await vscode.window.showErrorMessage(`Failed to connect to remote workspace ${params.workspaceId}`, seeLogs);
601+
if (action === seeLogs) {
602+
this.logger.show();
603+
}
604+
return;
589605
}
590-
return;
591606
}
592607
}
593608

594609
const usingSSHGateway = !!sshDestination;
595610
let localAppSSHConfigPath: string | undefined;
596611
if (!usingSSHGateway) {
597612
try {
613+
this.telemetry.sendTelemetryEvent('gitpod_desktop_ssh', { kind: 'local-app', status: 'connecting' });
614+
598615
const localAppDestData = await this.getWorkspaceLocalAppSSHDestination(params);
599616
sshDestination = localAppDestData.localAppSSHDest;
600617
localAppSSHConfigPath = localAppDestData.localAppSSHConfigPath;
618+
619+
this.telemetry.sendTelemetryEvent('gitpod_desktop_ssh', { kind: 'local-app', status: 'connected' });
601620
} catch (e) {
602621
this.logger.error(`Failed to connect to remote workspace ${params.workspaceId}`, e);
622+
this.telemetry.sendTelemetryEvent('gitpod_desktop_ssh', { kind: 'local-app', status: 'failed', reason: 'other-error' });
603623
if (e instanceof LocalAppError) {
604624
const seeLogs = 'See Logs';
605625
const action = await vscode.window.showErrorMessage(`Failed to connect to remote workspace ${params.workspaceId}`, seeLogs);
@@ -612,6 +632,7 @@ export default class RemoteConnector extends Disposable {
612632
}
613633
} else {
614634
// Do nothing, user cancelled the operation
635+
this.telemetry.sendTelemetryEvent('gitpod_desktop_ssh', { kind: 'local-app', status: 'failed', reason: 'cancelled' });
615636
}
616637
return;
617638
}

0 commit comments

Comments
 (0)