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

Commitaa3d71d

Browse files
feat(cli): support opening devcontainers in vscode (#17189)
Closes#16427Adds the option `-c,--container` to `open vscode` that allows openingVSCode into a running devcontainer.
1 parent99c6f23 commitaa3d71d

File tree

2 files changed

+469
-18
lines changed

2 files changed

+469
-18
lines changed

‎cli/open.go

Lines changed: 127 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ func (r *RootCmd) openVSCode() *serpent.Command {
4242
generateTokenbool
4343
testOpenErrorbool
4444
appearanceConfig codersdk.AppearanceConfig
45+
containerNamestring
4546
)
4647

4748
client:=new(codersdk.Client)
@@ -112,27 +113,48 @@ func (r *RootCmd) openVSCode() *serpent.Command {
112113
iflen(inv.Args)>1 {
113114
directory=inv.Args[1]
114115
}
115-
directory,err=resolveAgentAbsPath(workspaceAgent.ExpandedDirectory,directory,workspaceAgent.OperatingSystem,insideThisWorkspace)
116-
iferr!=nil {
117-
returnxerrors.Errorf("resolve agent path: %w",err)
118-
}
119116

120-
u:=&url.URL{
121-
Scheme:"vscode",
122-
Host:"coder.coder-remote",
123-
Path:"/open",
124-
}
117+
ifcontainerName!=""{
118+
containers,err:=client.WorkspaceAgentListContainers(ctx,workspaceAgent.ID,map[string]string{"devcontainer.local_folder":""})
119+
iferr!=nil {
120+
returnxerrors.Errorf("list workspace agent containers: %w",err)
121+
}
125122

126-
qp:= url.Values{}
123+
varfoundContainerbool
127124

128-
qp.Add("url",client.URL.String())
129-
qp.Add("owner",workspace.OwnerName)
130-
qp.Add("workspace",workspace.Name)
131-
qp.Add("agent",workspaceAgent.Name)
132-
ifdirectory!="" {
133-
qp.Add("folder",directory)
125+
for_,container:=rangecontainers.Containers {
126+
ifcontainer.FriendlyName!=containerName {
127+
continue
128+
}
129+
130+
foundContainer=true
131+
132+
ifdirectory=="" {
133+
localFolder,ok:=container.Labels["devcontainer.local_folder"]
134+
if!ok {
135+
returnxerrors.New("container missing `devcontainer.local_folder` label")
136+
}
137+
138+
directory,ok=container.Volumes[localFolder]
139+
if!ok {
140+
returnxerrors.New("container missing volume for `devcontainer.local_folder`")
141+
}
142+
}
143+
144+
break
145+
}
146+
147+
if!foundContainer {
148+
returnxerrors.New("no container found")
149+
}
150+
}
151+
152+
directory,err=resolveAgentAbsPath(workspaceAgent.ExpandedDirectory,directory,workspaceAgent.OperatingSystem,insideThisWorkspace)
153+
iferr!=nil {
154+
returnxerrors.Errorf("resolve agent path: %w",err)
134155
}
135156

157+
vartokenstring
136158
// We always set the token if we believe we can open without
137159
// printing the URI, otherwise the token must be explicitly
138160
// requested as it will be printed in plain text.
@@ -145,10 +167,31 @@ func (r *RootCmd) openVSCode() *serpent.Command {
145167
iferr!=nil {
146168
returnxerrors.Errorf("create API key: %w",err)
147169
}
148-
qp.Add("token",apiKey.Key)
170+
token=apiKey.Key
149171
}
150172

151-
u.RawQuery=qp.Encode()
173+
var (
174+
u*url.URL
175+
qp url.Values
176+
)
177+
ifcontainerName!="" {
178+
u,qp=buildVSCodeWorkspaceDevContainerLink(
179+
token,
180+
client.URL.String(),
181+
workspace,
182+
workspaceAgent,
183+
containerName,
184+
directory,
185+
)
186+
}else {
187+
u,qp=buildVSCodeWorkspaceLink(
188+
token,
189+
client.URL.String(),
190+
workspace,
191+
workspaceAgent,
192+
directory,
193+
)
194+
}
152195

153196
openingPath:=workspaceName
154197
ifdirectory!="" {
@@ -204,6 +247,13 @@ func (r *RootCmd) openVSCode() *serpent.Command {
204247
),
205248
Value:serpent.BoolOf(&generateToken),
206249
},
250+
{
251+
Flag:"container",
252+
FlagShorthand:"c",
253+
Description:"Container name to connect to in the workspace.",
254+
Value:serpent.StringOf(&containerName),
255+
Hidden:true,// Hidden until this features is at least in beta.
256+
},
207257
{
208258
Flag:"test.open-error",
209259
Description:"Don't run the open command.",
@@ -344,6 +394,65 @@ func (r *RootCmd) openApp() *serpent.Command {
344394
returncmd
345395
}
346396

397+
funcbuildVSCodeWorkspaceLink(
398+
tokenstring,
399+
clientURLstring,
400+
workspace codersdk.Workspace,
401+
workspaceAgent codersdk.WorkspaceAgent,
402+
directorystring,
403+
) (*url.URL, url.Values) {
404+
qp:= url.Values{}
405+
qp.Add("url",clientURL)
406+
qp.Add("owner",workspace.OwnerName)
407+
qp.Add("workspace",workspace.Name)
408+
qp.Add("agent",workspaceAgent.Name)
409+
410+
ifdirectory!="" {
411+
qp.Add("folder",directory)
412+
}
413+
414+
iftoken!="" {
415+
qp.Add("token",token)
416+
}
417+
418+
return&url.URL{
419+
Scheme:"vscode",
420+
Host:"coder.coder-remote",
421+
Path:"/open",
422+
RawQuery:qp.Encode(),
423+
},qp
424+
}
425+
426+
funcbuildVSCodeWorkspaceDevContainerLink(
427+
tokenstring,
428+
clientURLstring,
429+
workspace codersdk.Workspace,
430+
workspaceAgent codersdk.WorkspaceAgent,
431+
containerNamestring,
432+
containerFolderstring,
433+
) (*url.URL, url.Values) {
434+
containerFolder=filepath.ToSlash(containerFolder)
435+
436+
qp:= url.Values{}
437+
qp.Add("url",clientURL)
438+
qp.Add("owner",workspace.OwnerName)
439+
qp.Add("workspace",workspace.Name)
440+
qp.Add("agent",workspaceAgent.Name)
441+
qp.Add("devContainerName",containerName)
442+
qp.Add("devContainerFolder",containerFolder)
443+
444+
iftoken!="" {
445+
qp.Add("token",token)
446+
}
447+
448+
return&url.URL{
449+
Scheme:"vscode",
450+
Host:"coder.coder-remote",
451+
Path:"/openDevContainer",
452+
RawQuery:qp.Encode(),
453+
},qp
454+
}
455+
347456
// waitForAgentCond uses the watch workspace API to update the agent information
348457
// until the condition is met.
349458
funcwaitForAgentCond(ctx context.Context,client*codersdk.Client,workspace codersdk.Workspace,workspaceAgent codersdk.WorkspaceAgent,condfunc(codersdk.WorkspaceAgent)bool) (codersdk.Workspace, codersdk.WorkspaceAgent,error) {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp