@@ -14,7 +14,6 @@ import (
14
14
"net/http"
15
15
"net/netip"
16
16
"os"
17
- "os/exec"
18
17
"os/user"
19
18
"path/filepath"
20
19
"reflect"
@@ -37,7 +36,6 @@ import (
37
36
38
37
"cdr.dev/slog"
39
38
"github.com/coder/coder/agent/agentssh"
40
- "github.com/coder/coder/agent/usershell"
41
39
"github.com/coder/coder/buildinfo"
42
40
"github.com/coder/coder/coderd/database"
43
41
"github.com/coder/coder/coderd/gitauth"
@@ -205,42 +203,9 @@ func (a *agent) runLoop(ctx context.Context) {
205
203
}
206
204
}
207
205
208
- var (
209
- isCmdExeRe = regexp .MustCompile (`^(cmd|cmd\.exe)$` )
210
- )
206
+ var isCmdExeRe = regexp .MustCompile (`^(cmd|cmd\.exe)$` )
211
207
212
- func createMetadataCommand (ctx context.Context , script string ) (* exec.Cmd , error ) {
213
- // This is largely copied from agentssh, but for some reason the command
214
- // generated there always returns exit status 1 in Windows powershell.
215
- //
216
- // This function puts special PowerShell branching in place that fixes the issue,
217
- // but I'm hesitant on porting it to agentssh before understanding exactly what's
218
- // happening.
219
- currentUser , err := user .Current ()
220
- if err != nil {
221
- return nil , xerrors .Errorf ("get current user: %w" , err )
222
- }
223
- username := currentUser .Username
224
-
225
- shell , err := usershell .Get (username )
226
- if err != nil {
227
- return nil , xerrors .Errorf ("get user shell: %w" , err )
228
- }
229
- shellBase := filepath .Base (shell )
230
-
231
- var args []string
232
- switch {
233
- case isCmdExeRe .MatchString (shellBase ):
234
- args = append (args , "/c" )
235
- default :
236
- // -c works for powershell and sh variants.
237
- args = append (args , "-c" )
238
- }
239
- args = append (args , script )
240
- return exec .CommandContext (ctx , shell , args ... ), nil
241
- }
242
-
243
- func (* agent ) collectMetadata (ctx context.Context , md codersdk.WorkspaceAgentMetadataDescription ) * codersdk.WorkspaceAgentMetadataResult {
208
+ func (a * agent ) collectMetadata (ctx context.Context , md codersdk.WorkspaceAgentMetadataDescription ) * codersdk.WorkspaceAgentMetadataResult {
244
209
var out bytes.Buffer
245
210
result := & codersdk.WorkspaceAgentMetadataResult {
246
211
// CollectedAt is set here for testing purposes and overrode by
@@ -250,7 +215,7 @@ func (*agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentMet
250
215
// if it can guarantee the clocks are synchronized.
251
216
CollectedAt : time .Now (),
252
217
}
253
- cmd , err := createMetadataCommand (ctx , md .Script )
218
+ cmd , err := a . sshServer . CreateCommand (ctx , md .Script , nil )
254
219
if err != nil {
255
220
result .Error = fmt .Sprintf ("create cmd: %+v" , err )
256
221
return result
@@ -278,8 +243,12 @@ func (*agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentMet
278
243
out .Truncate (bufLimit )
279
244
}
280
245
246
+ // Important: if the command times out, we may see a misleading error like
247
+ // "exit status 1", so it's important to include the context error.
248
+ err = errors .Join (err , ctx .Err ())
249
+
281
250
if err != nil {
282
- result .Error = fmt .Sprintf ("run cmd (shell %v) : %+v" , cmd . Path , err )
251
+ result .Error = fmt .Sprintf ("run cmd: %+v" , err )
283
252
}
284
253
result .Value = out .String ()
285
254
return result
0 commit comments