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

Commit1922834

Browse files
feat: add ability to attach to devcontainers (#463)
1 parenta001bea commit1922834

File tree

3 files changed

+120
-5
lines changed

3 files changed

+120
-5
lines changed

‎src/commands.ts

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { makeCoderSdk, needToken } from "./api"
66
import{extractAgents}from"./api-helper"
77
import{CertificateError}from"./error"
88
import{Storage}from"./storage"
9-
import{AuthorityPrefix,toSafeHost}from"./util"
9+
import{toRemoteAuthority,toSafeHost}from"./util"
1010
import{OpenableTreeItem}from"./workspacesProvider"
1111

1212
exportclassCommands{
@@ -499,6 +499,26 @@ export class Commands {
499499
awaitopenWorkspace(baseUrl,workspaceOwner,workspaceName,workspaceAgent,folderPath,openRecent)
500500
}
501501

502+
/**
503+
* Open a devcontainer from a workspace belonging to the currently logged-in deployment.
504+
*
505+
* Throw if not logged into a deployment.
506+
*/
507+
publicasyncopenDevContainer(...args:string[]):Promise<void>{
508+
constbaseUrl=this.restClient.getAxiosInstance().defaults.baseURL
509+
if(!baseUrl){
510+
thrownewError("You are not logged in")
511+
}
512+
513+
constworkspaceOwner=args[0]asstring
514+
constworkspaceName=args[1]asstring
515+
constworkspaceAgent=undefined// args[2] is reserved, but we do not support multiple agents yet.
516+
constdevContainerName=args[3]asstring
517+
constdevContainerFolder=args[4]asstring
518+
519+
awaitopenDevContainer(baseUrl,workspaceOwner,workspaceName,workspaceAgent,devContainerName,devContainerFolder)
520+
}
521+
502522
/**
503523
* Update the current workspace. If there is no active workspace connection,
504524
* this is a no-op.
@@ -536,10 +556,7 @@ async function openWorkspace(
536556
){
537557
// A workspace can have multiple agents, but that's handled
538558
// when opening a workspace unless explicitly specified.
539-
letremoteAuthority=`ssh-remote+${AuthorityPrefix}.${toSafeHost(baseUrl)}--${workspaceOwner}--${workspaceName}`
540-
if(workspaceAgent){
541-
remoteAuthority+=`.${workspaceAgent}`
542-
}
559+
constremoteAuthority=toRemoteAuthority(baseUrl,workspaceOwner,workspaceName,workspaceAgent)
543560

544561
letnewWindow=true
545562
// Open in the existing window if no workspaces are open.
@@ -598,3 +615,32 @@ async function openWorkspace(
598615
reuseWindow:!newWindow,
599616
})
600617
}
618+
619+
asyncfunctionopenDevContainer(
620+
baseUrl:string,
621+
workspaceOwner:string,
622+
workspaceName:string,
623+
workspaceAgent:string|undefined,
624+
devContainerName:string,
625+
devContainerFolder:string,
626+
){
627+
constremoteAuthority=toRemoteAuthority(baseUrl,workspaceOwner,workspaceName,workspaceAgent)
628+
629+
constdevContainer=Buffer.from(JSON.stringify({containerName:devContainerName}),"utf-8").toString("hex")
630+
constdevContainerAuthority=`attached-container+${devContainer}@${remoteAuthority}`
631+
632+
letnewWindow=true
633+
if(!vscode.workspace.workspaceFolders?.length){
634+
newWindow=false
635+
}
636+
637+
awaitvscode.commands.executeCommand(
638+
"vscode.openFolder",
639+
vscode.Uri.from({
640+
scheme:"vscode-remote",
641+
authority:devContainerAuthority,
642+
path:devContainerFolder,
643+
}),
644+
newWindow,
645+
)
646+
}

‎src/extension.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,61 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
111111
awaitstorage.configureCli(toSafeHost(url),url,token)
112112

113113
vscode.commands.executeCommand("coder.open",owner,workspace,agent,folder,openRecent)
114+
}elseif(uri.path==="/openDevContainer"){
115+
constworkspaceOwner=params.get("owner")
116+
constworkspaceName=params.get("workspace")
117+
constworkspaceAgent=params.get("agent")
118+
constdevContainerName=params.get("devContainerName")
119+
constdevContainerFolder=params.get("devContainerFolder")
120+
121+
if(!workspaceOwner){
122+
thrownewError("workspace owner must be specified as a query parameter")
123+
}
124+
125+
if(!workspaceName){
126+
thrownewError("workspace name must be specified as a query parameter")
127+
}
128+
129+
if(!devContainerName){
130+
thrownewError("dev container name must be specified as a query parameter")
131+
}
132+
133+
if(!devContainerFolder){
134+
thrownewError("dev container folder must be specified as a query parameter")
135+
}
136+
137+
// We are not guaranteed that the URL we currently have is for the URL
138+
// this workspace belongs to, or that we even have a URL at all (the
139+
// queries will default to localhost) so ask for it if missing.
140+
// Pre-populate in case we do have the right URL so the user can just
141+
// hit enter and move on.
142+
consturl=awaitcommands.maybeAskUrl(params.get("url"),storage.getUrl())
143+
if(url){
144+
restClient.setHost(url)
145+
awaitstorage.setUrl(url)
146+
}else{
147+
thrownewError("url must be provided or specified as a query parameter")
148+
}
149+
150+
// If the token is missing we will get a 401 later and the user will be
151+
// prompted to sign in again, so we do not need to ensure it is set now.
152+
// For non-token auth, we write a blank token since the `vscodessh`
153+
// command currently always requires a token file. However, if there is
154+
// a query parameter for non-token auth go ahead and use it anyway; all
155+
// that really matters is the file is created.
156+
consttoken=needToken() ?params.get("token") :(params.get("token")??"")
157+
158+
// Store on disk to be used by the cli.
159+
awaitstorage.configureCli(toSafeHost(url),url,token)
160+
161+
vscode.commands.executeCommand(
162+
"coder.openDevContainer",
163+
workspaceOwner,
164+
workspaceName,
165+
workspaceAgent,
166+
devContainerName,
167+
devContainerFolder,
168+
)
114169
}else{
115170
thrownewError(`Unknown path${uri.path}`)
116171
}
@@ -123,6 +178,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
123178
vscode.commands.registerCommand("coder.login",commands.login.bind(commands))
124179
vscode.commands.registerCommand("coder.logout",commands.logout.bind(commands))
125180
vscode.commands.registerCommand("coder.open",commands.open.bind(commands))
181+
vscode.commands.registerCommand("coder.openDevContainer",commands.openDevContainer.bind(commands))
126182
vscode.commands.registerCommand("coder.openFromSidebar",commands.openFromSidebar.bind(commands))
127183
vscode.commands.registerCommand("coder.workspace.update",commands.updateWorkspace.bind(commands))
128184
vscode.commands.registerCommand("coder.createWorkspace",commands.createWorkspace.bind(commands))

‎src/util.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,19 @@ export function parseRemoteAuthority(authority: string): AuthorityParts | null {
6161
}
6262
}
6363

64+
exportfunctiontoRemoteAuthority(
65+
baseUrl:string,
66+
workspaceOwner:string,
67+
workspaceName:string,
68+
workspaceAgent:string|undefined,
69+
):string{
70+
letremoteAuthority=`ssh-remote+${AuthorityPrefix}.${toSafeHost(baseUrl)}--${workspaceOwner}--${workspaceName}`
71+
if(workspaceAgent){
72+
remoteAuthority+=`.${workspaceAgent}`
73+
}
74+
returnremoteAuthority
75+
}
76+
6477
/**
6578
* Given a URL, return the host in a format that is safe to write.
6679
*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp