Skip to content

Commit 8794254

Browse files
committed
Merge remote-tracking branch 'origin/main' into matifali/template-push-create
2 parents c2b5c68 + 7072b8e commit 8794254

File tree

129 files changed

+2857
-1178
lines changed

Some content is hidden

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

129 files changed

+2857
-1178
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ jobs:
7272
- "cmd/**"
7373
- "coderd/**"
7474
- "enterprise/**"
75-
- "examples/**"
75+
- "examples/*"
7676
- "provisioner/**"
7777
- "provisionerd/**"
7878
- "provisionersdk/**"

.github/workflows/pr-cleanup.yaml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ jobs:
1818
- name: Get PR number
1919
id: pr_number
2020
run: |
21-
if [ -z "${{ github.event.pull_request.number }}" ]; then
21+
if [ -n "${{ github.event.pull_request.number }}" ]; then
2222
echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
2323
else
2424
echo "PR_NUMBER=${{ github.event.inputs.pr_number }}" >> $GITHUB_OUTPUT
2525
fi
2626
2727
- name: Delete image
28+
continue-on-error: true
2829
uses: bots-house/ghcr-delete-image-action@v1.1.0
2930
with:
3031
owner: coder
@@ -33,20 +34,17 @@ jobs:
3334
tag: pr${{ steps.pr_number.outputs.PR_NUMBER }}
3435

3536
- name: Set up kubeconfig
36-
if: always()
3737
run: |
3838
set -euxo pipefail
3939
mkdir -p ~/.kube
4040
echo "${{ secrets.DELIVERYBOT_KUBECONFIG }}" > ~/.kube/config
4141
export KUBECONFIG=~/.kube/config
4242
4343
- name: Delete helm release
44-
if: always()
4544
run: |
4645
set -euxo pipefail
4746
helm delete --namespace "pr${{ steps.pr_number.outputs.PR_NUMBER }}" "pr${{ steps.pr_number.outputs.PR_NUMBER }}" || echo "helm release not found"
4847
4948
- name: "Remove PR namespace"
50-
if: always()
5149
run: |
5250
kubectl delete namespace "pr${{ steps.pr_number.outputs.PR_NUMBER }}" || echo "namespace not found"

.github/workflows/stale.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,21 @@ jobs:
4646
del_runs:
4747
runs-on: ubuntu-latest
4848
steps:
49-
- name: Delete workflow runs
49+
- name: Delete PR Cleanup workflow runs
5050
uses: Mattraks/delete-workflow-runs@v2
5151
with:
5252
token: ${{ github.token }}
5353
repository: ${{ github.repository }}
5454
retain_days: 1
5555
keep_minimum_runs: 1
5656
delete_workflow_pattern: pr-cleanup.yaml
57+
58+
- name: Delete PR Deploy workflow skipped runs
59+
uses: Mattraks/delete-workflow-runs@v2
60+
with:
61+
token: ${{ github.token }}
62+
repository: ${{ github.repository }}
63+
retain_days: 0
64+
keep_minimum_runs: 0
65+
delete_run_by_conclusion_pattern: skipped
66+
delete_workflow_pattern: pr-deploy.yaml

.vscode/settings.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,5 @@
211211
"go.testFlags": ["-short", "-coverpkg=./..."],
212212
// We often use a version of TypeScript that's ahead of the version shipped
213213
// with VS Code.
214-
"typescript.tsdk": "./site/node_modules/typescript/lib",
215-
"prettier.prettierPath": "./node_modules/prettier"
214+
"typescript.tsdk": "./site/node_modules/typescript/lib"
216215
}

agent/agent_test.go

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"go.uber.org/goleak"
3636
"golang.org/x/crypto/ssh"
3737
"golang.org/x/exp/maps"
38+
"golang.org/x/exp/slices"
3839
"golang.org/x/xerrors"
3940
"tailscale.com/net/speedtest"
4041
"tailscale.com/tailcfg"
@@ -1099,7 +1100,7 @@ func TestAgent_Lifecycle(t *testing.T) {
10991100
t.Parallel()
11001101

11011102
_, client, _, _, _ := setupAgent(t, agentsdk.Manifest{
1102-
StartupScript: "sleep 5",
1103+
StartupScript: "sleep 3",
11031104
StartupScriptTimeout: time.Nanosecond,
11041105
}, 0)
11051106

@@ -1111,10 +1112,10 @@ func TestAgent_Lifecycle(t *testing.T) {
11111112
var got []codersdk.WorkspaceAgentLifecycle
11121113
assert.Eventually(t, func() bool {
11131114
got = client.getLifecycleStates()
1114-
return len(got) > 0 && got[len(got)-1] == want[len(want)-1]
1115+
return slices.Contains(got, want[len(want)-1])
11151116
}, testutil.WaitShort, testutil.IntervalMedium)
11161117

1117-
require.Equal(t, want, got)
1118+
require.Equal(t, want, got[:len(want)])
11181119
})
11191120

11201121
t.Run("StartError", func(t *testing.T) {
@@ -1133,10 +1134,10 @@ func TestAgent_Lifecycle(t *testing.T) {
11331134
var got []codersdk.WorkspaceAgentLifecycle
11341135
assert.Eventually(t, func() bool {
11351136
got = client.getLifecycleStates()
1136-
return len(got) > 0 && got[len(got)-1] == want[len(want)-1]
1137+
return slices.Contains(got, want[len(want)-1])
11371138
}, testutil.WaitShort, testutil.IntervalMedium)
11381139

1139-
require.Equal(t, want, got)
1140+
require.Equal(t, want, got[:len(want)])
11401141
})
11411142

11421143
t.Run("Ready", func(t *testing.T) {
@@ -1165,14 +1166,12 @@ func TestAgent_Lifecycle(t *testing.T) {
11651166
t.Parallel()
11661167

11671168
_, client, _, _, closer := setupAgent(t, agentsdk.Manifest{
1168-
ShutdownScript: "sleep 5",
1169+
ShutdownScript: "sleep 3",
11691170
StartupScriptTimeout: 30 * time.Second,
11701171
}, 0)
11711172

1172-
var ready []codersdk.WorkspaceAgentLifecycle
11731173
assert.Eventually(t, func() bool {
1174-
ready = client.getLifecycleStates()
1175-
return len(ready) > 0 && ready[len(ready)-1] == codersdk.WorkspaceAgentLifecycleReady
1174+
return slices.Contains(client.getLifecycleStates(), codersdk.WorkspaceAgentLifecycleReady)
11761175
}, testutil.WaitShort, testutil.IntervalMedium)
11771176

11781177
// Start close asynchronously so that we an inspect the state.
@@ -1187,30 +1186,30 @@ func TestAgent_Lifecycle(t *testing.T) {
11871186
})
11881187

11891188
want := []codersdk.WorkspaceAgentLifecycle{
1189+
codersdk.WorkspaceAgentLifecycleStarting,
1190+
codersdk.WorkspaceAgentLifecycleReady,
11901191
codersdk.WorkspaceAgentLifecycleShuttingDown,
11911192
}
11921193

11931194
var got []codersdk.WorkspaceAgentLifecycle
11941195
assert.Eventually(t, func() bool {
1195-
got = client.getLifecycleStates()[len(ready):]
1196-
return len(got) > 0 && got[len(got)-1] == want[len(want)-1]
1196+
got = client.getLifecycleStates()
1197+
return slices.Contains(got, want[len(want)-1])
11971198
}, testutil.WaitShort, testutil.IntervalMedium)
11981199

1199-
require.Equal(t, want, got)
1200+
require.Equal(t, want, got[:len(want)])
12001201
})
12011202

12021203
t.Run("ShutdownTimeout", func(t *testing.T) {
12031204
t.Parallel()
12041205

12051206
_, client, _, _, closer := setupAgent(t, agentsdk.Manifest{
1206-
ShutdownScript: "sleep 5",
1207+
ShutdownScript: "sleep 3",
12071208
ShutdownScriptTimeout: time.Nanosecond,
12081209
}, 0)
12091210

1210-
var ready []codersdk.WorkspaceAgentLifecycle
12111211
assert.Eventually(t, func() bool {
1212-
ready = client.getLifecycleStates()
1213-
return len(ready) > 0 && ready[len(ready)-1] == codersdk.WorkspaceAgentLifecycleReady
1212+
return slices.Contains(client.getLifecycleStates(), codersdk.WorkspaceAgentLifecycleReady)
12141213
}, testutil.WaitShort, testutil.IntervalMedium)
12151214

12161215
// Start close asynchronously so that we an inspect the state.
@@ -1225,17 +1224,19 @@ func TestAgent_Lifecycle(t *testing.T) {
12251224
})
12261225

12271226
want := []codersdk.WorkspaceAgentLifecycle{
1227+
codersdk.WorkspaceAgentLifecycleStarting,
1228+
codersdk.WorkspaceAgentLifecycleReady,
12281229
codersdk.WorkspaceAgentLifecycleShuttingDown,
12291230
codersdk.WorkspaceAgentLifecycleShutdownTimeout,
12301231
}
12311232

12321233
var got []codersdk.WorkspaceAgentLifecycle
12331234
assert.Eventually(t, func() bool {
1234-
got = client.getLifecycleStates()[len(ready):]
1235-
return len(got) > 0 && got[len(got)-1] == want[len(want)-1]
1235+
got = client.getLifecycleStates()
1236+
return slices.Contains(got, want[len(want)-1])
12361237
}, testutil.WaitShort, testutil.IntervalMedium)
12371238

1238-
require.Equal(t, want, got)
1239+
require.Equal(t, want, got[:len(want)])
12391240
})
12401241

12411242
t.Run("ShutdownError", func(t *testing.T) {
@@ -1246,10 +1247,8 @@ func TestAgent_Lifecycle(t *testing.T) {
12461247
ShutdownScriptTimeout: 30 * time.Second,
12471248
}, 0)
12481249

1249-
var ready []codersdk.WorkspaceAgentLifecycle
12501250
assert.Eventually(t, func() bool {
1251-
ready = client.getLifecycleStates()
1252-
return len(ready) > 0 && ready[len(ready)-1] == codersdk.WorkspaceAgentLifecycleReady
1251+
return slices.Contains(client.getLifecycleStates(), codersdk.WorkspaceAgentLifecycleReady)
12531252
}, testutil.WaitShort, testutil.IntervalMedium)
12541253

12551254
// Start close asynchronously so that we an inspect the state.
@@ -1264,17 +1263,19 @@ func TestAgent_Lifecycle(t *testing.T) {
12641263
})
12651264

12661265
want := []codersdk.WorkspaceAgentLifecycle{
1266+
codersdk.WorkspaceAgentLifecycleStarting,
1267+
codersdk.WorkspaceAgentLifecycleReady,
12671268
codersdk.WorkspaceAgentLifecycleShuttingDown,
12681269
codersdk.WorkspaceAgentLifecycleShutdownError,
12691270
}
12701271

12711272
var got []codersdk.WorkspaceAgentLifecycle
12721273
assert.Eventually(t, func() bool {
1273-
got = client.getLifecycleStates()[len(ready):]
1274-
return len(got) > 0 && got[len(got)-1] == want[len(want)-1]
1274+
got = client.getLifecycleStates()
1275+
return slices.Contains(got, want[len(want)-1])
12751276
}, testutil.WaitShort, testutil.IntervalMedium)
12761277

1277-
require.Equal(t, want, got)
1278+
require.Equal(t, want, got[:len(want)])
12781279
})
12791280

12801281
t.Run("ShutdownScriptOnce", func(t *testing.T) {

cli/agent.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,12 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
106106
// Spawn a reaper so that we don't accumulate a ton
107107
// of zombie processes.
108108
if reaper.IsInitProcess() && !noReap && isLinux {
109-
logWriter := &lumberjack.Logger{
109+
logWriter := &lumberjackWriteCloseFixer{w: &lumberjack.Logger{
110110
Filename: filepath.Join(logDir, "coder-agent-init.log"),
111111
MaxSize: 5, // MB
112112
// Without this, rotated logs will never be deleted.
113113
MaxBackups: 1,
114-
}
114+
}}
115115
defer logWriter.Close()
116116

117117
sinks = append(sinks, sloghuman.Sink(logWriter))
@@ -149,14 +149,12 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
149149
// reaper.
150150
go DumpHandler(ctx)
151151

152-
ljLogger := &lumberjack.Logger{
152+
logWriter := &lumberjackWriteCloseFixer{w: &lumberjack.Logger{
153153
Filename: filepath.Join(logDir, "coder-agent.log"),
154154
MaxSize: 5, // MB
155155
// Without this, rotated logs will never be deleted.
156156
MaxBackups: 1,
157-
}
158-
defer ljLogger.Close()
159-
logWriter := &closeWriter{w: ljLogger}
157+
}}
160158
defer logWriter.Close()
161159

162160
sinks = append(sinks, sloghuman.Sink(logWriter))
@@ -403,24 +401,24 @@ func ServeHandler(ctx context.Context, logger slog.Logger, handler http.Handler,
403401
}
404402
}
405403

406-
// closeWriter is a wrapper around an io.WriteCloser that prevents
407-
// writes after Close. This is necessary because lumberjack will
408-
// re-open the file on write.
409-
type closeWriter struct {
404+
// lumberjackWriteCloseFixer is a wrapper around an io.WriteCloser that
405+
// prevents writes after Close. This is necessary because lumberjack
406+
// re-opens the file on Write.
407+
type lumberjackWriteCloseFixer struct {
410408
w io.WriteCloser
411409
mu sync.Mutex // Protects following.
412410
closed bool
413411
}
414412

415-
func (c *closeWriter) Close() error {
413+
func (c *lumberjackWriteCloseFixer) Close() error {
416414
c.mu.Lock()
417415
defer c.mu.Unlock()
418416

419417
c.closed = true
420418
return c.w.Close()
421419
}
422420

423-
func (c *closeWriter) Write(p []byte) (int, error) {
421+
func (c *lumberjackWriteCloseFixer) Write(p []byte) (int, error) {
424422
c.mu.Lock()
425423
defer c.mu.Unlock()
426424

cli/clistat/cgroup.go

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,10 @@ func (s *Statter) ContainerCPU() (*Result, error) {
8484
}
8585

8686
r := &Result{
87-
Unit: "cores",
88-
Used: used2 - used1,
89-
Total: ptr.To(total),
87+
Unit: "cores",
88+
Used: used2 - used1,
89+
Total: ptr.To(total),
90+
Prefix: PrefixDefault,
9091
}
9192
return r, nil
9293
}
@@ -184,20 +185,20 @@ func (s *Statter) cGroupV1CPUUsed() (float64, error) {
184185

185186
// ContainerMemory returns the memory usage of the container cgroup.
186187
// If the system is not containerized, this always returns nil.
187-
func (s *Statter) ContainerMemory() (*Result, error) {
188+
func (s *Statter) ContainerMemory(p Prefix) (*Result, error) {
188189
if ok, err := IsContainerized(s.fs); err != nil || !ok {
189190
return nil, nil //nolint:nilnil
190191
}
191192

192193
if s.isCGroupV2() {
193-
return s.cGroupV2Memory()
194+
return s.cGroupV2Memory(p)
194195
}
195196

196197
// Fall back to CGroupv1
197-
return s.cGroupV1Memory()
198+
return s.cGroupV1Memory(p)
198199
}
199200

200-
func (s *Statter) cGroupV2Memory() (*Result, error) {
201+
func (s *Statter) cGroupV2Memory(p Prefix) (*Result, error) {
201202
maxUsageBytes, err := readInt64(s.fs, cgroupV2MemoryMaxBytes)
202203
if err != nil {
203204
return nil, xerrors.Errorf("read memory total: %w", err)
@@ -214,13 +215,14 @@ func (s *Statter) cGroupV2Memory() (*Result, error) {
214215
}
215216

216217
return &Result{
217-
Total: ptr.To(float64(maxUsageBytes)),
218-
Used: float64(currUsageBytes - inactiveFileBytes),
219-
Unit: "B",
218+
Total: ptr.To(float64(maxUsageBytes)),
219+
Used: float64(currUsageBytes - inactiveFileBytes),
220+
Unit: "B",
221+
Prefix: p,
220222
}, nil
221223
}
222224

223-
func (s *Statter) cGroupV1Memory() (*Result, error) {
225+
func (s *Statter) cGroupV1Memory(p Prefix) (*Result, error) {
224226
maxUsageBytes, err := readInt64(s.fs, cgroupV1MemoryMaxUsageBytes)
225227
if err != nil {
226228
return nil, xerrors.Errorf("read memory total: %w", err)
@@ -239,9 +241,10 @@ func (s *Statter) cGroupV1Memory() (*Result, error) {
239241

240242
// Total memory used is usage - total_inactive_file
241243
return &Result{
242-
Total: ptr.To(float64(maxUsageBytes)),
243-
Used: float64(usageBytes - totalInactiveFileBytes),
244-
Unit: "B",
244+
Total: ptr.To(float64(maxUsageBytes)),
245+
Used: float64(usageBytes - totalInactiveFileBytes),
246+
Unit: "B",
247+
Prefix: p,
245248
}, nil
246249
}
247250

cli/clistat/disk.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010

1111
// Disk returns the disk usage of the given path.
1212
// If path is empty, it returns the usage of the root directory.
13-
func (*Statter) Disk(path string) (*Result, error) {
13+
func (*Statter) Disk(p Prefix, path string) (*Result, error) {
1414
if path == "" {
1515
path = "/"
1616
}
@@ -22,5 +22,6 @@ func (*Statter) Disk(path string) (*Result, error) {
2222
r.Total = ptr.To(float64(stat.Blocks * uint64(stat.Bsize)))
2323
r.Used = float64(stat.Blocks-stat.Bfree) * float64(stat.Bsize)
2424
r.Unit = "B"
25+
r.Prefix = p
2526
return &r, nil
2627
}

cli/clistat/disk_windows.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77

88
// Disk returns the disk usage of the given path.
99
// If path is empty, it defaults to C:\
10-
func (*Statter) Disk(path string) (*Result, error) {
10+
func (*Statter) Disk(p Prefix, path string) (*Result, error) {
1111
if path == "" {
1212
path = `C:\`
1313
}
@@ -31,5 +31,6 @@ func (*Statter) Disk(path string) (*Result, error) {
3131
r.Total = ptr.To(float64(totalBytes))
3232
r.Used = float64(totalBytes - freeBytes)
3333
r.Unit = "B"
34+
r.Prefix = p
3435
return &r, nil
3536
}

0 commit comments

Comments
 (0)