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

Commite7cad82

Browse files
committed
handle dev containers
1 parent195151a commite7cad82

File tree

4 files changed

+117
-38
lines changed

4 files changed

+117
-38
lines changed

‎src/commands.ts

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ export class Commands {
491491
}else{
492492
workspaceOwner=args[0]asstring
493493
workspaceName=args[1]asstring
494-
workspaceAgent=args[2]asstring
494+
workspaceAgent=args[2]asstring|undefined
495495
folderPath=args[3]asstring|undefined
496496
openRecent=args[4]asboolean|undefined
497497
}
@@ -522,11 +522,11 @@ export class Commands {
522522

523523
constworkspaceOwner=args[0]asstring
524524
constworkspaceName=args[1]asstring
525-
constworkspaceAgent=undefined//args[2]is reserved, but we do not support multiple agents yet.
525+
constworkspaceAgent=args[2]asstring|undefined
526526
constdevContainerName=args[3]asstring
527527
constdevContainerFolder=args[4]asstring
528528

529-
awaitopenDevContainer(baseUrl,workspaceOwner,workspaceName,workspaceAgent,devContainerName,devContainerFolder)
529+
awaitthis.openDevContainerInner(baseUrl,workspaceOwner,workspaceName,workspaceAgent,devContainerName,devContainerFolder)
530530
}
531531

532532
/**
@@ -652,33 +652,61 @@ export class Commands {
652652
reuseWindow:!newWindow,
653653
})
654654
}
655-
}
656655

657-
asyncfunctionopenDevContainer(
658-
baseUrl:string,
659-
workspaceOwner:string,
660-
workspaceName:string,
661-
workspaceAgent:string|undefined,
662-
devContainerName:string,
663-
devContainerFolder:string,
664-
){
665-
constremoteAuthority=toRemoteAuthority(baseUrl,workspaceOwner,workspaceName,workspaceAgent)
666-
667-
constdevContainer=Buffer.from(JSON.stringify({containerName:devContainerName}),"utf-8").toString("hex")
668-
constdevContainerAuthority=`attached-container+${devContainer}@${remoteAuthority}`
669-
670-
letnewWindow=true
671-
if(!vscode.workspace.workspaceFolders?.length){
672-
newWindow=false
673-
}
656+
privateasyncopenDevContainerInner(
657+
baseUrl:string,
658+
workspaceOwner:string,
659+
workspaceName:string,
660+
workspaceAgent:string|undefined,
661+
devContainerName:string,
662+
devContainerFolder:string,
663+
){
664+
letremoteAuthority=toRemoteAuthority(baseUrl,workspaceOwner,workspaceName,workspaceAgent)
665+
666+
if(workspaceAgent){
667+
letsshConfig
668+
try{
669+
// Fetch (or get defaults) for the SSH config.
670+
sshConfig=awaitfetchSSHConfig(this.restClient,this.vscodeProposed)
671+
}catch(error){
672+
constmessage=getErrorMessage(error,"no response from the server")
673+
this.storage.writeToCoderOutputChannel(`Failed to open workspace:${message}`)
674+
this.vscodeProposed.window.showErrorMessage("Failed to open workspace",{
675+
detail:message,
676+
modal:true,
677+
useCustom:true,
678+
})
679+
return
680+
}
681+
682+
constcoderConnectAddr=awaitmaybeCoderConnectAddr(
683+
workspaceAgent,
684+
workspaceName,
685+
workspaceOwner,
686+
sshConfig.hostname_suffix,
687+
)
688+
if(coderConnectAddr){
689+
remoteAuthority=`ssh-remote+${coderConnectAddr}`
690+
}
691+
}
692+
693+
constdevContainer=Buffer.from(JSON.stringify({containerName:devContainerName}),"utf-8").toString("hex")
694+
constdevContainerAuthority=`attached-container+${devContainer}@${remoteAuthority}`
674695

675-
awaitvscode.commands.executeCommand(
676-
"vscode.openFolder",
677-
vscode.Uri.from({
678-
scheme:"vscode-remote",
679-
authority:devContainerAuthority,
680-
path:devContainerFolder,
681-
}),
682-
newWindow,
683-
)
696+
letnewWindow=true
697+
if(!vscode.workspace.workspaceFolders?.length){
698+
newWindow=false
699+
}
700+
701+
awaitvscode.commands.executeCommand(
702+
"vscode.openFolder",
703+
vscode.Uri.from({
704+
scheme:"vscode-remote",
705+
authority:devContainerAuthority,
706+
path:devContainerFolder,
707+
}),
708+
newWindow,
709+
)
710+
}
684711
}
712+

‎src/remote.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -528,10 +528,32 @@ export class Remote {
528528
sshConfigResponse.hostname_suffix,
529529
)
530530
if(coderConnectAddr){
531-
awaitvscode.commands.executeCommand("vscode.newWindow",{
532-
remoteAuthority:`ssh-remote+${coderConnectAddr}`,
533-
reuseWindow:true,
534-
})
531+
// Find the path of the current workspace, which will have the same authority
532+
constfolderPath=this.vscodeProposed.workspace.workspaceFolders
533+
?.find(folder=>folder.uri.authority===remoteAuthority)
534+
?.uri.path;
535+
letnewRemoteAuthority=`ssh-remote+${coderConnectAddr}`
536+
if(parts.containerNameHex){
537+
newRemoteAuthority=`attached-container+${parts.containerNameHex}@${newRemoteAuthority}`
538+
}
539+
540+
if(folderPath){
541+
awaitvscode.commands.executeCommand(
542+
"vscode.openFolder",
543+
vscode.Uri.from({
544+
scheme:"vscode-remote",
545+
authority:newRemoteAuthority,
546+
path:folderPath,
547+
}),
548+
//`ForceNewWindow`
549+
false,
550+
)
551+
}else{
552+
awaitvscode.commands.executeCommand("vscode.newWindow",{
553+
remoteAuthority:newRemoteAuthority,
554+
reuseWindow:true,
555+
})
556+
}
535557
}
536558

537559
// Returning the URL and token allows the plugin to authenticate its own

‎src/util.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ it("ignore unrelated authorities", async () => {
99
"vscode://ssh-remote+coder-vscode-test--foo--bar",
1010
"vscode://ssh-remote+coder-vscode-foo--bar",
1111
"vscode://ssh-remote+coder--foo--bar",
12+
"vscode://attached-container+namehash@ssh-remote+dev.foo.admin.coder"
1213
]
1314
for(consttestoftests){
1415
expect(parseRemoteAuthority(test)).toBe(null)
@@ -29,34 +30,47 @@ it("should error on invalid authorities", async () => {
2930

3031
it("should parse authority",async()=>{
3132
expect(parseRemoteAuthority("vscode://ssh-remote+coder-vscode--foo--bar")).toStrictEqual({
33+
containerNameHex:undefined,
3234
agent:"",
3335
host:"coder-vscode--foo--bar",
3436
label:"",
3537
username:"foo",
3638
workspace:"bar",
3739
})
3840
expect(parseRemoteAuthority("vscode://ssh-remote+coder-vscode--foo--bar--baz")).toStrictEqual({
41+
containerNameHex:undefined,
3942
agent:"baz",
4043
host:"coder-vscode--foo--bar--baz",
4144
label:"",
4245
username:"foo",
4346
workspace:"bar",
4447
})
4548
expect(parseRemoteAuthority("vscode://ssh-remote+coder-vscode.dev.coder.com--foo--bar")).toStrictEqual({
49+
containerNameHex:undefined,
4650
agent:"",
4751
host:"coder-vscode.dev.coder.com--foo--bar",
4852
label:"dev.coder.com",
4953
username:"foo",
5054
workspace:"bar",
5155
})
5256
expect(parseRemoteAuthority("vscode://ssh-remote+coder-vscode.dev.coder.com--foo--bar--baz")).toStrictEqual({
57+
containerNameHex:undefined,
5358
agent:"baz",
5459
host:"coder-vscode.dev.coder.com--foo--bar--baz",
5560
label:"dev.coder.com",
5661
username:"foo",
5762
workspace:"bar",
5863
})
5964
expect(parseRemoteAuthority("vscode://ssh-remote+coder-vscode.dev.coder.com--foo--bar.baz")).toStrictEqual({
65+
containerNameHex:undefined,
66+
agent:"baz",
67+
host:"coder-vscode.dev.coder.com--foo--bar.baz",
68+
label:"dev.coder.com",
69+
username:"foo",
70+
workspace:"bar",
71+
})
72+
expect(parseRemoteAuthority("vscode://attached-container+namehash@ssh-remote+coder-vscode.dev.coder.com--foo--bar.baz")).toStrictEqual({
73+
containerNameHex:"namehash",
6074
agent:"baz",
6175
host:"coder-vscode.dev.coder.com--foo--bar.baz",
6276
label:"dev.coder.com",

‎src/util.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import{lookup}from"dns"
22
importipRangeCheckfrom"ip-range-check"
3+
import{ssh}from"node-forge"
34
import*asosfrom"os"
45
importurlfrom"url"
56
import{promisify}from"util"
67

78
exportinterfaceAuthorityParts{
9+
containerNameHex:string|undefined
810
agent:string|undefined
911
host:string
1012
label:string
@@ -24,14 +26,26 @@ export const AuthorityPrefix = "coder-vscode"
2426
* Throw an error if the host is invalid.
2527
*/
2628
exportfunctionparseRemoteAuthority(authority:string):AuthorityParts|null{
27-
// The authority looks like: vscode://ssh-remote+<ssh host name>
28-
constauthorityParts=authority.split("+")
29+
// The Dev Container authority looks like: vscode://attached-container+containerNameHex@ssh-remote+<ssh host name>
30+
// The SSH authority looks like: vscode://ssh-remote+<ssh host name>
31+
constauthorityParts=authority.split("@")
32+
letcontainerNameHex=undefined
33+
letsshAuthority
34+
if(authorityParts.length==1){
35+
sshAuthority=authorityParts[0]
36+
}elseif(authorityParts.length==2&&authorityParts[0].includes("attached-container+")){
37+
sshAuthority=authorityParts[1]
38+
containerNameHex=authorityParts[0].split("+")[1]
39+
}else{
40+
returnnull
41+
}
42+
constsshAuthorityParts=sshAuthority.split("+")
2943

3044
// We create SSH host names in a format matching:
3145
// coder-vscode(--|.)<username>--<workspace>(--|.)<agent?>
3246
// The agent can be omitted; the user will be prompted for it instead.
3347
// Anything else is unrelated to Coder and can be ignored.
34-
constparts=authorityParts[1].split("--")
48+
constparts=sshAuthorityParts[1].split("--")
3549
if(parts.length<=1||(parts[0]!==AuthorityPrefix&&!parts[0].startsWith(`${AuthorityPrefix}.`))){
3650
returnnull
3751
}
@@ -56,8 +70,9 @@ export function parseRemoteAuthority(authority: string): AuthorityParts | null {
5670
}
5771

5872
return{
73+
containerNameHex:containerNameHex,
5974
agent:agent,
60-
host:authorityParts[1],
75+
host:sshAuthorityParts[1],
6176
label:parts[0].replace(/^coder-vscode\.?/,""),
6277
username:parts[1],
6378
workspace:workspace,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp