Skip to content

Commit c82ff9a

Browse files
committed
Merge remote-tracking branch 'origin/main' into stevenmasley/soft_delete_versions
2 parents 9a416c3 + 3bbfcc5 commit c82ff9a

File tree

237 files changed

+3270
-1654
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

237 files changed

+3270
-1654
lines changed

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ gen: \
472472
site/.prettierignore \
473473
site/.eslintignore \
474474
site/e2e/provisionerGenerated.ts \
475+
site/src/theme/icons.json \
475476
examples/examples.gen.json
476477
.PHONY: gen
477478

@@ -495,6 +496,7 @@ gen/mark-fresh:
495496
site/.prettierignore \
496497
site/.eslintignore \
497498
site/e2e/provisionerGenerated.ts \
499+
site/src/theme/icons.json \
498500
examples/examples.gen.json \
499501
"
500502
for file in $$files; do
@@ -538,7 +540,7 @@ provisionerd/proto/provisionerd.pb.go: provisionerd/proto/provisionerd.proto
538540
./provisionerd/proto/provisionerd.proto
539541

540542
site/src/api/typesGenerated.ts: scripts/apitypings/main.go $(shell find ./codersdk $(FIND_EXCLUSIONS) -type f -name '*.go')
541-
go run scripts/apitypings/main.go > site/src/api/typesGenerated.ts
543+
go run ./scripts/apitypings/ > site/src/api/typesGenerated.ts
542544
cd site
543545
pnpm run format:types ./src/api/typesGenerated.ts
544546

@@ -547,6 +549,10 @@ site/e2e/provisionerGenerated.ts: provisionerd/proto/provisionerd.pb.go provisio
547549
../scripts/pnpm_install.sh
548550
pnpm run gen:provisioner
549551

552+
site/src/theme/icons.json: $(wildcard site/static/icon/*)
553+
go run ./scripts/gensite/ -icons $@
554+
pnpm run format:write:only $@
555+
550556
examples/examples.gen.json: scripts/examplegen/main.go examples/examples.go $(shell find ./examples/templates)
551557
go run ./scripts/examplegen/main.go > examples/examples.gen.json
552558

agent/agent.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,10 @@ func (a *agent) createTailnet(ctx context.Context, agentID uuid.UUID, derpMap *t
833833
}
834834
break
835835
}
836-
logger.Debug(ctx, "accepted conn", slog.F("remote", conn.RemoteAddr().String()))
836+
clog := logger.With(
837+
slog.F("remote", conn.RemoteAddr().String()),
838+
slog.F("local", conn.LocalAddr().String()))
839+
clog.Info(ctx, "accepted conn")
837840
wg.Add(1)
838841
closed := make(chan struct{})
839842
go func() {
@@ -865,7 +868,7 @@ func (a *agent) createTailnet(ctx context.Context, agentID uuid.UUID, derpMap *t
865868
logger.Warn(ctx, "failed to unmarshal init", slog.F("raw", data))
866869
return
867870
}
868-
_ = a.handleReconnectingPTY(ctx, logger, msg, conn)
871+
_ = a.handleReconnectingPTY(ctx, clog, msg, conn)
869872
}()
870873
}
871874
wg.Wait()
@@ -892,6 +895,10 @@ func (a *agent) createTailnet(ctx context.Context, agentID uuid.UUID, derpMap *t
892895
}
893896
break
894897
}
898+
clog := a.logger.Named("speedtest").With(
899+
slog.F("remote", conn.RemoteAddr().String()),
900+
slog.F("local", conn.LocalAddr().String()))
901+
clog.Info(ctx, "accepted conn")
895902
wg.Add(1)
896903
closed := make(chan struct{})
897904
go func() {
@@ -904,7 +911,12 @@ func (a *agent) createTailnet(ctx context.Context, agentID uuid.UUID, derpMap *t
904911
}()
905912
go func() {
906913
defer close(closed)
907-
_ = speedtest.ServeConn(conn)
914+
sErr := speedtest.ServeConn(conn)
915+
if sErr != nil {
916+
clog.Error(ctx, "test ended with error", slog.Error(sErr))
917+
return
918+
}
919+
clog.Info(ctx, "test ended")
908920
}()
909921
}
910922
wg.Wait()
@@ -1021,12 +1033,12 @@ func (a *agent) handleReconnectingPTY(ctx context.Context, logger slog.Logger, m
10211033
// If the agent is closed, we don't want to
10221034
// log this as an error since it's expected.
10231035
if closed {
1024-
connLogger.Debug(ctx, "reconnecting pty failed with attach error (agent closed)", slog.Error(err))
1036+
connLogger.Info(ctx, "reconnecting pty failed with attach error (agent closed)", slog.Error(err))
10251037
} else {
10261038
connLogger.Error(ctx, "reconnecting pty failed with attach error", slog.Error(err))
10271039
}
10281040
}
1029-
connLogger.Debug(ctx, "reconnecting pty connection closed")
1041+
connLogger.Info(ctx, "reconnecting pty connection closed")
10301042
}()
10311043

10321044
var rpty reconnectingpty.ReconnectingPTY

agent/agent_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1850,13 +1850,16 @@ func TestAgent_UpdatedDERP(t *testing.T) {
18501850
func TestAgent_Speedtest(t *testing.T) {
18511851
t.Parallel()
18521852
t.Skip("This test is relatively flakey because of Tailscale's speedtest code...")
1853+
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
18531854
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
18541855
defer cancel()
18551856
derpMap, _ := tailnettest.RunDERPAndSTUN(t)
18561857
//nolint:dogsled
18571858
conn, _, _, _, _ := setupAgent(t, agentsdk.Manifest{
18581859
DERPMap: derpMap,
1859-
}, 0)
1860+
}, 0, func(client *agenttest.Client, options *agent.Options) {
1861+
options.Logger = logger.Named("agent")
1862+
})
18601863
defer conn.Close()
18611864
res, err := conn.Speedtest(ctx, speedtest.Upload, 250*time.Millisecond)
18621865
require.NoError(t, err)

agent/agentssh/agentssh.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"time"
2020

2121
"github.com/gliderlabs/ssh"
22+
"github.com/kballard/go-shellquote"
2223
"github.com/pkg/sftp"
2324
"github.com/prometheus/client_golang/prometheus"
2425
"github.com/spf13/afero"
@@ -515,8 +516,29 @@ func (s *Server) CreateCommand(ctx context.Context, script string, env []string)
515516
if runtime.GOOS == "windows" {
516517
caller = "/c"
517518
}
519+
name := shell
518520
args := []string{caller, script}
519521

522+
if strings.HasPrefix(strings.TrimSpace(script), "#!") {
523+
// If the script starts with a shebang, we should
524+
// execute it directly. This is useful for running
525+
// scripts that aren't executable.
526+
shebang := strings.SplitN(script, "\n", 2)[0]
527+
shebang = strings.TrimPrefix(shebang, "#!")
528+
shebang = strings.TrimSpace(shebang)
529+
words, err := shellquote.Split(shebang)
530+
if err != nil {
531+
return nil, xerrors.Errorf("split shebang: %w", err)
532+
}
533+
name = words[0]
534+
if len(words) > 1 {
535+
args = words[1:]
536+
} else {
537+
args = []string{}
538+
}
539+
args = append(args, caller, script)
540+
}
541+
520542
// gliderlabs/ssh returns a command slice of zero
521543
// when a shell is requested.
522544
if len(script) == 0 {
@@ -528,7 +550,7 @@ func (s *Server) CreateCommand(ctx context.Context, script string, env []string)
528550
}
529551
}
530552

531-
cmd := pty.CommandContext(ctx, shell, args...)
553+
cmd := pty.CommandContext(ctx, name, args...)
532554
cmd.Dir = manifest.Directory
533555

534556
// If the metadata directory doesn't exist, we run the command

agent/agentssh/agentssh_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"bytes"
77
"context"
88
"net"
9+
"runtime"
910
"strings"
1011
"sync"
1112
"testing"
@@ -71,6 +72,42 @@ func TestNewServer_ServeClient(t *testing.T) {
7172
<-done
7273
}
7374

75+
func TestNewServer_ExecuteShebang(t *testing.T) {
76+
t.Parallel()
77+
if runtime.GOOS == "windows" {
78+
t.Skip("bash doesn't exist on Windows")
79+
}
80+
81+
ctx := context.Background()
82+
logger := slogtest.Make(t, nil)
83+
s, err := agentssh.NewServer(ctx, logger, prometheus.NewRegistry(), afero.NewMemMapFs(), 0, "")
84+
require.NoError(t, err)
85+
t.Cleanup(func() {
86+
_ = s.Close()
87+
})
88+
s.AgentToken = func() string { return "" }
89+
s.Manifest = atomic.NewPointer(&agentsdk.Manifest{})
90+
91+
t.Run("Basic", func(t *testing.T) {
92+
t.Parallel()
93+
cmd, err := s.CreateCommand(ctx, `#!/bin/bash
94+
echo test`, nil)
95+
require.NoError(t, err)
96+
output, err := cmd.AsExec().CombinedOutput()
97+
require.NoError(t, err)
98+
require.Equal(t, "test\n", string(output))
99+
})
100+
t.Run("Args", func(t *testing.T) {
101+
t.Parallel()
102+
cmd, err := s.CreateCommand(ctx, `#!/usr/bin/env bash
103+
echo test`, nil)
104+
require.NoError(t, err)
105+
output, err := cmd.AsExec().CombinedOutput()
106+
require.NoError(t, err)
107+
require.Equal(t, "test\n", string(output))
108+
})
109+
}
110+
74111
func TestNewServer_CloseActiveConnections(t *testing.T) {
75112
t.Parallel()
76113

cli/create.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func (r *RootCmd) create() *clibase.Cmd {
2727
workspaceName string
2828

2929
parameterFlags workspaceParameterFlags
30+
autoUpdates string
3031
)
3132
client := new(codersdk.Client)
3233
cmd := &clibase.Cmd{
@@ -169,6 +170,7 @@ func (r *RootCmd) create() *clibase.Cmd {
169170
AutostartSchedule: schedSpec,
170171
TTLMillis: ttlMillis,
171172
RichParameterValues: richParameters,
173+
AutomaticUpdates: codersdk.AutomaticUpdates(autoUpdates),
172174
})
173175
if err != nil {
174176
return xerrors.Errorf("create workspace: %w", err)
@@ -208,6 +210,13 @@ func (r *RootCmd) create() *clibase.Cmd {
208210
Description: "Specify a duration after which the workspace should shut down (e.g. 8h).",
209211
Value: clibase.DurationOf(&stopAfter),
210212
},
213+
clibase.Option{
214+
Flag: "automatic-updates",
215+
Env: "CODER_WORKSPACE_AUTOMATIC_UPDATES",
216+
Description: "Specify automatic updates setting for the workspace (accepts 'always' or 'never').",
217+
Default: string(codersdk.AutomaticUpdatesNever),
218+
Value: clibase.StringOf(&autoUpdates),
219+
},
211220
cliui.SkipPromptOption(),
212221
)
213222
cmd.Options = append(cmd.Options, parameterFlags.cliParameters()...)

cli/create_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func TestCreate(t *testing.T) {
3838
"--template", template.Name,
3939
"--start-at", "9:30AM Mon-Fri US/Central",
4040
"--stop-after", "8h",
41+
"--automatic-updates", "always",
4142
}
4243
inv, root := clitest.New(t, args...)
4344
clitest.SetupConfig(t, client, root)
@@ -73,6 +74,7 @@ func TestCreate(t *testing.T) {
7374
if assert.NotNil(t, ws.TTLMillis) {
7475
assert.Equal(t, *ws.TTLMillis, 8*time.Hour.Milliseconds())
7576
}
77+
assert.Equal(t, codersdk.AutomaticUpdatesAlways, ws.AutomaticUpdates)
7678
}
7779
})
7880

cli/exp_scaletest.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,8 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
525525

526526
useHostUser bool
527527

528+
parameterFlags workspaceParameterFlags
529+
528530
tracingFlags = &scaletestTracingFlags{}
529531
strategy = &scaletestStrategyFlags{}
530532
cleanupStrategy = &scaletestStrategyFlags{cleanup: true}
@@ -597,11 +599,29 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
597599
return xerrors.Errorf("get template version %q: %w", tpl.ActiveVersionID, err)
598600
}
599601

602+
cliRichParameters, err := asWorkspaceBuildParameters(parameterFlags.richParameters)
603+
if err != nil {
604+
return xerrors.Errorf("can't parse given parameter values: %w", err)
605+
}
606+
607+
richParameters, err := prepWorkspaceBuild(inv, client, prepWorkspaceBuildArgs{
608+
Action: WorkspaceCreate,
609+
Template: tpl,
610+
NewWorkspaceName: "scaletest-%", // TODO: the scaletest runner will pass in a different name here. Does this matter?
611+
612+
RichParameterFile: parameterFlags.richParameterFile,
613+
RichParameters: cliRichParameters,
614+
})
615+
if err != nil {
616+
return xerrors.Errorf("prepare build: %w", err)
617+
}
618+
600619
// Do a dry-run to ensure the template and parameters are valid
601620
// before we start creating users and workspaces.
602621
if !noPlan {
603622
dryRun, err := client.CreateTemplateVersionDryRun(ctx, templateVersion.ID, codersdk.CreateTemplateVersionDryRunRequest{
604-
WorkspaceName: "scaletest",
623+
WorkspaceName: "scaletest",
624+
RichParameterValues: richParameters,
605625
})
606626
if err != nil {
607627
return xerrors.Errorf("start dry run workspace creation: %w", err)
@@ -653,7 +673,8 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
653673
OrganizationID: me.OrganizationIDs[0],
654674
// UserID is set by the test automatically.
655675
Request: codersdk.CreateWorkspaceRequest{
656-
TemplateID: tpl.ID,
676+
TemplateID: tpl.ID,
677+
RichParameterValues: richParameters,
657678
},
658679
NoWaitForAgents: noWaitForAgents,
659680
},
@@ -865,6 +886,7 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
865886
},
866887
}
867888

889+
cmd.Options = append(cmd.Options, parameterFlags.cliParameters()...)
868890
tracingFlags.attach(&cmd.Options)
869891
strategy.attach(&cmd.Options)
870892
cleanupStrategy.attach(&cmd.Options)

cli/exp_scaletest_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ func TestScaleTestCreateWorkspaces(t *testing.T) {
4848
"--cleanup-job-timeout", "15s",
4949
"--output", "text",
5050
"--output", "json:"+outputFile,
51+
"--parameter", "foo=baz",
52+
"--rich-parameter-file", "/path/to/some/parameter/file.ext",
5153
)
5254
clitest.SetupConfig(t, client, root)
5355
pty := ptytest.New(t)

cli/ssh_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ func TestSSH(t *testing.T) {
183183
// Run this async so the SSH command has to wait for
184184
// the build and agent to connect!
185185
_ = agenttest.New(t, client.URL, agentToken)
186-
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
187186
<-ctx.Done()
188187
})
189188

@@ -246,7 +245,6 @@ func TestSSH(t *testing.T) {
246245
// Run this async so the SSH command has to wait for
247246
// the build and agent to connect.
248247
_ = agenttest.New(t, client.URL, agentToken)
249-
coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
250248
<-ctx.Done()
251249
})
252250

cli/testdata/coder_create_--help.golden

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ USAGE:
1010
$ coder create <username>/<workspace_name>
1111

1212
OPTIONS:
13+
--automatic-updates string, $CODER_WORKSPACE_AUTOMATIC_UPDATES (default: never)
14+
Specify automatic updates setting for the workspace (accepts 'always'
15+
or 'never').
16+
1317
--parameter string-array, $CODER_RICH_PARAMETER
1418
Rich parameter value in the format "name=value".
1519

cli/testdata/coder_list_--output_json.golden

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"health": {
5858
"healthy": true,
5959
"failing_agents": []
60-
}
60+
},
61+
"automatic_updates": "never"
6162
}
6263
]

cli/testdata/coder_users_--help.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ SUBCOMMANDS:
1111
activate Update a user's status to 'active'. Active users can fully
1212
interact with the platform
1313
create
14+
delete Delete a user by username or user_id.
1415
list
1516
show Show a single user. Use 'me' to indicate the currently
1617
authenticated user.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
coder v0.0.0-devel
2+
3+
USAGE:
4+
coder users delete <username|user_id>
5+
6+
Delete a user by username or user_id.
7+
8+
Aliases: rm
9+
10+
———
11+
Run `coder --help` for a list of global options.

cli/testdata/coder_users_suspend_--help.golden

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ USAGE:
66
Update a user's status to 'suspended'. A suspended user cannot log into the
77
platform
88

9-
Aliases: rm, delete
10-
119
$ coder users suspend example_user
1210

1311
OPTIONS:

0 commit comments

Comments
 (0)