Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit25ba630

Browse files
author
Aaron Lehmann
committed
Use coder ssh in place of coder vscodessh
Build on top of recent coder PRs to make coder ssh provide equivalentfunctionality to vscodessh, avoiding the need for a VSCode-specific sshsubcommand.
1 parent2766d2f commit25ba630

File tree

6 files changed

+63
-20
lines changed

6 files changed

+63
-20
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-prefixcoder-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-
networkinformation 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/commands.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ async function openWorkspace(
538538
// when opening a workspace unless explicitly specified.
539539
letremoteAuthority=`ssh-remote+${AuthorityPrefix}.${toSafeHost(baseUrl)}--${workspaceOwner}--${workspaceName}`
540540
if(workspaceAgent){
541-
remoteAuthority+=`--${workspaceAgent}`
541+
remoteAuthority+=`.${workspaceAgent}`
542542
}
543543

544544
letnewWindow=true

‎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
exporttypeFeatureSet={
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.19.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-
awaitthis.updateSSHConfig(workspaceRestClient,parts.label,parts.host,binaryPath,logDir)
470+
awaitthis.updateSSHConfig(workspaceRestClient,parts.label,parts.host,binaryPath,logDir,featureSet)
471471
}catch(error){
472472
this.storage.writeToCoderOutputChannel(`Failed to configure SSH:${error}`)
473473
throwerror
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+
constlogFiles=awaitfs.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-
privateasyncupdateSSHConfig(restClient:Api,label:string,hostName:string,binaryPath:string,logDir:string){
540+
privateasyncupdateSSHConfig(
541+
restClient:Api,
542+
label:string,
543+
hostName:string,
544+
binaryPath:string,
545+
logDir:string,
546+
featureSet:FeatureSet,
547+
){
536548
letdeploymentSSHConfig={}
537549
try{
538550
constdeploymentConfig=awaitrestClient.getDeploymentSSHConfig()
@@ -610,13 +622,21 @@ export class Remote {
610622
headerArg=` --header-command${escapeSubcommand(headerCommand)}`
611623
}
612624

625+
consthostPrefix=label ?`${AuthorityPrefix}.${label}--` :`${AuthorityPrefix}--`
626+
627+
constproxyCommand=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())}${awaitthis.formatLogArg(logDir)} --ssh-host-prefix${hostPrefix} %h`
631+
:`${escape(binaryPath)}${headerArg} vscodessh --network-info-dir${escape(
632+
this.storage.getNetworkInfoPath(),
633+
)}${awaitthis.formatLogArg(logDir)} --session-token-file${escape(this.storage.getSessionTokenPath(label))} --url-file${escape(
634+
this.storage.getUrlPath(label),
635+
)} %h`
636+
613637
constsshValues:SSHValues={
614-
Host:label ?`${AuthorityPrefix}.${label}--*` :`${AuthorityPrefix}--*`,
615-
ProxyCommand:`${escape(binaryPath)}${headerArg} vscodessh --network-info-dir${escape(
616-
this.storage.getNetworkInfoPath(),
617-
)}${awaitthis.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",

‎src/util.test.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ it("should parse authority", async () => {
5656
username:"foo",
5757
workspace:"bar",
5858
})
59+
expect(parseRemoteAuthority("vscode://ssh-remote+coder-vscode.dev.coder.com--foo--bar.baz")).toStrictEqual({
60+
agent:"baz",
61+
host:"coder-vscode.dev.coder.com--foo--bar.baz",
62+
label:"dev.coder.com",
63+
username:"foo",
64+
workspace:"bar",
65+
})
5966
})
6067

6168
it("escapes url host",async()=>{

‎src/util.ts‎

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@ export function parseRemoteAuthority(authority: string): AuthorityParts | null {
2424
// The authority looks like: vscode://ssh-remote+<ssh host name>
2525
constauthorityParts=authority.split("+")
2626

27-
// We create SSH host names in one of two formats:
28-
// coder-vscode--<username>--<workspace>--<agent?> (old style)
29-
// coder-vscode.<label>--<username>--<workspace>--<agent>
27+
// We create SSH host names in a format matching:
28+
// coder-vscode(--|.)<username>--<workspace>(--|.)<agent?>
3029
// The agent can be omitted; the user will be prompted for it instead.
3130
// Anything else is unrelated to Coder and can be ignored.
3231
constparts=authorityParts[1].split("--")
@@ -38,15 +37,27 @@ export function parseRemoteAuthority(authority: string): AuthorityParts | null {
3837
// Validate the SSH host name. Including the prefix, we expect at least
3938
// three parts, or four if including the agent.
4039
if((parts.length!==3&&parts.length!==4)||parts.some((p)=>!p)){
41-
thrownewError(`Invalid Coder SSH authority. Must be: <username>--<workspace>--<agent?>`)
40+
thrownewError(`Invalid Coder SSH authority. Must be: <username>--<workspace>(--|.)<agent?>`)
41+
}
42+
43+
letworkspace=parts[2]
44+
letagent=""
45+
if(parts.length===4){
46+
agent=parts[3]
47+
}elseif(parts.length===3){
48+
constworkspaceParts=parts[2].split(".")
49+
if(workspaceParts.length===2){
50+
workspace=workspaceParts[0]
51+
agent=workspaceParts[1]
52+
}
4253
}
4354

4455
return{
45-
agent:parts[3]??"",
56+
agent:agent,
4657
host:authorityParts[1],
4758
label:parts[0].replace(/^coder-vscode\.?/,""),
4859
username:parts[1],
49-
workspace:parts[2],
60+
workspace:workspace,
5061
}
5162
}
5263

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp