Skip to content

Commit bae5606

Browse files
committed
wire up provisioner daemons healthcheck
1 parent 102816e commit bae5606

File tree

4 files changed

+153
-25
lines changed

4 files changed

+153
-25
lines changed

coderd/coderd.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,13 @@ func New(options *Options) *API {
440440
CurrentVersion: buildinfo.Version(),
441441
WorkspaceProxiesFetchUpdater: *(options.WorkspaceProxiesFetchUpdater).Load(),
442442
},
443+
ProvisionerDaemons: healthcheck.ProvisionerDaemonsReportOptions{
444+
CurrentVersion: buildinfo.Version(),
445+
CurrentAPIVersion: provisionersdk.VersionCurrent,
446+
ProvisionerDaemonsFn: options.Database.GetProvisionerDaemons,
447+
TimeNowFn: dbtime.Now,
448+
StaleInterval: provisionerdserver.DefaultHeartbeatInterval * 3,
449+
},
443450
})
444451
}
445452
}

coderd/healthcheck/healthcheck.go

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type Checker interface {
1818
Websocket(ctx context.Context, opts *WebsocketReportOptions) WebsocketReport
1919
Database(ctx context.Context, opts *DatabaseReportOptions) DatabaseReport
2020
WorkspaceProxy(ctx context.Context, opts *WorkspaceProxyReportOptions) WorkspaceProxyReport
21+
ProvisionerDaemons(ctx context.Context, opts *ProvisionerDaemonsReportOptions) ProvisionerDaemonsReport
2122
}
2223

2324
// @typescript-generate Report
@@ -32,22 +33,24 @@ type Report struct {
3233
// FailingSections is a list of sections that have failed their healthcheck.
3334
FailingSections []codersdk.HealthSection `json:"failing_sections"`
3435

35-
DERP derphealth.Report `json:"derp"`
36-
AccessURL AccessURLReport `json:"access_url"`
37-
Websocket WebsocketReport `json:"websocket"`
38-
Database DatabaseReport `json:"database"`
39-
WorkspaceProxy WorkspaceProxyReport `json:"workspace_proxy"`
36+
DERP derphealth.Report `json:"derp"`
37+
AccessURL AccessURLReport `json:"access_url"`
38+
Websocket WebsocketReport `json:"websocket"`
39+
Database DatabaseReport `json:"database"`
40+
WorkspaceProxy WorkspaceProxyReport `json:"workspace_proxy"`
41+
ProvisionerDaemons ProvisionerDaemonsReport `json:"provisioner_daemon"`
4042

4143
// The Coder version of the server that the report was generated on.
4244
CoderVersion string `json:"coder_version"`
4345
}
4446

4547
type ReportOptions struct {
46-
AccessURL AccessURLReportOptions
47-
Database DatabaseReportOptions
48-
DerpHealth derphealth.ReportOptions
49-
Websocket WebsocketReportOptions
50-
WorkspaceProxy WorkspaceProxyReportOptions
48+
AccessURL AccessURLReportOptions
49+
Database DatabaseReportOptions
50+
DerpHealth derphealth.ReportOptions
51+
Websocket WebsocketReportOptions
52+
WorkspaceProxy WorkspaceProxyReportOptions
53+
ProvisionerDaemons ProvisionerDaemonsReportOptions
5154

5255
Checker Checker
5356
}
@@ -79,6 +82,11 @@ func (defaultChecker) WorkspaceProxy(ctx context.Context, opts *WorkspaceProxyRe
7982
return report
8083
}
8184

85+
func (defaultChecker) ProvisionerDaemons(ctx context.Context, opts *ProvisionerDaemonsReportOptions) (report ProvisionerDaemonsReport) {
86+
report.Run(ctx, opts)
87+
return report
88+
}
89+
8290
func Run(ctx context.Context, opts *ReportOptions) *Report {
8391
var (
8492
wg sync.WaitGroup
@@ -149,26 +157,41 @@ func Run(ctx context.Context, opts *ReportOptions) *Report {
149157
report.WorkspaceProxy = opts.Checker.WorkspaceProxy(ctx, &opts.WorkspaceProxy)
150158
}()
151159

160+
wg.Add(1)
161+
go func() {
162+
defer wg.Done()
163+
defer func() {
164+
if err := recover(); err != nil {
165+
report.ProvisionerDaemons.Error = health.Errorf(health.CodeUnknown, "provisioner daemon report panic: %s", err)
166+
}
167+
}()
168+
169+
report.ProvisionerDaemons = opts.Checker.ProvisionerDaemons(ctx, &opts.ProvisionerDaemons)
170+
}()
171+
152172
report.CoderVersion = buildinfo.Version()
153173
wg.Wait()
154174

155175
report.Time = time.Now()
156176
report.FailingSections = []codersdk.HealthSection{}
157-
if !report.DERP.Healthy {
177+
if report.DERP.Severity.Value() > health.SeverityWarning.Value() {
158178
report.FailingSections = append(report.FailingSections, codersdk.HealthSectionDERP)
159179
}
160-
if !report.AccessURL.Healthy {
180+
if report.AccessURL.Severity.Value() > health.SeverityOK.Value() {
161181
report.FailingSections = append(report.FailingSections, codersdk.HealthSectionAccessURL)
162182
}
163-
if !report.Websocket.Healthy {
183+
if report.Websocket.Severity.Value() > health.SeverityWarning.Value() {
164184
report.FailingSections = append(report.FailingSections, codersdk.HealthSectionWebsocket)
165185
}
166-
if !report.Database.Healthy {
186+
if report.Database.Severity.Value() > health.SeverityWarning.Value() {
167187
report.FailingSections = append(report.FailingSections, codersdk.HealthSectionDatabase)
168188
}
169-
if !report.WorkspaceProxy.Healthy {
189+
if report.WorkspaceProxy.Severity.Value() > health.SeverityWarning.Value() {
170190
report.FailingSections = append(report.FailingSections, codersdk.HealthSectionWorkspaceProxy)
171191
}
192+
if report.ProvisionerDaemons.Severity.Value() > health.SeverityWarning.Value() {
193+
report.FailingSections = append(report.FailingSections, codersdk.HealthSectionProvisionerDaemons)
194+
}
172195

173196
report.Healthy = len(report.FailingSections) == 0
174197

@@ -190,6 +213,9 @@ func Run(ctx context.Context, opts *ReportOptions) *Report {
190213
if report.WorkspaceProxy.Severity.Value() > report.Severity.Value() {
191214
report.Severity = report.WorkspaceProxy.Severity
192215
}
216+
if report.ProvisionerDaemons.Severity.Value() > report.Severity.Value() {
217+
report.Severity = report.ProvisionerDaemons.Severity
218+
}
193219
return &report
194220
}
195221

coderd/healthcheck/healthcheck_test.go

Lines changed: 99 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ import (
1313
)
1414

1515
type testChecker struct {
16-
DERPReport derphealth.Report
17-
AccessURLReport healthcheck.AccessURLReport
18-
WebsocketReport healthcheck.WebsocketReport
19-
DatabaseReport healthcheck.DatabaseReport
20-
WorkspaceProxyReport healthcheck.WorkspaceProxyReport
16+
DERPReport derphealth.Report
17+
AccessURLReport healthcheck.AccessURLReport
18+
WebsocketReport healthcheck.WebsocketReport
19+
DatabaseReport healthcheck.DatabaseReport
20+
WorkspaceProxyReport healthcheck.WorkspaceProxyReport
21+
ProvisionerDaemonsReport healthcheck.ProvisionerDaemonsReport
2122
}
2223

2324
func (c *testChecker) DERP(context.Context, *derphealth.ReportOptions) derphealth.Report {
@@ -40,6 +41,10 @@ func (c *testChecker) WorkspaceProxy(context.Context, *healthcheck.WorkspaceProx
4041
return c.WorkspaceProxyReport
4142
}
4243

44+
func (c *testChecker) ProvisionerDaemons(context.Context, *healthcheck.ProvisionerDaemonsReportOptions) healthcheck.ProvisionerDaemonsReport {
45+
return c.ProvisionerDaemonsReport
46+
}
47+
4348
func TestHealthcheck(t *testing.T) {
4449
t.Parallel()
4550

@@ -72,6 +77,9 @@ func TestHealthcheck(t *testing.T) {
7277
Healthy: true,
7378
Severity: health.SeverityOK,
7479
},
80+
ProvisionerDaemonsReport: healthcheck.ProvisionerDaemonsReport{
81+
Severity: health.SeverityOK,
82+
},
7583
},
7684
healthy: true,
7785
severity: health.SeverityOK,
@@ -99,6 +107,9 @@ func TestHealthcheck(t *testing.T) {
99107
Healthy: true,
100108
Severity: health.SeverityOK,
101109
},
110+
ProvisionerDaemonsReport: healthcheck.ProvisionerDaemonsReport{
111+
Severity: health.SeverityOK,
112+
},
102113
},
103114
healthy: false,
104115
severity: health.SeverityError,
@@ -127,6 +138,9 @@ func TestHealthcheck(t *testing.T) {
127138
Healthy: true,
128139
Severity: health.SeverityOK,
129140
},
141+
ProvisionerDaemonsReport: healthcheck.ProvisionerDaemonsReport{
142+
Severity: health.SeverityOK,
143+
},
130144
},
131145
healthy: true,
132146
severity: health.SeverityWarning,
@@ -154,6 +168,9 @@ func TestHealthcheck(t *testing.T) {
154168
Healthy: true,
155169
Severity: health.SeverityOK,
156170
},
171+
ProvisionerDaemonsReport: healthcheck.ProvisionerDaemonsReport{
172+
Severity: health.SeverityOK,
173+
},
157174
},
158175
healthy: false,
159176
severity: health.SeverityWarning,
@@ -181,6 +198,9 @@ func TestHealthcheck(t *testing.T) {
181198
Healthy: true,
182199
Severity: health.SeverityOK,
183200
},
201+
ProvisionerDaemonsReport: healthcheck.ProvisionerDaemonsReport{
202+
Severity: health.SeverityOK,
203+
},
184204
},
185205
healthy: false,
186206
severity: health.SeverityError,
@@ -208,6 +228,9 @@ func TestHealthcheck(t *testing.T) {
208228
Healthy: true,
209229
Severity: health.SeverityOK,
210230
},
231+
ProvisionerDaemonsReport: healthcheck.ProvisionerDaemonsReport{
232+
Severity: health.SeverityOK,
233+
},
211234
},
212235
healthy: false,
213236
severity: health.SeverityError,
@@ -235,6 +258,9 @@ func TestHealthcheck(t *testing.T) {
235258
Healthy: false,
236259
Severity: health.SeverityError,
237260
},
261+
ProvisionerDaemonsReport: healthcheck.ProvisionerDaemonsReport{
262+
Severity: health.SeverityOK,
263+
},
238264
},
239265
severity: health.SeverityError,
240266
healthy: false,
@@ -263,6 +289,70 @@ func TestHealthcheck(t *testing.T) {
263289
Warnings: []health.Message{{Message: "foobar", Code: "EFOOBAR"}},
264290
Severity: health.SeverityWarning,
265291
},
292+
ProvisionerDaemonsReport: healthcheck.ProvisionerDaemonsReport{
293+
Severity: health.SeverityOK,
294+
},
295+
},
296+
severity: health.SeverityWarning,
297+
healthy: true,
298+
failingSections: []codersdk.HealthSection{},
299+
}, {
300+
name: "ProvisionerDaemonsFail",
301+
checker: &testChecker{
302+
DERPReport: derphealth.Report{
303+
Healthy: true,
304+
Severity: health.SeverityOK,
305+
},
306+
AccessURLReport: healthcheck.AccessURLReport{
307+
Healthy: true,
308+
Severity: health.SeverityOK,
309+
},
310+
WebsocketReport: healthcheck.WebsocketReport{
311+
Healthy: true,
312+
Severity: health.SeverityOK,
313+
},
314+
DatabaseReport: healthcheck.DatabaseReport{
315+
Healthy: true,
316+
Severity: health.SeverityOK,
317+
},
318+
WorkspaceProxyReport: healthcheck.WorkspaceProxyReport{
319+
Healthy: true,
320+
Severity: health.SeverityOK,
321+
},
322+
ProvisionerDaemonsReport: healthcheck.ProvisionerDaemonsReport{
323+
Severity: health.SeverityError,
324+
},
325+
},
326+
severity: health.SeverityError,
327+
healthy: false,
328+
failingSections: []codersdk.HealthSection{codersdk.HealthSectionProvisionerDaemons},
329+
}, {
330+
name: "ProvisionerDaemonsWarn",
331+
checker: &testChecker{
332+
DERPReport: derphealth.Report{
333+
Healthy: true,
334+
Severity: health.SeverityOK,
335+
},
336+
AccessURLReport: healthcheck.AccessURLReport{
337+
Healthy: true,
338+
Severity: health.SeverityOK,
339+
},
340+
WebsocketReport: healthcheck.WebsocketReport{
341+
Healthy: true,
342+
Severity: health.SeverityOK,
343+
},
344+
DatabaseReport: healthcheck.DatabaseReport{
345+
Healthy: true,
346+
Severity: health.SeverityOK,
347+
},
348+
WorkspaceProxyReport: healthcheck.WorkspaceProxyReport{
349+
Healthy: true,
350+
Severity: health.SeverityOK,
351+
},
352+
ProvisionerDaemonsReport: healthcheck.ProvisionerDaemonsReport{
353+
Severity: health.SeverityWarning,
354+
Warnings: []health.Message{{Message: "foobar", Code: "EFOOBAR"}},
355+
},
266356
},
267357
severity: health.SeverityWarning,
268358
healthy: true,
@@ -291,6 +381,9 @@ func TestHealthcheck(t *testing.T) {
291381
Healthy: false,
292382
Severity: health.SeverityError,
293383
},
384+
ProvisionerDaemonsReport: healthcheck.ProvisionerDaemonsReport{
385+
Severity: health.SeverityError,
386+
},
294387
},
295388
severity: health.SeverityError,
296389
failingSections: []codersdk.HealthSection{
@@ -299,6 +392,7 @@ func TestHealthcheck(t *testing.T) {
299392
codersdk.HealthSectionWebsocket,
300393
codersdk.HealthSectionDatabase,
301394
codersdk.HealthSectionWorkspaceProxy,
395+
codersdk.HealthSectionProvisionerDaemons,
302396
},
303397
}} {
304398
c := c

codersdk/health.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ type HealthSection string
1212

1313
// If you add another const below, make sure to add it to HealthSections!
1414
const (
15-
HealthSectionDERP HealthSection = "DERP"
16-
HealthSectionAccessURL HealthSection = "AccessURL"
17-
HealthSectionWebsocket HealthSection = "Websocket"
18-
HealthSectionDatabase HealthSection = "Database"
19-
HealthSectionWorkspaceProxy HealthSection = "WorkspaceProxy"
15+
HealthSectionDERP HealthSection = "DERP"
16+
HealthSectionAccessURL HealthSection = "AccessURL"
17+
HealthSectionWebsocket HealthSection = "Websocket"
18+
HealthSectionDatabase HealthSection = "Database"
19+
HealthSectionWorkspaceProxy HealthSection = "WorkspaceProxy"
20+
HealthSectionProvisionerDaemons HealthSection = "ProvisionerDaemons"
2021
)
2122

2223
var HealthSections = []HealthSection{

0 commit comments

Comments
 (0)