( page: Page, workspace: string, binaryPath = coderBinary, binaryArgs: string[] = [], )
| 363 | * sshIntoWorkspace spawns a Coder SSH process and a client connected to it. |
| 364 | */ |
| 365 | export const sshIntoWorkspace = async ( |
| 366 | page: Page, |
| 367 | workspace: string, |
| 368 | binaryPath = coderBinary, |
| 369 | binaryArgs: string[] = [], |
| 370 | ): Promise<ssh.Client> => { |
| 371 | const sessionToken = await findSessionToken(page); |
| 372 | return new Promise<ssh.Client>((resolve, reject) => { |
| 373 | const cp = spawn(binaryPath, [...binaryArgs, "ssh", "--stdio", workspace], { |
| 374 | env: { |
| 375 | ...process.env, |
| 376 | CODER_SESSION_TOKEN: sessionToken, |
| 377 | CODER_URL: `http://localhost:${coderPort}`, |
| 378 | }, |
| 379 | }); |
| 380 | cp.on("error", (err) => reject(err)); |
| 381 | const proxyStream = new Duplex({ |
| 382 | read: (size) => { |
| 383 | return cp.stdout.read(Math.min(size, cp.stdout.readableLength)); |
| 384 | }, |
| 385 | write: cp.stdin.write.bind(cp.stdin), |
| 386 | }); |
| 387 | cp.stderr.on("data", (data) => console.info(data.toString())); |
| 388 | cp.stdout.on("readable", (...args) => { |
| 389 | proxyStream.emit("readable", ...args); |
| 390 | if (cp.stdout.readableLength > 0) { |
| 391 | proxyStream.emit("data", cp.stdout.read()); |
| 392 | } |
| 393 | }); |
| 394 | const client = new ssh.Client(); |
| 395 | client.connect({ |
| 396 | sock: proxyStream, |
| 397 | username: "coder", |
| 398 | }); |
| 399 | client.on("error", (err) => reject(err)); |
| 400 | client.on("ready", () => { |
| 401 | resolve(client); |
| 402 | }); |
| 403 | }); |
| 404 | }; |
| 405 | |
| 406 | export const stopWorkspace = async (page: Page, workspaceName: string) => { |
| 407 | const user = currentUser(page); |
no test coverage detected