Skip to content

Commit fb0ca0c

Browse files
committed
fix windows?
1 parent ba6f151 commit fb0ca0c

File tree

2 files changed

+62
-17
lines changed

2 files changed

+62
-17
lines changed

agent/agent.go

+52-6
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ import (
1414
"net/http"
1515
"net/netip"
1616
"os"
17+
"os/exec"
1718
"os/user"
1819
"path/filepath"
1920
"reflect"
21+
"runtime"
2022
"sort"
2123
"strconv"
2224
"strings"
@@ -35,6 +37,7 @@ import (
3537

3638
"cdr.dev/slog"
3739
"github.com/coder/coder/agent/agentssh"
40+
"github.com/coder/coder/agent/usershell"
3841
"github.com/coder/coder/buildinfo"
3942
"github.com/coder/coder/coderd/database"
4043
"github.com/coder/coder/coderd/gitauth"
@@ -202,7 +205,34 @@ func (a *agent) runLoop(ctx context.Context) {
202205
}
203206
}
204207

205-
func (a *agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentMetadataDescription) *codersdk.WorkspaceAgentMetadataResult {
208+
func createMetadataCommand(ctx context.Context, script string) (*exec.Cmd, error) {
209+
// This is largely copied from agentssh, but for some reason the command
210+
// generated there always returns exit status 1 in Windows.
211+
currentUser, err := user.Current()
212+
if err != nil {
213+
return nil, xerrors.Errorf("get current user: %w", err)
214+
}
215+
username := currentUser.Username
216+
217+
shell, err := usershell.Get(username)
218+
if err != nil {
219+
return nil, xerrors.Errorf("get user shell: %w", err)
220+
}
221+
222+
var caller string
223+
switch {
224+
case filepath.Base(shell) == "pwsh.exe":
225+
caller = "-Command"
226+
case runtime.GOOS == "windows":
227+
caller = "/c"
228+
default:
229+
caller = "-c"
230+
}
231+
args := []string{caller, "Get-Process"}
232+
return exec.CommandContext(ctx, shell, args...), nil
233+
}
234+
235+
func (*agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentMetadataDescription) *codersdk.WorkspaceAgentMetadataResult {
206236
var out bytes.Buffer
207237
result := &codersdk.WorkspaceAgentMetadataResult{
208238
// CollectedAt is set here for testing purposes and overrode by
@@ -213,18 +243,32 @@ func (a *agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentM
213243
// if it is certain the clocks are in sync.
214244
CollectedAt: time.Now(),
215245
}
216-
cmd, err := a.sshServer.CreateCommand(ctx, md.Script, nil)
246+
cmd, err := createMetadataCommand(ctx, md.Script)
217247
if err != nil {
218-
result.Error = err.Error()
248+
result.Error = fmt.Sprintf("create cmd: %+v", err)
219249
return result
220250
}
221251

252+
// execPath, err := exec.LookPath("cmd.exe")
253+
// if err != nil {
254+
// result.Error = fmt.Sprintf("look path: %+v", err)
255+
// return result
256+
// }
257+
258+
// cmd = exec.CommandContext(ctx, execPath, "/c", "echo hello")
259+
222260
cmd.Stdout = &out
223261
cmd.Stderr = &out
224262

225-
// The error isn't mutually exclusive with useful output.
226-
err = cmd.Run()
263+
// We split up Start and Wait so that we can return a more useful error.
264+
err = cmd.Start()
265+
if err != nil {
266+
result.Error = fmt.Sprintf("start cmd: %+v", err)
267+
return result
268+
}
227269

270+
// This error isn't mutually exclusive with useful output.
271+
err = cmd.Wait()
228272
const bufLimit = 10 << 10
229273
if out.Len() > bufLimit {
230274
err = errors.Join(
@@ -234,8 +278,10 @@ func (a *agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentM
234278
out.Truncate(bufLimit)
235279
}
236280

281+
fmt.Printf("ran %+v %+q: %v\n", cmd.Path, cmd.Args, err)
282+
237283
if err != nil {
238-
result.Error = err.Error()
284+
result.Error = fmt.Sprintf("run cmd: %+v", err)
239285
}
240286
result.Value = out.String()
241287
return result

agent/agent_test.go

+10-11
Original file line numberDiff line numberDiff line change
@@ -976,19 +976,20 @@ 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+
}
983+
979984
t.Run("Once", func(t *testing.T) {
980985
t.Parallel()
981-
script := "echo -n hello"
982-
if runtime.GOOS == "windows" {
983-
script = "powershell " + script
984-
}
985986
//nolint:dogsled
986987
_, client, _, _, _ := setupAgent(t, agentsdk.Manifest{
987988
Metadata: []codersdk.WorkspaceAgentMetadataDescription{
988989
{
989990
Key: "greeting",
990991
Interval: 0,
991-
Script: script,
992+
Script: echoHello,
992993
},
993994
},
994995
}, 0)
@@ -1012,17 +1013,13 @@ func TestAgent_Metadata(t *testing.T) {
10121013

10131014
t.Run("Many", func(t *testing.T) {
10141015
t.Parallel()
1015-
script := "echo -n hello"
1016-
if runtime.GOOS == "windows" {
1017-
script = "powershell " + script
1018-
}
10191016
//nolint:dogsled
10201017
_, client, _, _, _ := setupAgent(t, agentsdk.Manifest{
10211018
Metadata: []codersdk.WorkspaceAgentMetadataDescription{
10221019
{
10231020
Key: "greeting",
10241021
Interval: 1,
1025-
Script: script,
1022+
Script: echoHello,
10261023
},
10271024
},
10281025
}, 0)
@@ -1034,7 +1031,9 @@ func TestAgent_Metadata(t *testing.T) {
10341031
}, testutil.WaitShort, testutil.IntervalMedium)
10351032

10361033
collectedAt1 := gotMd["greeting"].CollectedAt
1037-
assert.Equal(t, "hello", gotMd["greeting"].Value)
1034+
if !assert.Equal(t, "hello\n", gotMd["greeting"].Value) {
1035+
t.Logf("got: %+v", gotMd)
1036+
}
10381037

10391038
if !assert.Eventually(t, func() bool {
10401039
gotMd = client.getMetadata()

0 commit comments

Comments
 (0)