Skip to content

Commit cfc1564

Browse files
committed
fix windows?
1 parent ba6f151 commit cfc1564

File tree

2 files changed

+65
-17
lines changed

2 files changed

+65
-17
lines changed

agent/agent.go

+55-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,36 @@ 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+
args := []string{"-NoProfile", "-NonInteractive"}
233+
_ = caller
234+
return exec.CommandContext(ctx, "pwsh.exe", args...), nil
235+
}
236+
237+
func (*agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentMetadataDescription) *codersdk.WorkspaceAgentMetadataResult {
206238
var out bytes.Buffer
207239
result := &codersdk.WorkspaceAgentMetadataResult{
208240
// CollectedAt is set here for testing purposes and overrode by
@@ -213,18 +245,33 @@ func (a *agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentM
213245
// if it is certain the clocks are in sync.
214246
CollectedAt: time.Now(),
215247
}
216-
cmd, err := a.sshServer.CreateCommand(ctx, md.Script, nil)
248+
cmd, err := createMetadataCommand(ctx, md.Script)
217249
if err != nil {
218-
result.Error = err.Error()
250+
result.Error = fmt.Sprintf("create cmd: %+v", err)
219251
return result
220252
}
221253

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+
222262
cmd.Stdout = &out
223263
cmd.Stderr = &out
264+
cmd.Stdin = io.LimitReader(nil, 0)
224265

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

273+
// This error isn't mutually exclusive with useful output.
274+
err = cmd.Wait()
228275
const bufLimit = 10 << 10
229276
if out.Len() > bufLimit {
230277
err = errors.Join(
@@ -234,8 +281,10 @@ func (a *agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentM
234281
out.Truncate(bufLimit)
235282
}
236283

284+
fmt.Printf("ran %+v %+q: %v\n", cmd.Path, cmd.Args, err)
285+
237286
if err != nil {
238-
result.Error = err.Error()
287+
result.Error = fmt.Sprintf("run cmd: %+v", err)
239288
}
240289
result.Value = out.String()
241290
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)