Skip to content

Commit bd376c4

Browse files
committed
better handle stale daemons
1 parent e058a05 commit bd376c4

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

coderd/healthcheck/provisioner.go

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/coder/coder/v2/coderd/database"
1111
"github.com/coder/coder/v2/coderd/database/db2sdk"
1212
"github.com/coder/coder/v2/coderd/database/dbauthz"
13+
"github.com/coder/coder/v2/coderd/database/dbtime"
1314
"github.com/coder/coder/v2/coderd/healthcheck/health"
1415
"github.com/coder/coder/v2/coderd/provisionerdserver"
1516
"github.com/coder/coder/v2/coderd/util/apiversion"
@@ -29,13 +30,14 @@ type ProvisionerDaemonsReport struct {
2930
}
3031

3132
type ProvisionerDaemonsReportDeps struct {
33+
// Required
3234
CurrentVersion string
3335
CurrentAPIMajorVersion int
36+
Store ProvisionerDaemonsStore
3437

35-
Store ProvisionerDaemonsStore
36-
37-
TimeNowFn func() time.Time
38-
StaleInterval time.Duration
38+
// Optional
39+
TimeNowFn func() time.Time // Defaults to dbtime.Now
40+
StaleInterval time.Duration // Defaults to 3 heartbeats
3941

4042
Dismissed bool
4143
}
@@ -49,7 +51,12 @@ func (r *ProvisionerDaemonsReport) Run(ctx context.Context, opts *ProvisionerDae
4951
r.Severity = health.SeverityOK
5052
r.Warnings = make([]health.Message, 0)
5153
r.Dismissed = opts.Dismissed
54+
55+
if opts.TimeNowFn == nil {
56+
opts.TimeNowFn = dbtime.Now
57+
}
5258
now := opts.TimeNowFn()
59+
5360
if opts.StaleInterval == 0 {
5461
opts.StaleInterval = provisionerdserver.DefaultHeartbeatInterval * 3
5562
}
@@ -79,17 +86,6 @@ func (r *ProvisionerDaemonsReport) Run(ctx context.Context, opts *ProvisionerDae
7986
r.Error = ptr.Ref("error fetching provisioner daemons: " + err.Error())
8087
return
8188
}
82-
83-
for _, daemon := range daemons {
84-
r.ProvisionerDaemons = append(r.ProvisionerDaemons, db2sdk.ProvisionerDaemon(daemon))
85-
}
86-
87-
if len(r.ProvisionerDaemons) == 0 {
88-
r.Severity = health.SeverityError
89-
r.Error = ptr.Ref("No provisioner daemons found!")
90-
return
91-
}
92-
9389
for _, daemon := range daemons {
9490
// Daemon never connected, skip.
9591
if !daemon.LastSeenAt.Valid {
@@ -99,6 +95,9 @@ func (r *ProvisionerDaemonsReport) Run(ctx context.Context, opts *ProvisionerDae
9995
if now.Sub(daemon.LastSeenAt.Time) > (opts.StaleInterval) {
10096
continue
10197
}
98+
99+
r.ProvisionerDaemons = append(r.ProvisionerDaemons, db2sdk.ProvisionerDaemon(daemon))
100+
102101
// For release versions, just check MAJOR.MINOR and ignore patch.
103102
if !semver.IsValid(daemon.Version) {
104103
if r.Severity.Value() < health.SeverityError.Value() {
@@ -128,4 +127,10 @@ func (r *ProvisionerDaemonsReport) Run(ctx context.Context, opts *ProvisionerDae
128127
r.Warnings = append(r.Warnings, health.Messagef(health.CodeProvisionerDaemonAPIMajorVersionDeprecated, "Provisioner daemon %q reports deprecated major API version %d. Consider upgrading!", daemon.Name, provisionersdk.CurrentMajor))
129128
}
130129
}
130+
131+
if len(r.ProvisionerDaemons) == 0 {
132+
r.Severity = health.SeverityError
133+
r.Error = ptr.Ref("No active provisioner daemons found!")
134+
return
135+
}
131136
}

coderd/healthcheck/provisioner_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func TestProvisionerDaemonReport(t *testing.T) {
4343
currentVersion: "v1.2.3",
4444
currentAPIMajorVersion: provisionersdk.CurrentMajor,
4545
expectedSeverity: health.SeverityError,
46-
expectedError: "No provisioner daemons found!",
46+
expectedError: "No active provisioner daemons found!",
4747
},
4848
{
4949
name: "error fetching daemons",
@@ -115,6 +115,14 @@ func TestProvisionerDaemonReport(t *testing.T) {
115115
expectedSeverity: health.SeverityOK,
116116
provisionerDaemons: []database.ProvisionerDaemon{fakeProvisionerDaemonStale(t, "pd-ok", "v1.2.3", "0.9", dbtime.Now().Add(-5*time.Minute)), fakeProvisionerDaemon(t, "pd-new", "v2.3.4", "1.0")},
117117
},
118+
{
119+
name: "one stale",
120+
currentVersion: "v2.3.4",
121+
currentAPIMajorVersion: provisionersdk.CurrentMajor,
122+
expectedSeverity: health.SeverityError,
123+
expectedError: "No active provisioner daemons found!",
124+
provisionerDaemons: []database.ProvisionerDaemon{fakeProvisionerDaemonStale(t, "pd-ok", "v1.2.3", "0.9", dbtime.Now().Add(-5*time.Minute))},
125+
},
118126
} {
119127
tt := tt
120128
t.Run(tt.name, func(t *testing.T) {

0 commit comments

Comments
 (0)