Skip to content

Commit 39aec7a

Browse files
committed
feat(cli/vscodessh): add support for --wait and scripts that block login
1 parent 5284d97 commit 39aec7a

File tree

1 file changed

+37
-23
lines changed

1 file changed

+37
-23
lines changed

cli/vscodessh.go

+37-23
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"cdr.dev/slog/sloggers/sloghuman"
2222

2323
"github.com/coder/coder/v2/cli/clibase"
24+
"github.com/coder/coder/v2/cli/cliui"
2425
"github.com/coder/coder/v2/codersdk"
2526
)
2627

@@ -36,6 +37,7 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {
3637
urlFile string
3738
networkInfoDir string
3839
networkInfoInterval time.Duration
40+
waitEnum string
3941
)
4042
cmd := &clibase.Cmd{
4143
// A SSH config entry is added by the VS Code extension that
@@ -97,35 +99,41 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {
9799
}
98100
owner := parts[1]
99101
name := parts[2]
102+
if len(parts) > 3 {
103+
name += "." + parts[3]
104+
}
100105

101-
workspace, err := client.WorkspaceByOwnerAndName(ctx, owner, name, codersdk.WorkspaceOptions{})
106+
_, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, owner, name)
102107
if err != nil {
103-
return xerrors.Errorf("find workspace: %w", err)
108+
return xerrors.Errorf("find workspace and agent: %w", err)
104109
}
105110

106-
var agent codersdk.WorkspaceAgent
107-
var found bool
108-
for _, resource := range workspace.LatestBuild.Resources {
109-
if len(resource.Agents) == 0 {
110-
continue
111-
}
112-
for _, resourceAgent := range resource.Agents {
113-
// If an agent name isn't included we default to
114-
// the first agent!
115-
if len(parts) != 4 {
116-
agent = resourceAgent
117-
found = true
111+
// Select the startup script behavior based on template configuration or flags.
112+
var wait bool
113+
switch waitEnum {
114+
case "yes":
115+
wait = true
116+
case "no":
117+
wait = false
118+
case "auto":
119+
for _, script := range workspaceAgent.Scripts {
120+
if script.StartBlocksLogin {
121+
wait = true
118122
break
119123
}
120-
if resourceAgent.Name != parts[3] {
121-
continue
122-
}
123-
agent = resourceAgent
124-
found = true
125-
break
126124
}
127-
if found {
128-
break
125+
default:
126+
return xerrors.Errorf("unknown wait value %q", waitEnum)
127+
}
128+
129+
err = cliui.Agent(ctx, inv.Stderr, workspaceAgent.ID, cliui.AgentOptions{
130+
Fetch: client.WorkspaceAgent,
131+
FetchLogs: client.WorkspaceAgentLogsAfter,
132+
Wait: wait,
133+
})
134+
if err != nil {
135+
if xerrors.Is(err, context.Canceled) {
136+
return cliui.Canceled
129137
}
130138
}
131139

@@ -137,7 +145,7 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {
137145
if r.disableDirect {
138146
_, _ = fmt.Fprintln(inv.Stderr, "Direct connections disabled.")
139147
}
140-
agentConn, err := client.DialWorkspaceAgent(ctx, agent.ID, &codersdk.DialWorkspaceAgentOptions{
148+
agentConn, err := client.DialWorkspaceAgent(ctx, workspaceAgent.ID, &codersdk.DialWorkspaceAgentOptions{
141149
Logger: logger,
142150
BlockEndpoints: r.disableDirect,
143151
})
@@ -229,6 +237,12 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {
229237
Default: "5s",
230238
Value: clibase.DurationOf(&networkInfoInterval),
231239
},
240+
{
241+
Flag: "wait",
242+
Description: "Specifies whether or not to wait for the startup script to finish executing. Auto means that the agent startup script behavior configured in the workspace template is used.",
243+
Default: "auto",
244+
Value: clibase.EnumOf(&waitEnum, "yes", "no", "auto"),
245+
},
232246
}
233247
return cmd
234248
}

0 commit comments

Comments
 (0)