From 8d5c9728aa30ae27c777063a8f10c79fea45974d Mon Sep 17 00:00:00 2001 From: Pudong Zheng Date: Thu, 7 Dec 2023 09:54:30 +0000 Subject: [PATCH] use http create key endpoint --- package.json | 8 ++- src/local-ssh/ipc/extensionServiceServer.ts | 62 +++++++-------------- yarn.lock | 5 -- 3 files changed, 24 insertions(+), 51 deletions(-) diff --git a/package.json b/package.json index b25204d..299b201 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,10 @@ "type": "string", "description": "The log level for ssh proxy.", "scope": "application", - "enum": ["none", "debug"], + "enum": [ + "none", + "debug" + ], "default": "none" } } @@ -429,13 +432,12 @@ "webpack-cli": "^4.7.2" }, "dependencies": { - "@connectrpc/connect-node": "1.1.2", "@connectrpc/connect": "1.1.2", + "@connectrpc/connect-node": "1.1.2", "@gitpod/gitpod-protocol": "main-gha", "@gitpod/local-app-api-grpcweb": "main-gha", "@gitpod/public-api": "main-gha", "@gitpod/supervisor-api-grpcweb": "main-gha", - "@improbable-eng/grpc-web-node-http-transport": "^0.14.0", "@microsoft/dev-tunnels-ssh": "^3.11.24", "@microsoft/dev-tunnels-ssh-keys": "^3.11.24", "@microsoft/dev-tunnels-ssh-tcp": "^3.11.24", diff --git a/src/local-ssh/ipc/extensionServiceServer.ts b/src/local-ssh/ipc/extensionServiceServer.ts index 9136fc3..e725642 100644 --- a/src/local-ssh/ipc/extensionServiceServer.ts +++ b/src/local-ssh/ipc/extensionServiceServer.ts @@ -13,14 +13,11 @@ import { Server, createChannel, createClient, createServer } from 'nice-grpc'; import { ITelemetryService } from '../../common/telemetry'; import { Configuration } from '../../configuration'; import { timeout } from '../../common/async'; -import { BrowserHeaders } from 'browser-headers'; -import { ControlServiceClient, ServiceError } from '@gitpod/supervisor-api-grpcweb/lib/control_pb_service'; -import { NodeHttpTransport } from '@improbable-eng/grpc-web-node-http-transport'; -import { CreateSSHKeyPairRequest, CreateSSHKeyPairResponse } from '@gitpod/supervisor-api-grpcweb/lib/control_pb'; +import { ServiceError } from '@gitpod/supervisor-api-grpcweb/lib/control_pb_service'; import * as ssh2 from 'ssh2'; import { ParsedKey } from 'ssh2-streams'; import { WrapError } from '../../common/utils'; -import { ConnectError, Code } from '@connectrpc/connect'; +import { ConnectError } from '@connectrpc/connect'; import { rawWorkspaceToWorkspaceData } from '../../publicApi'; function isServiceError(obj: any): obj is ServiceError { @@ -28,32 +25,6 @@ function isServiceError(obj: any): obj is ServiceError { return obj != null && typeof obj === 'object' && typeof obj.metadata != null && typeof obj.code === 'number' && typeof obj.message === 'string'; } -function wrapSupervisorAPIError(callback: () => Promise, opts?: { maxRetries?: number; signal?: AbortSignal }): Promise { - const maxRetries = opts?.maxRetries ?? 5; - let retries = 0; - - const onError: (err: any) => Promise = async (err) => { - if (!isServiceError(err)) { - throw err; - } - - const shouldRetry = opts?.signal ? !opts.signal.aborted : retries++ < maxRetries; - const isNetworkProblem = err.message.includes('Response closed without'); - if (shouldRetry && (err.code === Code.Unavailable || err.code === Code.Aborted || isNetworkProblem)) { - await timeout(1000); - return callback().catch(onError); - } - if (isNetworkProblem) { - err.code = Code.Unavailable; - } - // codes of grpc-web are align with grpc and connect - // see https://github.com/improbable-eng/grpc-web/blob/1d9bbb09a0990bdaff0e37499570dbc7d6e58ce8/client/grpc-web/src/Code.ts#L1 - throw new WrapError('Failed to call supervisor API', err, 'SupervisorAPI:' + Code[err.code]); - }; - - return callback().catch(onError); -} - class ExtensionServiceImpl implements ExtensionServiceImplementation { constructor( private logService: ILogService, @@ -65,18 +36,23 @@ class ExtensionServiceImpl implements ExtensionServiceImplementation { private async getWorkspaceSSHKey(ownerToken: string, workspaceUrl: string, signal: AbortSignal) { const url = new URL(workspaceUrl); - url.pathname = '/_supervisor/v1'; - const { privateKey, userName } = await wrapSupervisorAPIError(() => new Promise((resolve, reject) => { - const metadata = new BrowserHeaders(); - metadata.append('x-gitpod-owner-token', ownerToken); - const client = new ControlServiceClient(url.toString(), { transport: NodeHttpTransport() }); - client.createSSHKeyPair(new CreateSSHKeyPairRequest(), metadata, (err, resp) => { - if (err) { - return reject(err); - } - resolve(resp!.toObject()); - }); - }), { signal }); + url.pathname = '/_supervisor/v1/ssh_keys/create'; + + const resp = await fetch(url, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'X-Client': 'vscode-desktop-extension', + "x-gitpod-owner-token": ownerToken + }, + signal + }); + + if (!resp.ok) { + throw new Error(`Cannot create workspace SSH private Key, response: ${resp.status} ${resp.statusText}`); + } + + const { privateKey, userName } = (await resp.json()) as { privateKey: string; userName: string }; const parsedResult = ssh2.utils.parseKey(privateKey); if (parsedResult instanceof Error || !parsedResult) { diff --git a/yarn.lock b/yarn.lock index 430f7f6..fe9cb50 100644 --- a/yarn.lock +++ b/yarn.lock @@ -203,11 +203,6 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== -"@improbable-eng/grpc-web-node-http-transport@^0.14.0": - version "0.14.1" - resolved "https://registry.yarnpkg.com/@improbable-eng/grpc-web-node-http-transport/-/grpc-web-node-http-transport-0.14.1.tgz#16c078db2e10aca9a8f7fb235a80b2fa447273a3" - integrity sha512-ZsCTzI1iKUbmQjB5DNZSI5/hvdliuaPpS2h8mVj1QzynL3IFb5NrNnHVHbfcH1wbm26Ka6Z1CrKFGvKLrmbFIg== - "@improbable-eng/grpc-web@0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@improbable-eng/grpc-web/-/grpc-web-0.14.0.tgz#a71c5af471dcef6a2810798f71f93ed8d6ac3817"