@@ -531,7 +531,7 @@ export default class RemoteConnector extends Disposable {
531531 if ( identityFilePaths . length ) {
532532 sshDestInfo . user = `${ workspaceId } #${ ownerToken } ` ;
533533 }
534- this . logger . warn ( `Registered SSH public keys not supported in ${ gitpodHost } , using version ${ gitpodVersion } ` ) ;
534+ this . logger . warn ( `Registered SSH public keys not supported in ${ gitpodHost } , using version ${ gitpodVersion . version } ` ) ;
535535 }
536536
537537 return {
@@ -618,20 +618,28 @@ export default class RemoteConnector extends Disposable {
618618 return true ;
619619 }
620620
621- private async showSSHPasswordModal ( password : string ) {
621+ private async showSSHPasswordModal ( password : string , gitpodHost : string ) {
622622 const maskedPassword = '•' . repeat ( password . length - 3 ) + password . substring ( password . length - 3 ) ;
623623
624+ const gitpodVersion = await getGitpodVersion ( gitpodHost ) ;
625+ const sshKeysSupported = isFeatureSupported ( gitpodVersion , 'SSHPublicKeys' ) ;
626+
624627 const copy : vscode . MessageItem = { title : 'Copy' } ;
625628 const configureSSH : vscode . MessageItem = { title : 'Configure SSH' } ;
626629 const showLogs : vscode . MessageItem = { title : 'Show logs' , isCloseAffordance : true } ;
627- const action = await vscode . window . showWarningMessage ( `You don't have registered any SSH public key for this machine in your Gitpod account.\nAlternatively, copy and use this temporary password until workspace restart: ${ maskedPassword } ` , { modal : true } , copy , configureSSH , showLogs ) ;
630+ const message = sshKeysSupported
631+ ? `You don't have registered any SSH public key for this machine in your Gitpod account.\nAlternatively, copy and use this temporary password until workspace restart: ${ maskedPassword } `
632+ : `An SSH key is required for passwordless authentication.\nAlternatively, copy and use this password: ${ maskedPassword } ` ;
633+ const action = await vscode . window . showWarningMessage ( message , { modal : true } , copy , configureSSH , showLogs ) ;
628634 if ( action === copy ) {
629635 await vscode . env . clipboard . writeText ( password ) ;
630636 return ;
631637 }
632638 if ( action === configureSSH ) {
633- await vscode . env . openExternal ( vscode . Uri . parse ( 'https://gitpod.io/keys' ) ) ;
634- throw new Error ( `SSH password modal dialog, ${ configureSSH } ` ) ;
639+ const serviceUrl = new URL ( gitpodHost ) . toString ( ) . replace ( / \/ $ / , '' ) ;
640+ const externalUrl = sshKeysSupported ? `${ serviceUrl } /keys` : 'https://www.gitpod.io/docs/configure/ssh#create-an-ssh-key' ;
641+ await vscode . env . openExternal ( vscode . Uri . parse ( externalUrl ) ) ;
642+ throw new Error ( `SSH password modal dialog, Configure SSH` ) ;
635643 }
636644
637645 this . logger . show ( ) ;
@@ -658,7 +666,7 @@ export default class RemoteConnector extends Disposable {
658666 if ( isFeatureSupported ( gitpodVersion , 'SSHPublicKeys' ) /* && isFeatureSupported('', 'sendHeartBeat') */ ) {
659667 sessionScopes . push ( 'function:getSSHPublicKeys' , 'function:sendHeartBeat' ) ;
660668 } else {
661- this . logger . warn ( `function:getSSHPublicKeys and function:sendHeartBeat session scopes not supported in ${ gitpodHost } , using version ${ gitpodVersion } ` ) ;
669+ this . logger . warn ( `function:getSSHPublicKeys and function:sendHeartBeat session scopes not supported in ${ gitpodHost } , using version ${ gitpodVersion . version } ` ) ;
662670 }
663671
664672 return vscode . authentication . getSession (
@@ -680,6 +688,7 @@ export default class RemoteConnector extends Disposable {
680688 }
681689
682690 const params : SSHConnectionParams = JSON . parse ( uri . query ) ;
691+ const gitpodVersion = await getGitpodVersion ( params . gitpodHost ) ;
683692
684693 const session = await this . getGitpodSession ( params . gitpodHost ) ;
685694 if ( ! session ) {
@@ -692,18 +701,18 @@ export default class RemoteConnector extends Disposable {
692701 let sshDestination : string | undefined ;
693702 if ( ! forceUseLocalApp ) {
694703 try {
695- this . telemetry . sendTelemetryEvent ( 'vscode_desktop_ssh' , { kind : 'gateway' , status : 'connecting' , ...params } ) ;
704+ this . telemetry . sendRawTelemetryEvent ( 'vscode_desktop_ssh' , { kind : 'gateway' , status : 'connecting' , ...params , gitpodVersion : gitpodVersion . raw } ) ;
696705
697706 const { destination, password } = await this . getWorkspaceSSHDestination ( session . accessToken , params ) ;
698707 sshDestination = destination ;
699708
700709 if ( password ) {
701- await this . showSSHPasswordModal ( password ) ;
710+ await this . showSSHPasswordModal ( password , params . gitpodHost ) ;
702711 }
703712
704- this . telemetry . sendTelemetryEvent ( 'vscode_desktop_ssh' , { kind : 'gateway' , status : 'connected' , ...params } ) ;
713+ this . telemetry . sendRawTelemetryEvent ( 'vscode_desktop_ssh' , { kind : 'gateway' , status : 'connected' , ...params , gitpodVersion : gitpodVersion . raw } ) ;
705714 } catch ( e ) {
706- this . telemetry . sendRawTelemetryEvent ( 'vscode_desktop_ssh' , { kind : 'gateway' , status : 'failed' , reason : e . toString ( ) , ...params } ) ;
715+ this . telemetry . sendRawTelemetryEvent ( 'vscode_desktop_ssh' , { kind : 'gateway' , status : 'failed' , reason : e . toString ( ) , ...params , gitpodVersion : gitpodVersion . raw } ) ;
707716 if ( e instanceof NoSSHGatewayError ) {
708717 this . logger . error ( 'No SSH gateway:' , e ) ;
709718 vscode . window . showWarningMessage ( `${ e . host } 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.` ) ;
@@ -735,15 +744,15 @@ export default class RemoteConnector extends Disposable {
735744 let localAppSSHConfigPath : string | undefined ;
736745 if ( ! usingSSHGateway ) {
737746 try {
738- this . telemetry . sendTelemetryEvent ( 'vscode_desktop_ssh' , { kind : 'local-app' , status : 'connecting' , ...params } ) ;
747+ this . telemetry . sendRawTelemetryEvent ( 'vscode_desktop_ssh' , { kind : 'local-app' , status : 'connecting' , ...params , gitpodVersion : gitpodVersion . raw } ) ;
739748
740749 const localAppDestData = await this . getWorkspaceLocalAppSSHDestination ( params ) ;
741750 sshDestination = localAppDestData . localAppSSHDest ;
742751 localAppSSHConfigPath = localAppDestData . localAppSSHConfigPath ;
743752
744- this . telemetry . sendTelemetryEvent ( 'vscode_desktop_ssh' , { kind : 'local-app' , status : 'connected' , ...params } ) ;
753+ this . telemetry . sendRawTelemetryEvent ( 'vscode_desktop_ssh' , { kind : 'local-app' , status : 'connected' , ...params , gitpodVersion : gitpodVersion . raw } ) ;
745754 } catch ( e ) {
746- this . telemetry . sendRawTelemetryEvent ( 'vscode_desktop_ssh' , { kind : 'local-app' , status : 'failed' , reason : e . toString ( ) , ...params } ) ;
755+ this . telemetry . sendRawTelemetryEvent ( 'vscode_desktop_ssh' , { kind : 'local-app' , status : 'failed' , reason : e . toString ( ) , ...params , gitpodVersion : gitpodVersion . raw } ) ;
747756 this . logger . error ( `Failed to connect ${ params . workspaceId } Gitpod workspace:` , e ) ;
748757 if ( e instanceof LocalAppError ) {
749758 const seeLogs = 'See Logs' ;
@@ -829,26 +838,27 @@ export default class RemoteConnector extends Disposable {
829838 if ( isFeatureSupported ( gitpodVersion , 'localHeartbeat' ) ) {
830839 // gitpod remote extension installation is async so sometimes gitpod-desktop will activate before gitpod-remote
831840 // let's try a few times for it to finish install
832- let retryCount = 10 ;
833- const tryStartHeartbeat = async ( ) => {
841+ let retryCount = 15 ;
842+ const tryStopRemoteHeartbeat = async ( ) => {
834843 // Check for gitpod remote extension version to avoid sending heartbeat in both extensions at the same time
835844 const isGitpodRemoteHeartbeatCancelled = await cancelGitpodRemoteHeartbeat ( ) ;
836845 if ( isGitpodRemoteHeartbeatCancelled ) {
837- const session = await this . getGitpodSession ( connectionInfo . gitpodHost ) ;
838- if ( session ) {
839- this . startHeartBeat ( session . accessToken , connectionInfo ) ;
840- }
841- this . telemetry . sendTelemetryEvent ( 'vscode_desktop_heartbeat_state' , { enabled : String ( ! ! this . heartbeatManager ) , gitpodHost : connectionInfo . gitpodHost , workspaceId : connectionInfo . workspaceId , instanceId : connectionInfo . instanceId } ) ;
846+ this . telemetry . sendTelemetryEvent ( 'vscode_desktop_heartbeat_state' , { enabled : String ( true ) , gitpodHost : connectionInfo . gitpodHost , workspaceId : connectionInfo . workspaceId , instanceId : connectionInfo . instanceId , gitpodVersion : gitpodVersion . raw } ) ;
842847 } else if ( retryCount > 0 ) {
843848 retryCount -- ;
844- setTimeout ( tryStartHeartbeat , 3000 ) ;
849+ setTimeout ( tryStopRemoteHeartbeat , 3000 ) ;
845850 } else {
846- this . telemetry . sendTelemetryEvent ( 'vscode_desktop_heartbeat_state' , { enabled : String ( false ) , gitpodHost : connectionInfo . gitpodHost , workspaceId : connectionInfo . workspaceId , instanceId : connectionInfo . instanceId } ) ;
851+ this . telemetry . sendTelemetryEvent ( 'vscode_desktop_heartbeat_state' , { enabled : String ( false ) , gitpodHost : connectionInfo . gitpodHost , workspaceId : connectionInfo . workspaceId , instanceId : connectionInfo . instanceId , gitpodVersion : gitpodVersion . raw } ) ;
847852 }
848853 } ;
849- tryStartHeartbeat ( ) ;
854+
855+ const session = await this . getGitpodSession ( connectionInfo . gitpodHost ) ;
856+ if ( session ) {
857+ this . startHeartBeat ( session . accessToken , connectionInfo ) ;
858+ tryStopRemoteHeartbeat ( ) ;
859+ }
850860 } else {
851- this . logger . warn ( `Local heatbeat not supported in ${ connectionInfo . gitpodHost } , using version ${ gitpodVersion } ` ) ;
861+ this . logger . warn ( `Local heatbeat not supported in ${ connectionInfo . gitpodHost } , using version ${ gitpodVersion . version } ` ) ;
852862 }
853863 }
854864
0 commit comments