@@ -64,6 +64,14 @@ function checkRunning(pid: number): true | Error {
64
64
}
65
65
}
66
66
67
+ class LocalAppError extends Error {
68
+ override name = 'LocalAppError' ;
69
+
70
+ constructor ( message ?: string , readonly logPath ?: string ) {
71
+ super ( message ) ;
72
+ }
73
+ }
74
+
67
75
export default class RemoteConnector extends Disposable {
68
76
69
77
public static AUTH_COMPLETE_PATH = '/auth-complete' ;
@@ -391,7 +399,6 @@ export default class RemoteConnector extends Disposable {
391
399
392
400
const workspaceInfo = await withServerApi ( session . accessToken , serviceUrl . toString ( ) , service => service . server . getWorkspace ( workspaceId ) , this . logger ) ;
393
401
if ( ! workspaceInfo . latestInstance ) {
394
- this . logger . error ( 'No running instance for this workspaceId' , workspaceId ) ;
395
402
throw new Error ( 'no_running_instance' ) ;
396
403
}
397
404
@@ -401,31 +408,29 @@ export default class RemoteConnector extends Disposable {
401
408
const sshHostKeyResponse = await fetch ( sshHostKeyEndPoint ) ;
402
409
if ( ! sshHostKeyResponse . ok ) {
403
410
// Gitpod SSH gateway not configured
404
- this . logger . error ( 'SSH gateway not configured for this Gitpod Host' , gitpodHost ) ;
405
411
throw new Error ( 'no_ssh_gateway' ) ;
406
412
}
407
413
408
414
const ownerToken = await withServerApi ( session . accessToken , serviceUrl . toString ( ) , service => service . server . getOwnerToken ( workspaceId ) , this . logger ) ;
409
415
410
416
const sshDestInfo = {
411
417
user : `${ workspaceId } #${ ownerToken } ` ,
412
- hostName : workspaceUrl . host
418
+ // See https://github.com/gitpod-io/gitpod/pull/9786 for reasoning about `.ssh` suffix
419
+ hostName : workspaceUrl . host . replace ( workspaceId , `${ workspaceId } .ssh` )
413
420
} ;
414
421
415
422
return Buffer . from ( JSON . stringify ( sshDestInfo ) , 'utf8' ) . toString ( 'hex' ) ;
416
423
}
417
424
418
- private async getWorkspaceLocalAppSSHDestination ( params : SSHConnectionParams ) : Promise < { localAppSSHDest ? : string ; localAppSSHConfigPath ? : string ; } > {
425
+ private async getWorkspaceLocalAppSSHDestination ( params : SSHConnectionParams ) : Promise < { localAppSSHDest : string ; localAppSSHConfigPath : string ; } > {
419
426
return vscode . window . withProgress ( {
420
427
location : vscode . ProgressLocation . Notification ,
421
428
cancellable : true ,
422
429
title : `Connecting to Gitpod workspace: ${ params . workspaceId } `
423
430
} , async ( _ , token ) => {
424
431
let localAppLogPath : string | undefined ;
425
-
426
- let connection : ResolveSSHConnectionResponse | undefined ;
427
432
try {
428
- connection = await this . withLocalApp ( params . gitpodHost , ( client , config ) => {
433
+ const connection = await this . withLocalApp ( params . gitpodHost , ( client , config ) => {
429
434
localAppLogPath = config . logPath ;
430
435
431
436
const request = new ResolveSSHConnectionRequest ( ) ;
@@ -435,26 +440,18 @@ export default class RemoteConnector extends Disposable {
435
440
client . resolveSSHConnection ( request , ( e , r ) => r ? resolve ( r ) : reject ( e ) )
436
441
) ;
437
442
} , token ) ;
438
- } catch ( e ) {
439
- if ( e instanceof Error && e . message !== 'cancelled' ) {
440
- this . logger . error ( `Failed to connect to remote workspace ${ params . workspaceId } using local app` , e ) ;
441
443
442
- const seeLogs = 'See Logs' ;
443
- const action = await vscode . window . showErrorMessage ( `Failed to connect to remote workspace ${ params . workspaceId } using local app` , seeLogs ) ;
444
- if ( action === seeLogs ) {
445
- this . logger . show ( ) ;
446
- if ( localAppLogPath ) {
447
- const document = await vscode . workspace . openTextDocument ( vscode . Uri . file ( localAppLogPath ) ) ;
448
- vscode . window . showTextDocument ( document ) ;
449
- }
450
- }
444
+ return {
445
+ localAppSSHDest : connection . getHost ( ) ,
446
+ localAppSSHConfigPath : connection . getConfigFile ( )
447
+ } ;
448
+ } catch ( e ) {
449
+ if ( e instanceof Error && e . message === 'cancelled' ) {
450
+ throw e ;
451
451
}
452
- }
453
452
454
- return {
455
- localAppSSHDest : connection ?. getHost ( ) ,
456
- localAppSSHConfigPath : connection ?. getConfigFile ( )
457
- } ;
453
+ throw new LocalAppError ( e . message , localAppLogPath ) ;
454
+ }
458
455
} ) ;
459
456
}
460
457
@@ -534,21 +531,47 @@ export default class RemoteConnector extends Disposable {
534
531
try {
535
532
sshDestination = await this . getWorkspaceSSHDestination ( params . workspaceId , params . gitpodHost ) ;
536
533
} catch ( e ) {
537
- if ( e instanceof Error && e . message === 'no_running_instance' ) {
534
+ if ( e instanceof Error && e . message === 'no_ssh_gateway' ) {
535
+ this . logger . error ( 'SSH gateway not configured for this Gitpod Host' , params . gitpodHost ) ;
536
+ // Do nothing and continue execution
537
+ } else if ( e instanceof Error && e . message === 'no_running_instance' ) {
538
+ this . logger . error ( 'No running instance for this workspaceId' , params . workspaceId ) ;
538
539
vscode . window . showErrorMessage ( `Failed to connect to remote workspace: No running instance for '${ params . workspaceId } '` ) ;
539
540
return ;
541
+ } else {
542
+ this . logger . error ( `Failed to connect to remote workspace ${ params . workspaceId } ` , e ) ;
543
+ const seeLogs = 'See Logs' ;
544
+ const action = await vscode . window . showErrorMessage ( `Failed to connect to remote workspace ${ params . workspaceId } ` , seeLogs ) ;
545
+ if ( action === seeLogs ) {
546
+ this . logger . show ( ) ;
547
+ }
548
+ return ;
540
549
}
541
550
}
542
551
543
552
const usingSSHGateway = ! ! sshDestination ;
544
553
let localAppSSHConfigPath : string | undefined ;
545
554
if ( ! usingSSHGateway ) {
546
- vscode . window . showInformationMessage ( `Falling back connecting to remote workspace using local app. You should update your Gitpod installation [enabling direct SSH access](https://github.com/gitpod-io/gitpod/blob/main/install/installer/docs/workspace-ssh-access.md)`) ;
555
+ 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. `) ;
547
556
try {
548
557
const localAppDestData = await this . getWorkspaceLocalAppSSHDestination ( params ) ;
549
558
sshDestination = localAppDestData . localAppSSHDest ;
550
559
localAppSSHConfigPath = localAppDestData . localAppSSHConfigPath ;
551
560
} catch ( e ) {
561
+ this . logger . error ( `Failed to connect to remote workspace ${ params . workspaceId } ` , e ) ;
562
+ if ( e instanceof LocalAppError ) {
563
+ const seeLogs = 'See Logs' ;
564
+ const action = await vscode . window . showErrorMessage ( `Failed to connect to remote workspace ${ params . workspaceId } ` , seeLogs ) ;
565
+ if ( action === seeLogs ) {
566
+ this . logger . show ( ) ;
567
+ if ( e . logPath ) {
568
+ const document = await vscode . workspace . openTextDocument ( vscode . Uri . file ( e . logPath ) ) ;
569
+ vscode . window . showTextDocument ( document ) ;
570
+ }
571
+ }
572
+ } else {
573
+ // Do nothing, user cancelled the operation
574
+ }
552
575
return ;
553
576
}
554
577
}
0 commit comments