@@ -21,6 +21,7 @@ import (
21
21
"cdr.dev/slog/sloggers/sloghuman"
22
22
23
23
"github.com/coder/coder/v2/cli/clibase"
24
+ "github.com/coder/coder/v2/cli/cliui"
24
25
"github.com/coder/coder/v2/cli/cliutil"
25
26
"github.com/coder/coder/v2/codersdk"
26
27
)
@@ -38,6 +39,7 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {
38
39
logDir string
39
40
networkInfoDir string
40
41
networkInfoInterval time.Duration
42
+ waitEnum string
41
43
)
42
44
cmd := & clibase.Cmd {
43
45
// A SSH config entry is added by the VS Code extension that
@@ -99,35 +101,45 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {
99
101
}
100
102
owner := parts [1 ]
101
103
name := parts [2 ]
104
+ if len (parts ) > 3 {
105
+ name += "." + parts [3 ]
106
+ }
107
+
108
+ // Set autostart to false because it's assumed the VS Code extension
109
+ // will call this command after the workspace is started.
110
+ autostart := false
102
111
103
- workspace , err := client . WorkspaceByOwnerAndName (ctx , owner , name , codersdk. WorkspaceOptions {} )
112
+ _ , workspaceAgent , err := getWorkspaceAndAgent (ctx , inv , client , autostart , owner , name )
104
113
if err != nil {
105
- return xerrors .Errorf ("find workspace: %w" , err )
114
+ return xerrors .Errorf ("find workspace and agent : %w" , err )
106
115
}
107
116
108
- var agent codersdk.WorkspaceAgent
109
- var found bool
110
- for _ , resource := range workspace .LatestBuild .Resources {
111
- if len (resource .Agents ) == 0 {
112
- continue
113
- }
114
- for _ , resourceAgent := range resource .Agents {
115
- // If an agent name isn't included we default to
116
- // the first agent!
117
- if len (parts ) != 4 {
118
- agent = resourceAgent
119
- found = true
117
+ // Select the startup script behavior based on template configuration or flags.
118
+ var wait bool
119
+ switch waitEnum {
120
+ case "yes" :
121
+ wait = true
122
+ case "no" :
123
+ wait = false
124
+ case "auto" :
125
+ for _ , script := range workspaceAgent .Scripts {
126
+ if script .StartBlocksLogin {
127
+ wait = true
120
128
break
121
129
}
122
- if resourceAgent .Name != parts [3 ] {
123
- continue
124
- }
125
- agent = resourceAgent
126
- found = true
127
- break
128
130
}
129
- if found {
130
- break
131
+ default :
132
+ return xerrors .Errorf ("unknown wait value %q" , waitEnum )
133
+ }
134
+
135
+ err = cliui .Agent (ctx , inv .Stderr , workspaceAgent .ID , cliui.AgentOptions {
136
+ Fetch : client .WorkspaceAgent ,
137
+ FetchLogs : client .WorkspaceAgentLogsAfter ,
138
+ Wait : wait ,
139
+ })
140
+ if err != nil {
141
+ if xerrors .Is (err , context .Canceled ) {
142
+ return cliui .Canceled
131
143
}
132
144
}
133
145
@@ -152,7 +164,7 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {
152
164
if r .disableDirect {
153
165
logger .Info (ctx , "direct connections disabled" )
154
166
}
155
- agentConn , err := client .DialWorkspaceAgent (ctx , agent .ID , & codersdk.DialWorkspaceAgentOptions {
167
+ agentConn , err := client .DialWorkspaceAgent (ctx , workspaceAgent .ID , & codersdk.DialWorkspaceAgentOptions {
156
168
Logger : logger ,
157
169
BlockEndpoints : r .disableDirect ,
158
170
})
@@ -249,6 +261,12 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {
249
261
Default : "5s" ,
250
262
Value : clibase .DurationOf (& networkInfoInterval ),
251
263
},
264
+ {
265
+ Flag : "wait" ,
266
+ 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." ,
267
+ Default : "auto" ,
268
+ Value : clibase .EnumOf (& waitEnum , "yes" , "no" , "auto" ),
269
+ },
252
270
}
253
271
return cmd
254
272
}
0 commit comments