Skip to content

feat(cli/vscodessh): add support for --wait and scripts that block login #10473

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 2, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 41 additions & 23 deletions cli/vscodessh.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"cdr.dev/slog/sloggers/sloghuman"

"github.com/coder/coder/v2/cli/clibase"
"github.com/coder/coder/v2/cli/cliui"
"github.com/coder/coder/v2/cli/cliutil"
"github.com/coder/coder/v2/codersdk"
)
Expand All @@ -38,6 +39,7 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {
logDir string
networkInfoDir string
networkInfoInterval time.Duration
waitEnum string
)
cmd := &clibase.Cmd{
// A SSH config entry is added by the VS Code extension that
Expand Down Expand Up @@ -99,35 +101,45 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {
}
owner := parts[1]
name := parts[2]
if len(parts) > 3 {
name += "." + parts[3]
}

// Set autostart to false because it's assumed the VS Code extension
// will call this command after the workspace is started.
autostart := false

workspace, err := client.WorkspaceByOwnerAndName(ctx, owner, name, codersdk.WorkspaceOptions{})
_, workspaceAgent, err := getWorkspaceAndAgent(ctx, inv, client, autostart, owner, name)
if err != nil {
return xerrors.Errorf("find workspace: %w", err)
return xerrors.Errorf("find workspace and agent: %w", err)
}

var agent codersdk.WorkspaceAgent
var found bool
for _, resource := range workspace.LatestBuild.Resources {
if len(resource.Agents) == 0 {
continue
}
for _, resourceAgent := range resource.Agents {
// If an agent name isn't included we default to
// the first agent!
if len(parts) != 4 {
agent = resourceAgent
found = true
// Select the startup script behavior based on template configuration or flags.
var wait bool
switch waitEnum {
case "yes":
wait = true
case "no":
wait = false
case "auto":
for _, script := range workspaceAgent.Scripts {
if script.StartBlocksLogin {
wait = true
break
}
if resourceAgent.Name != parts[3] {
continue
}
agent = resourceAgent
found = true
break
}
if found {
break
default:
return xerrors.Errorf("unknown wait value %q", waitEnum)
}

err = cliui.Agent(ctx, inv.Stderr, workspaceAgent.ID, cliui.AgentOptions{
Fetch: client.WorkspaceAgent,
FetchLogs: client.WorkspaceAgentLogsAfter,
Wait: wait,
})
if err != nil {
if xerrors.Is(err, context.Canceled) {
return cliui.Canceled
}
}

Expand All @@ -152,7 +164,7 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {
if r.disableDirect {
logger.Info(ctx, "direct connections disabled")
}
agentConn, err := client.DialWorkspaceAgent(ctx, agent.ID, &codersdk.DialWorkspaceAgentOptions{
agentConn, err := client.DialWorkspaceAgent(ctx, workspaceAgent.ID, &codersdk.DialWorkspaceAgentOptions{
Logger: logger,
BlockEndpoints: r.disableDirect,
})
Expand Down Expand Up @@ -249,6 +261,12 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {
Default: "5s",
Value: clibase.DurationOf(&networkInfoInterval),
},
{
Flag: "wait",
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.",
Default: "auto",
Value: clibase.EnumOf(&waitEnum, "yes", "no", "auto"),
},
}
return cmd
}
Expand Down