Skip to content

Commit 2e2f13a

Browse files
Merge branch 'main' into dm-experiment-autostart
2 parents 2d239a6 + 56c792a commit 2e2f13a

21 files changed

+478
-113
lines changed

agent/agentexec/cli_linux_test.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,9 @@ import (
2222
"github.com/coder/coder/v2/testutil"
2323
)
2424

25+
//nolint:paralleltest // This test is sensitive to environment variables
2526
func TestCLI(t *testing.T) {
26-
t.Parallel()
27-
2827
t.Run("OK", func(t *testing.T) {
29-
t.Parallel()
30-
3128
ctx := testutil.Context(t, testutil.WaitMedium)
3229
cmd, path := cmd(ctx, t, 123, 12)
3330
err := cmd.Start()
@@ -40,8 +37,6 @@ func TestCLI(t *testing.T) {
4037
})
4138

4239
t.Run("Defaults", func(t *testing.T) {
43-
t.Parallel()
44-
4540
ctx := testutil.Context(t, testutil.WaitMedium)
4641
cmd, path := cmd(ctx, t, 0, 0)
4742
err := cmd.Start()

agent/agentexec/exec_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func TestExec(t *testing.T) {
3636
//nolint:paralleltest // we need to test environment variables
3737
t.Run("Disabled", func(t *testing.T) {
3838
if runtime.GOOS != "linux" {
39-
t.Skip("skipping on linux")
39+
t.Skip("skipping on non-linux")
4040
}
4141

4242
cmd, err := agentexec.CommandContext(context.Background(), "sh", "-c", "sleep")
@@ -52,7 +52,7 @@ func TestExec(t *testing.T) {
5252
t.Setenv(agentexec.EnvProcPrioMgmt, "hello")
5353

5454
if runtime.GOOS != "linux" {
55-
t.Skip("skipping on linux")
55+
t.Skip("skipping on non-linux")
5656
}
5757

5858
executable, err := os.Executable()
@@ -69,7 +69,7 @@ func TestExec(t *testing.T) {
6969
t.Setenv(agentexec.EnvProcNiceScore, "10")
7070

7171
if runtime.GOOS != "linux" {
72-
t.Skip("skipping on linux")
72+
t.Skip("skipping on non-linux")
7373
}
7474

7575
executable, err := os.Executable()
@@ -86,7 +86,7 @@ func TestExec(t *testing.T) {
8686
t.Setenv(agentexec.EnvProcOOMScore, "123")
8787

8888
if runtime.GOOS != "linux" {
89-
t.Skip("skipping on linux")
89+
t.Skip("skipping on non-linux")
9090
}
9191

9292
executable, err := os.Executable()
@@ -104,7 +104,7 @@ func TestExec(t *testing.T) {
104104
t.Setenv(agentexec.EnvProcNiceScore, "14")
105105

106106
if runtime.GOOS != "linux" {
107-
t.Skip("skipping on linux")
107+
t.Skip("skipping on non-linux")
108108
}
109109

110110
executable, err := os.Executable()

coderd/coderd.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,8 @@ func New(options *Options) *API {
628628
CurrentVersion: buildinfo.Version(),
629629
CurrentAPIMajorVersion: proto.CurrentMajor,
630630
Store: options.Database,
631-
// TimeNow and StaleInterval set to defaults, see healthcheck/provisioner.go
631+
StaleInterval: provisionerdserver.StaleInterval,
632+
// TimeNow set to default, see healthcheck/provisioner.go
632633
},
633634
})
634635
}

coderd/healthcheck/provisioner.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func (r *ProvisionerDaemonsReport) Run(ctx context.Context, opts *ProvisionerDae
5050
now := opts.TimeNow()
5151

5252
if opts.StaleInterval == 0 {
53-
opts.StaleInterval = provisionerdserver.DefaultHeartbeatInterval * 3
53+
opts.StaleInterval = provisionerdserver.StaleInterval
5454
}
5555

5656
if opts.CurrentVersion == "" {

coderd/healthcheck/provisioner_test.go

+80-26
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,21 @@ import (
1515
"github.com/coder/coder/v2/coderd/database/dbtime"
1616
"github.com/coder/coder/v2/coderd/healthcheck"
1717
"github.com/coder/coder/v2/coderd/healthcheck/health"
18+
"github.com/coder/coder/v2/coderd/provisionerdserver"
1819
"github.com/coder/coder/v2/codersdk"
1920
"github.com/coder/coder/v2/codersdk/healthsdk"
2021
"github.com/coder/coder/v2/provisionerd/proto"
22+
"github.com/coder/coder/v2/testutil"
2123
)
2224

2325
func TestProvisionerDaemonReport(t *testing.T) {
2426
t.Parallel()
2527

26-
now := dbtime.Now()
28+
var (
29+
now = dbtime.Now()
30+
oneHourAgo = now.Add(-time.Hour)
31+
staleThreshold = now.Add(-provisionerdserver.StaleInterval).Add(-time.Second)
32+
)
2733

2834
for _, tt := range []struct {
2935
name string
@@ -65,7 +71,9 @@ func TestProvisionerDaemonReport(t *testing.T) {
6571
currentVersion: "v1.2.3",
6672
currentAPIMajorVersion: proto.CurrentMajor,
6773
expectedSeverity: health.SeverityOK,
68-
provisionerDaemons: []database.ProvisionerDaemon{fakeProvisionerDaemon(t, "pd-ok", "v1.2.3", "1.0", now)},
74+
provisionerDaemons: []database.ProvisionerDaemon{
75+
fakeProvisionerDaemon(t, withName("pd-ok"), withVersion("v1.2.3"), withAPIVersion("1.0"), withCreatedAt(now), withLastSeenAt(now)),
76+
},
6977
expectedItems: []healthsdk.ProvisionerDaemonsReportItem{
7078
{
7179
ProvisionerDaemon: codersdk.ProvisionerDaemon{
@@ -88,7 +96,9 @@ func TestProvisionerDaemonReport(t *testing.T) {
8896
currentAPIMajorVersion: proto.CurrentMajor,
8997
expectedSeverity: health.SeverityWarning,
9098
expectedWarningCode: health.CodeProvisionerDaemonVersionMismatch,
91-
provisionerDaemons: []database.ProvisionerDaemon{fakeProvisionerDaemon(t, "pd-old", "v1.1.2", "1.0", now)},
99+
provisionerDaemons: []database.ProvisionerDaemon{
100+
fakeProvisionerDaemon(t, withName("pd-old"), withVersion("v1.1.2"), withAPIVersion("1.0"), withCreatedAt(now), withLastSeenAt(now)),
101+
},
92102
expectedItems: []healthsdk.ProvisionerDaemonsReportItem{
93103
{
94104
ProvisionerDaemon: codersdk.ProvisionerDaemon{
@@ -116,7 +126,9 @@ func TestProvisionerDaemonReport(t *testing.T) {
116126
currentAPIMajorVersion: proto.CurrentMajor,
117127
expectedSeverity: health.SeverityError,
118128
expectedWarningCode: health.CodeUnknown,
119-
provisionerDaemons: []database.ProvisionerDaemon{fakeProvisionerDaemon(t, "pd-invalid-version", "invalid", "1.0", now)},
129+
provisionerDaemons: []database.ProvisionerDaemon{
130+
fakeProvisionerDaemon(t, withName("pd-invalid-version"), withVersion("invalid"), withAPIVersion("1.0"), withCreatedAt(now), withLastSeenAt(now)),
131+
},
120132
expectedItems: []healthsdk.ProvisionerDaemonsReportItem{
121133
{
122134
ProvisionerDaemon: codersdk.ProvisionerDaemon{
@@ -144,7 +156,9 @@ func TestProvisionerDaemonReport(t *testing.T) {
144156
currentAPIMajorVersion: proto.CurrentMajor,
145157
expectedSeverity: health.SeverityError,
146158
expectedWarningCode: health.CodeUnknown,
147-
provisionerDaemons: []database.ProvisionerDaemon{fakeProvisionerDaemon(t, "pd-invalid-api", "v1.2.3", "invalid", now)},
159+
provisionerDaemons: []database.ProvisionerDaemon{
160+
fakeProvisionerDaemon(t, withName("pd-invalid-api"), withVersion("v1.2.3"), withAPIVersion("invalid"), withCreatedAt(now), withLastSeenAt(now)),
161+
},
148162
expectedItems: []healthsdk.ProvisionerDaemonsReportItem{
149163
{
150164
ProvisionerDaemon: codersdk.ProvisionerDaemon{
@@ -172,7 +186,9 @@ func TestProvisionerDaemonReport(t *testing.T) {
172186
currentAPIMajorVersion: 2,
173187
expectedSeverity: health.SeverityWarning,
174188
expectedWarningCode: health.CodeProvisionerDaemonAPIMajorVersionDeprecated,
175-
provisionerDaemons: []database.ProvisionerDaemon{fakeProvisionerDaemon(t, "pd-old-api", "v2.3.4", "1.0", now)},
189+
provisionerDaemons: []database.ProvisionerDaemon{
190+
fakeProvisionerDaemon(t, withName("pd-old-api"), withVersion("v2.3.4"), withAPIVersion("1.0"), withCreatedAt(now), withLastSeenAt(now)),
191+
},
176192
expectedItems: []healthsdk.ProvisionerDaemonsReportItem{
177193
{
178194
ProvisionerDaemon: codersdk.ProvisionerDaemon{
@@ -200,7 +216,10 @@ func TestProvisionerDaemonReport(t *testing.T) {
200216
currentAPIMajorVersion: proto.CurrentMajor,
201217
expectedSeverity: health.SeverityWarning,
202218
expectedWarningCode: health.CodeProvisionerDaemonVersionMismatch,
203-
provisionerDaemons: []database.ProvisionerDaemon{fakeProvisionerDaemon(t, "pd-ok", "v1.2.3", "1.0", now), fakeProvisionerDaemon(t, "pd-old", "v1.1.2", "1.0", now)},
219+
provisionerDaemons: []database.ProvisionerDaemon{
220+
fakeProvisionerDaemon(t, withName("pd-ok"), withVersion("v1.2.3"), withAPIVersion("1.0"), withCreatedAt(now), withLastSeenAt(now)),
221+
fakeProvisionerDaemon(t, withName("pd-old"), withVersion("v1.1.2"), withAPIVersion("1.0"), withCreatedAt(now), withLastSeenAt(now)),
222+
},
204223
expectedItems: []healthsdk.ProvisionerDaemonsReportItem{
205224
{
206225
ProvisionerDaemon: codersdk.ProvisionerDaemon{
@@ -241,7 +260,10 @@ func TestProvisionerDaemonReport(t *testing.T) {
241260
currentAPIMajorVersion: proto.CurrentMajor,
242261
expectedSeverity: health.SeverityWarning,
243262
expectedWarningCode: health.CodeProvisionerDaemonVersionMismatch,
244-
provisionerDaemons: []database.ProvisionerDaemon{fakeProvisionerDaemon(t, "pd-ok", "v1.2.3", "1.0", now), fakeProvisionerDaemon(t, "pd-new", "v2.3.4", "1.0", now)},
263+
provisionerDaemons: []database.ProvisionerDaemon{
264+
fakeProvisionerDaemon(t, withName("pd-ok"), withVersion("v1.2.3"), withAPIVersion("1.0"), withCreatedAt(now), withLastSeenAt(now)),
265+
fakeProvisionerDaemon(t, withName("pd-new"), withVersion("v2.3.4"), withAPIVersion("1.0"), withCreatedAt(now), withLastSeenAt(now)),
266+
},
245267
expectedItems: []healthsdk.ProvisionerDaemonsReportItem{
246268
{
247269
ProvisionerDaemon: codersdk.ProvisionerDaemon{
@@ -281,7 +303,10 @@ func TestProvisionerDaemonReport(t *testing.T) {
281303
currentVersion: "v2.3.4",
282304
currentAPIMajorVersion: proto.CurrentMajor,
283305
expectedSeverity: health.SeverityOK,
284-
provisionerDaemons: []database.ProvisionerDaemon{fakeProvisionerDaemonStale(t, "pd-stale", "v1.2.3", "0.9", now.Add(-5*time.Minute), now), fakeProvisionerDaemon(t, "pd-ok", "v2.3.4", "1.0", now)},
306+
provisionerDaemons: []database.ProvisionerDaemon{
307+
fakeProvisionerDaemon(t, withName("pd-stale"), withVersion("v1.2.3"), withAPIVersion("0.9"), withCreatedAt(oneHourAgo), withLastSeenAt(staleThreshold)),
308+
fakeProvisionerDaemon(t, withName("pd-ok"), withVersion("v2.3.4"), withAPIVersion("1.0"), withCreatedAt(now), withLastSeenAt(now)),
309+
},
285310
expectedItems: []healthsdk.ProvisionerDaemonsReportItem{
286311
{
287312
ProvisionerDaemon: codersdk.ProvisionerDaemon{
@@ -304,8 +329,10 @@ func TestProvisionerDaemonReport(t *testing.T) {
304329
currentAPIMajorVersion: proto.CurrentMajor,
305330
expectedSeverity: health.SeverityError,
306331
expectedWarningCode: health.CodeProvisionerDaemonsNoProvisionerDaemons,
307-
provisionerDaemons: []database.ProvisionerDaemon{fakeProvisionerDaemonStale(t, "pd-ok", "v1.2.3", "0.9", now.Add(-5*time.Minute), now)},
308-
expectedItems: []healthsdk.ProvisionerDaemonsReportItem{},
332+
provisionerDaemons: []database.ProvisionerDaemon{
333+
fakeProvisionerDaemon(t, withName("pd-stale"), withVersion("v1.2.3"), withAPIVersion("0.9"), withCreatedAt(oneHourAgo), withLastSeenAt(staleThreshold)),
334+
},
335+
expectedItems: []healthsdk.ProvisionerDaemonsReportItem{},
309336
},
310337
} {
311338
tt := tt
@@ -353,25 +380,52 @@ func TestProvisionerDaemonReport(t *testing.T) {
353380
}
354381
}
355382

356-
func fakeProvisionerDaemon(t *testing.T, name, version, apiVersion string, now time.Time) database.ProvisionerDaemon {
383+
func withName(s string) func(*database.ProvisionerDaemon) {
384+
return func(pd *database.ProvisionerDaemon) {
385+
pd.Name = s
386+
}
387+
}
388+
389+
func withCreatedAt(at time.Time) func(*database.ProvisionerDaemon) {
390+
return func(pd *database.ProvisionerDaemon) {
391+
pd.CreatedAt = at
392+
}
393+
}
394+
395+
func withLastSeenAt(at time.Time) func(*database.ProvisionerDaemon) {
396+
return func(pd *database.ProvisionerDaemon) {
397+
pd.LastSeenAt.Valid = true
398+
pd.LastSeenAt.Time = at
399+
}
400+
}
401+
402+
func withVersion(v string) func(*database.ProvisionerDaemon) {
403+
return func(pd *database.ProvisionerDaemon) {
404+
pd.Version = v
405+
}
406+
}
407+
408+
func withAPIVersion(v string) func(*database.ProvisionerDaemon) {
409+
return func(pd *database.ProvisionerDaemon) {
410+
pd.APIVersion = v
411+
}
412+
}
413+
414+
func fakeProvisionerDaemon(t *testing.T, opts ...func(*database.ProvisionerDaemon)) database.ProvisionerDaemon {
357415
t.Helper()
358-
return database.ProvisionerDaemon{
416+
pd := database.ProvisionerDaemon{
359417
ID: uuid.Nil,
360-
Name: name,
361-
CreatedAt: now,
362-
LastSeenAt: sql.NullTime{Time: now, Valid: true},
418+
Name: testutil.GetRandomName(t),
419+
CreatedAt: time.Time{},
420+
LastSeenAt: sql.NullTime{},
363421
Provisioners: []database.ProvisionerType{database.ProvisionerTypeEcho, database.ProvisionerTypeTerraform},
364422
ReplicaID: uuid.NullUUID{},
365423
Tags: map[string]string{},
366-
Version: version,
367-
APIVersion: apiVersion,
424+
Version: "",
425+
APIVersion: "",
368426
}
369-
}
370-
371-
func fakeProvisionerDaemonStale(t *testing.T, name, version, apiVersion string, lastSeenAt, now time.Time) database.ProvisionerDaemon {
372-
t.Helper()
373-
d := fakeProvisionerDaemon(t, name, version, apiVersion, now)
374-
d.LastSeenAt.Valid = true
375-
d.LastSeenAt.Time = lastSeenAt
376-
return d
427+
for _, o := range opts {
428+
o(&pd)
429+
}
430+
return pd
377431
}

coderd/provisionerdserver/provisionerdserver.go

+4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ const (
5757
// DefaultHeartbeatInterval is the interval at which the provisioner daemon
5858
// will update its last seen at timestamp in the database.
5959
DefaultHeartbeatInterval = time.Minute
60+
61+
// StaleInterval is the amount of time after the last heartbeat for which
62+
// the provisioner will be reported as 'stale'.
63+
StaleInterval = 90 * time.Second
6064
)
6165

6266
type Options struct {

coderd/templateversions.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -1515,7 +1515,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
15151515

15161516
// Check for eligible provisioners. This allows us to log a message warning deployment administrators
15171517
// of users submitting jobs for which no provisioners are available.
1518-
matchedProvisioners, err = checkProvisioners(ctx, tx, organization.ID, tags, api.DeploymentValues.Provisioner.DaemonPollInterval.Value())
1518+
matchedProvisioners, err = checkProvisioners(ctx, tx, organization.ID, tags)
15191519
if err != nil {
15201520
api.Logger.Error(ctx, "failed to check eligible provisioner daemons for job", slog.Error(err))
15211521
} else if matchedProvisioners.Count == 0 {
@@ -1823,7 +1823,7 @@ func (api *API) publishTemplateUpdate(ctx context.Context, templateID uuid.UUID)
18231823
}
18241824
}
18251825

1826-
func checkProvisioners(ctx context.Context, store database.Store, orgID uuid.UUID, wantTags map[string]string, pollInterval time.Duration) (codersdk.MatchedProvisioners, error) {
1826+
func checkProvisioners(ctx context.Context, store database.Store, orgID uuid.UUID, wantTags map[string]string) (codersdk.MatchedProvisioners, error) {
18271827
// Check for eligible provisioners. This allows us to return a warning to the user if they
18281828
// submit a job for which no provisioner is available.
18291829
eligibleProvisioners, err := store.GetProvisionerDaemonsByOrganization(ctx, database.GetProvisionerDaemonsByOrganizationParams{
@@ -1835,15 +1835,15 @@ func checkProvisioners(ctx context.Context, store database.Store, orgID uuid.UUI
18351835
return codersdk.MatchedProvisioners{}, xerrors.Errorf("provisioner daemons by organization: %w", err)
18361836
}
18371837

1838-
threePollsAgo := time.Now().Add(-3 * pollInterval)
1838+
staleInterval := time.Now().Add(-provisionerdserver.StaleInterval)
18391839
mostRecentlySeen := codersdk.NullTime{}
18401840
var matched codersdk.MatchedProvisioners
18411841
for _, provisioner := range eligibleProvisioners {
18421842
if !provisioner.LastSeenAt.Valid {
18431843
continue
18441844
}
18451845
matched.Count++
1846-
if provisioner.LastSeenAt.Time.After(threePollsAgo) {
1846+
if provisioner.LastSeenAt.Time.After(staleInterval) {
18471847
matched.Available++
18481848
}
18491849
if provisioner.LastSeenAt.Time.After(mostRecentlySeen.Time) {

0 commit comments

Comments
 (0)