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

Commitde4e8ca

Browse files
feat(cli): support opening devcontainers in vscode
1 parentcc733ab commitde4e8ca

File tree

2 files changed

+461
-18
lines changed

2 files changed

+461
-18
lines changed

‎cli/open.go

Lines changed: 122 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,46 @@ 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+
foundContainer=true
128+
129+
ifdirectory=="" {
130+
localFolder,ok:=container.Labels["devcontainer.local_folder"]
131+
if!ok {
132+
returnxerrors.New("container missing `devcontainer.local_folder` label")
133+
}
134+
135+
directory,ok=container.Volumes[localFolder]
136+
if!ok {
137+
returnxerrors.New("container missing volume for `devcontainer.local_folder`")
138+
}
139+
}
140+
141+
break
142+
}
143+
}
144+
145+
if!foundContainer {
146+
returnxerrors.New("no container found")
147+
}
148+
}
149+
150+
directory,err=resolveAgentAbsPath(workspaceAgent.ExpandedDirectory,directory,workspaceAgent.OperatingSystem,insideThisWorkspace)
151+
iferr!=nil {
152+
returnxerrors.Errorf("resolve agent path: %w",err)
134153
}
135154

155+
vartokenstring
136156
// We always set the token if we believe we can open without
137157
// printing the URI, otherwise the token must be explicitly
138158
// requested as it will be printed in plain text.
@@ -145,10 +165,31 @@ func (r *RootCmd) openVSCode() *serpent.Command {
145165
iferr!=nil {
146166
returnxerrors.Errorf("create API key: %w",err)
147167
}
148-
qp.Add("token",apiKey.Key)
168+
token=apiKey.Key
149169
}
150170

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

153194
openingPath:=workspaceName
154195
ifdirectory!="" {
@@ -204,6 +245,12 @@ func (r *RootCmd) openVSCode() *serpent.Command {
204245
),
205246
Value:serpent.BoolOf(&generateToken),
206247
},
248+
{
249+
Flag:"container",
250+
FlagShorthand:"c",
251+
Description:"Container name to connect to in the workspace.",
252+
Value:serpent.StringOf(&containerName),
253+
},
207254
{
208255
Flag:"test.open-error",
209256
Description:"Don't run the open command.",
@@ -344,6 +391,63 @@ func (r *RootCmd) openApp() *serpent.Command {
344391
returncmd
345392
}
346393

394+
funcbuildVSCodeWorkspaceLink(
395+
tokenstring,
396+
clientURLstring,
397+
workspace codersdk.Workspace,
398+
workspaceAgent codersdk.WorkspaceAgent,
399+
directorystring,
400+
) (*url.URL, url.Values) {
401+
qp:= url.Values{}
402+
qp.Add("url",clientURL)
403+
qp.Add("owner",workspace.OwnerName)
404+
qp.Add("workspace",workspace.Name)
405+
qp.Add("agent",workspaceAgent.Name)
406+
407+
ifdirectory!="" {
408+
qp.Add("folder",directory)
409+
}
410+
411+
iftoken!="" {
412+
qp.Add("token",token)
413+
}
414+
415+
return&url.URL{
416+
Scheme:"vscode",
417+
Host:"coder.coder-remote",
418+
Path:"/open",
419+
RawQuery:qp.Encode(),
420+
},qp
421+
}
422+
423+
funcbuildVSCodeWorkspaceDevContainerLink(
424+
tokenstring,
425+
clientURLstring,
426+
workspace codersdk.Workspace,
427+
workspaceAgent codersdk.WorkspaceAgent,
428+
containerNamestring,
429+
containerFolderstring,
430+
) (*url.URL, url.Values) {
431+
qp:= url.Values{}
432+
qp.Add("url",clientURL)
433+
qp.Add("owner",workspace.OwnerName)
434+
qp.Add("workspace",workspace.Name)
435+
qp.Add("agent",workspaceAgent.Name)
436+
qp.Add("devContainerName",containerName)
437+
qp.Add("devContainerFolder",containerFolder)
438+
439+
iftoken!="" {
440+
qp.Add("token",token)
441+
}
442+
443+
return&url.URL{
444+
Scheme:"vscode",
445+
Host:"coder.coder-remote",
446+
Path:"/openDevContainer",
447+
RawQuery:qp.Encode(),
448+
},qp
449+
}
450+
347451
// waitForAgentCond uses the watch workspace API to update the agent information
348452
// until the condition is met.
349453
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