Skip to content

Commit 7e2c50d

Browse files
committed
Use coder ssh in place of coder vscodessh
Build on top of recent coder PRs to make coder ssh provide equivalent functionality to vscodessh, avoiding the need for a VSCode-specific ssh subcommand.
1 parent 2766d2f commit 7e2c50d

File tree

3 files changed

+38
-13
lines changed

3 files changed

+38
-13
lines changed

CONTRIBUTING.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ contains the `coder-vscode` prefix, and if so we delay activation to:
3434

3535
```text
3636
Host coder-vscode.dev.coder.com--*
37-
ProxyCommand "/tmp/coder" vscodessh --network-info-dir "/home/kyle/.config/Code/User/globalStorage/coder.coder-remote/net" --session-token-file "/home/kyle/.config/Code/User/globalStorage/coder.coder-remote/dev.coder.com/session_token" --url-file "/home/kyle/.config/Code/User/globalStorage/coder.coder-remote/dev.coder.com/url" %h
37+
ProxyCommand "/tmp/coder" --global-config "/home/kyle/.config/Code/User/globalStorage/coder.coder-remote/dev.coder.com" ssh --stdio --network-info-dir "/home/kyle/.config/Code/User/globalStorage/coder.coder-remote/net" --ssh-host-prefix coder-vscode.dev.coder.com-- %h
3838
ConnectTimeout 0
3939
StrictHostKeyChecking no
4040
UserKnownHostsFile /dev/null
@@ -50,8 +50,8 @@ specified port. This port is printed to the `Remote - SSH` log file in the VS
5050
Code Output panel in the format `-> socksPort <port> ->`. We use this port to
5151
find the SSH process ID that is being used by the remote session.
5252

53-
The `vscodessh` subcommand on the `coder` binary periodically flushes its
54-
network information to `network-info-dir + "/" + process.ppid`. SSH executes
53+
The `ssh` subcommand on the `coder` binary periodically flushes its network
54+
information to `network-info-dir + "/" + process.ppid`. SSH executes
5555
`ProxyCommand`, which means the `process.ppid` will always be the matching SSH
5656
command.
5757

src/featureSet.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as semver from "semver"
33
export type FeatureSet = {
44
vscodessh: boolean
55
proxyLogDirectory: boolean
6+
wildcardSSH: boolean
67
}
78

89
/**
@@ -21,5 +22,9 @@ export function featureSetForVersion(version: semver.SemVer | null): FeatureSet
2122
// If this check didn't exist, VS Code connections would fail on
2223
// older versions because of an unknown CLI argument.
2324
proxyLogDirectory: (version?.compare("2.3.3") || 0) > 0 || version?.prerelease[0] === "devel",
25+
26+
// FIXME fill in the version which has https://github.com/coder/coder/pull/16088,
27+
// https://github.com/coder/coder/pull/16078, https://github.com/coder/coder/pull/16080
28+
wildcardSSH: (version?.compare("2.18.0") || 0) > 0 || version?.prerelease[0] === "devel",
2429
}
2530
}

src/remote.ts

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -467,20 +467,25 @@ export class Remote {
467467
// "Host not found".
468468
try {
469469
this.storage.writeToCoderOutputChannel("Updating SSH config...")
470-
await this.updateSSHConfig(workspaceRestClient, parts.label, parts.host, binaryPath, logDir)
470+
await this.updateSSHConfig(workspaceRestClient, parts.label, parts.host, binaryPath, logDir, featureSet)
471471
} catch (error) {
472472
this.storage.writeToCoderOutputChannel(`Failed to configure SSH: ${error}`)
473473
throw error
474474
}
475475

476476
// TODO: This needs to be reworked; it fails to pick up reconnects.
477-
this.findSSHProcessID().then((pid) => {
477+
this.findSSHProcessID().then(async (pid) => {
478478
if (!pid) {
479479
// TODO: Show an error here!
480480
return
481481
}
482482
disposables.push(this.showNetworkUpdates(pid))
483-
this.commands.workspaceLogPath = logDir ? path.join(logDir, `${pid}.log`) : undefined
483+
if (logDir) {
484+
const logFiles = await fs.readdir(logDir)
485+
this.commands.workspaceLogPath = logFiles.find((file) => file.endsWith(`${pid}.log`))
486+
} else {
487+
this.commands.workspaceLogPath = undefined
488+
}
484489
})
485490

486491
// Register the label formatter again because SSH overrides it!
@@ -532,7 +537,14 @@ export class Remote {
532537

533538
// updateSSHConfig updates the SSH configuration with a wildcard that handles
534539
// all Coder entries.
535-
private async updateSSHConfig(restClient: Api, label: string, hostName: string, binaryPath: string, logDir: string) {
540+
private async updateSSHConfig(
541+
restClient: Api,
542+
label: string,
543+
hostName: string,
544+
binaryPath: string,
545+
logDir: string,
546+
featureSet: FeatureSet,
547+
) {
536548
let deploymentSSHConfig = {}
537549
try {
538550
const deploymentConfig = await restClient.getDeploymentSSHConfig()
@@ -610,13 +622,21 @@ export class Remote {
610622
headerArg = ` --header-command ${escapeSubcommand(headerCommand)}`
611623
}
612624

625+
const hostPrefix = label ? `${AuthorityPrefix}.${label}--` : `${AuthorityPrefix}--`
626+
627+
const proxyCommand = featureSet.wildcardSSH
628+
? `${escape(binaryPath)}${headerArg} --global-config ${escape(
629+
path.dirname(this.storage.getSessionTokenPath(label)),
630+
)} ssh --stdio --network-info-dir ${escape(this.storage.getNetworkInfoPath())}${await this.formatLogArg(logDir)} --ssh-host-prefix ${hostPrefix} %h`
631+
: `${escape(binaryPath)}${headerArg} vscodessh --network-info-dir ${escape(
632+
this.storage.getNetworkInfoPath(),
633+
)}${await this.formatLogArg(logDir)} --session-token-file ${escape(this.storage.getSessionTokenPath(label))} --url-file ${escape(
634+
this.storage.getUrlPath(label),
635+
)} %h`
636+
613637
const sshValues: SSHValues = {
614-
Host: label ? `${AuthorityPrefix}.${label}--*` : `${AuthorityPrefix}--*`,
615-
ProxyCommand: `${escape(binaryPath)}${headerArg} vscodessh --network-info-dir ${escape(
616-
this.storage.getNetworkInfoPath(),
617-
)}${await this.formatLogArg(logDir)} --session-token-file ${escape(this.storage.getSessionTokenPath(label))} --url-file ${escape(
618-
this.storage.getUrlPath(label),
619-
)} %h`,
638+
Host: hostPrefix + `*`,
639+
ProxyCommand: proxyCommand,
620640
ConnectTimeout: "0",
621641
StrictHostKeyChecking: "no",
622642
UserKnownHostsFile: "/dev/null",

0 commit comments

Comments
 (0)