diff --git a/packages/core/src/awsService/ec2/model.ts b/packages/core/src/awsService/ec2/model.ts index 9a5e13feaef..42d69828aa7 100644 --- a/packages/core/src/awsService/ec2/model.ts +++ b/packages/core/src/awsService/ec2/model.ts @@ -36,7 +36,7 @@ import { SshKeyPair } from './sshKeyPair' import { Ec2SessionTracker } from './remoteSessionManager' import { getEc2SsmEnv } from './utils' -export type Ec2ConnectErrorCode = 'EC2SSMStatus' | 'EC2SSMPermission' | 'EC2SSMConnect' | 'EC2SSMAgentStatus' +export type Ec2ConnectErrorCode = 'EC2SSMStatus' | 'EC2SSMPermission' | 'EC2SSMTestConnect' | 'EC2SSMAgentStatus' export interface Ec2RemoteEnv extends VscodeRemoteConnection { selection: Ec2Selection @@ -215,8 +215,8 @@ export class Ec2Connecter implements vscode.Disposable { remoteUser.name ) } catch (err) { - const message = err instanceof SshError ? 'Testing SSH connection to instance failed' : '' - this.throwConnectionError(message, selection, err as Error) + const message = err instanceof SshError ? `Testing SSM connection to instance failed: ${err.message}` : '' + this.throwConnectionError(message, selection, { ...(err as Error), code: 'EC2SSMTestConnect' }) } finally { await this.ssmClient.terminateSession(testSession) } diff --git a/packages/core/src/shared/extensions/ssh.ts b/packages/core/src/shared/extensions/ssh.ts index ba349a902c2..44af313d108 100644 --- a/packages/core/src/shared/extensions/ssh.ts +++ b/packages/core/src/shared/extensions/ssh.ts @@ -130,6 +130,15 @@ export class RemoteSshSettings extends Settings.define('remote.SSH', remoteSshTy } } +/** + * Test a SSH connection over SSM. + * @param ProcessClass given process to test the connection within. + * @param hostname + * @param sshPath + * @param user + * @param session SSM session credentials. These cannot be reused, so it may be required to create a seperate session for the test connection. + * @returns + */ export async function testSshConnection( ProcessClass: typeof ChildProcess, hostname: string, @@ -137,20 +146,18 @@ export async function testSshConnection( user: string, session: SSM.StartSessionResponse ): Promise { + const env = { SESSION_ID: session.SessionId, STREAM_URL: session.StreamUrl, TOKEN: session.TokenValue } + const process = new ProcessClass(sshPath, ['-T', `${user}@${hostname}`, 'echo "test connection succeeded" && exit']) try { - const env = { SESSION_ID: session.SessionId, STREAM_URL: session.StreamUrl, TOKEN: session.TokenValue } - const result = await new ProcessClass(sshPath, [ - '-T', - `${user}@${hostname}`, - 'echo "test connection succeeded" && exit', - ]).run({ + return await process.run({ spawnOptions: { env, }, }) - return result } catch (error) { - throw new SshError('SSH connection test failed', { cause: error as Error }) + throw new SshError(process.result()?.stderr ?? 'An unknown error occurred when testing the connection', { + cause: error as Error, + }) } }