Skip to content

Commit cae381f

Browse files
committed
Works on my Windows desktop?
1 parent 56a45cc commit cae381f

File tree

2 files changed

+25
-33
lines changed

2 files changed

+25
-33
lines changed

agent/agent.go

+22-27
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
"os/user"
1919
"path/filepath"
2020
"reflect"
21-
"runtime"
21+
"regexp"
2222
"sort"
2323
"strconv"
2424
"strings"
@@ -205,9 +205,17 @@ func (a *agent) runLoop(ctx context.Context) {
205205
}
206206
}
207207

208+
var (
209+
isCmdExeRe = regexp.MustCompile(`^(cmd|cmd\.exe)$`)
210+
)
211+
208212
func createMetadataCommand(ctx context.Context, script string) (*exec.Cmd, error) {
209213
// This is largely copied from agentssh, but for some reason the command
210-
// generated there always returns exit status 1 in Windows.
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.
211219
currentUser, err := user.Current()
212220
if err != nil {
213221
return nil, xerrors.Errorf("get current user: %w", err)
@@ -218,31 +226,28 @@ func createMetadataCommand(ctx context.Context, script string) (*exec.Cmd, error
218226
if err != nil {
219227
return nil, xerrors.Errorf("get user shell: %w", err)
220228
}
229+
shellBase := filepath.Base(shell)
221230

222-
var caller string
231+
var args []string
223232
switch {
224-
case filepath.Base(shell) == "pwsh.exe":
225-
caller = "-Command"
226-
case runtime.GOOS == "windows":
227-
caller = "/c"
233+
case isCmdExeRe.MatchString(shellBase):
234+
args = append(args, "/c")
228235
default:
229-
caller = "-c"
236+
// -c works for powershell and sh variants.
237+
args = append(args, "-c")
230238
}
231-
// args := []string{caller, "Get-Process"}
232-
args := []string{"-NoProfile", "-NonInteractive"}
233-
_ = caller
234-
return exec.CommandContext(ctx, "powershell", args...), nil
239+
args = append(args, script)
240+
return exec.CommandContext(ctx, shell, args...), nil
235241
}
236242

237243
func (*agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentMetadataDescription) *codersdk.WorkspaceAgentMetadataResult {
238244
var out bytes.Buffer
239245
result := &codersdk.WorkspaceAgentMetadataResult{
240246
// CollectedAt is set here for testing purposes and overrode by
241-
// the server to the time the server received the result to protect
242-
// against clock skew.
247+
// coderd to the time of server receipt to solve clock skew.
243248
//
244249
// In the future, the server may accept the timestamp from the agent
245-
// if it is certain the clocks are in sync.
250+
// if it can guarantee the clocks are synchronized.
246251
CollectedAt: time.Now(),
247252
}
248253
cmd, err := createMetadataCommand(ctx, md.Script)
@@ -251,19 +256,11 @@ func (*agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentMet
251256
return result
252257
}
253258

254-
// execPath, err := exec.LookPath("cmd.exe")
255-
// if err != nil {
256-
// result.Error = fmt.Sprintf("look path: %+v", err)
257-
// return result
258-
// }
259-
260-
// cmd = exec.CommandContext(ctx, execPath, "/c", "echo hello")
261-
262259
cmd.Stdout = &out
263260
cmd.Stderr = &out
264261
cmd.Stdin = io.LimitReader(nil, 0)
265262

266-
// We split up Start and Wait so that we can return a more useful error.
263+
// We split up Start and Wait instead of calling Run so that we can return a more precise error.
267264
err = cmd.Start()
268265
if err != nil {
269266
result.Error = fmt.Sprintf("start cmd: %+v", err)
@@ -281,10 +278,8 @@ func (*agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentMet
281278
out.Truncate(bufLimit)
282279
}
283280

284-
fmt.Printf("ran %+v %+q: %v\n", cmd.Path, cmd.Args, err)
285-
286281
if err != nil {
287-
result.Error = fmt.Sprintf("run cmd: %+v", err)
282+
result.Error = fmt.Sprintf("run cmd (shell %v): %+v", cmd.Path, err)
288283
}
289284
result.Value = out.String()
290285
return result

agent/agent_test.go

+3-6
Original file line numberDiff line numberDiff line change
@@ -976,10 +976,7 @@ func TestAgent_StartupScript(t *testing.T) {
976976
func TestAgent_Metadata(t *testing.T) {
977977
t.Parallel()
978978

979-
echoHello := "echo hello"
980-
if runtime.GOOS == "windows" {
981-
echoHello = "echo 'hello'"
982-
}
979+
echoHello := "echo 'hello'"
983980

984981
t.Run("Once", func(t *testing.T) {
985982
t.Parallel()
@@ -1031,8 +1028,8 @@ func TestAgent_Metadata(t *testing.T) {
10311028
}, testutil.WaitShort, testutil.IntervalMedium)
10321029

10331030
collectedAt1 := gotMd["greeting"].CollectedAt
1034-
if !assert.Equal(t, "hello\n", gotMd["greeting"].Value) {
1035-
t.Logf("got: %+v", gotMd)
1031+
if !assert.Equal(t, "hello", strings.TrimSpace(gotMd["greeting"].Value)) {
1032+
t.Errorf("got: %+v", gotMd)
10361033
}
10371034

10381035
if !assert.Eventually(t, func() bool {

0 commit comments

Comments
 (0)