Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit411ce46

Browse files
authored
feat(coderd/healthcheck): add health check for proxy (#10846)
Adds a health check for workspace proxies:- Healthy iff all proxies are healthy and the same version,- Warning if some proxies are unhealthy,- Error if all proxies are unhealthy, or do not all have the same version.
1 parentb501046 commit411ce46

File tree

15 files changed

+865
-35
lines changed

15 files changed

+865
-35
lines changed

‎coderd/apidoc/docs.go

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/apidoc/swagger.json

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/coderd.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,12 @@ type Options struct {
135135
AccessControlStore*atomic.Pointer[dbauthz.AccessControlStore]
136136
// AppSecurityKey is the crypto key used to sign and encrypt tokens related to
137137
// workspace applications. It consists of both a signing and encryption key.
138-
AppSecurityKey workspaceapps.SecurityKey
139-
HealthcheckFuncfunc(ctx context.Context,apiKeystring)*healthcheck.Report
140-
HealthcheckTimeout time.Duration
141-
HealthcheckRefresh time.Duration
138+
AppSecurityKey workspaceapps.SecurityKey
139+
140+
HealthcheckFuncfunc(ctx context.Context,apiKeystring)*healthcheck.Report
141+
HealthcheckTimeout time.Duration
142+
HealthcheckRefresh time.Duration
143+
WorkspaceProxiesFetchUpdater*atomic.Pointer[healthcheck.WorkspaceProxiesFetchUpdater]
142144

143145
// OAuthSigningKey is the crypto key used to sign and encrypt state strings
144146
// related to OAuth. This is a symmetric secret key using hmac to sign payloads.
@@ -396,6 +398,13 @@ func New(options *Options) *API {
396398
*options.UpdateCheckOptions,
397399
)
398400
}
401+
402+
ifoptions.WorkspaceProxiesFetchUpdater==nil {
403+
options.WorkspaceProxiesFetchUpdater=&atomic.Pointer[healthcheck.WorkspaceProxiesFetchUpdater]{}
404+
varwpfu healthcheck.WorkspaceProxiesFetchUpdater=&healthcheck.AGPLWorkspaceProxiesFetchUpdater{}
405+
options.WorkspaceProxiesFetchUpdater.Store(&wpfu)
406+
}
407+
399408
ifoptions.HealthcheckFunc==nil {
400409
options.HealthcheckFunc=func(ctx context.Context,apiKeystring)*healthcheck.Report {
401410
returnhealthcheck.Run(ctx,&healthcheck.ReportOptions{
@@ -413,9 +422,14 @@ func New(options *Options) *API {
413422
DerpHealth: derphealth.ReportOptions{
414423
DERPMap:api.DERPMap(),
415424
},
425+
WorkspaceProxy: healthcheck.WorkspaceProxyReportOptions{
426+
CurrentVersion:buildinfo.Version(),
427+
WorkspaceProxiesFetchUpdater:*(options.WorkspaceProxiesFetchUpdater).Load(),
428+
},
416429
})
417430
}
418431
}
432+
419433
ifoptions.HealthcheckTimeout==0 {
420434
options.HealthcheckTimeout=30*time.Second
421435
}

‎coderd/healthcheck/healthcheck.go

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,19 @@ import (
1313
)
1414

1515
const (
16-
SectionDERPstring="DERP"
17-
SectionAccessURLstring="AccessURL"
18-
SectionWebsocketstring="Websocket"
19-
SectionDatabasestring="Database"
16+
SectionDERPstring="DERP"
17+
SectionAccessURLstring="AccessURL"
18+
SectionWebsocketstring="Websocket"
19+
SectionDatabasestring="Database"
20+
SectionWorkspaceProxystring="WorkspaceProxy"
2021
)
2122

2223
typeCheckerinterface {
2324
DERP(ctx context.Context,opts*derphealth.ReportOptions) derphealth.Report
2425
AccessURL(ctx context.Context,opts*AccessURLReportOptions)AccessURLReport
2526
Websocket(ctx context.Context,opts*WebsocketReportOptions)WebsocketReport
2627
Database(ctx context.Context,opts*DatabaseReportOptions)DatabaseReport
28+
WorkspaceProxy(ctx context.Context,opts*WorkspaceProxyReportOptions)WorkspaceProxyReport
2729
}
2830

2931
// @typescript-generate Report
@@ -38,20 +40,22 @@ type Report struct {
3840
// FailingSections is a list of sections that have failed their healthcheck.
3941
FailingSections []string`json:"failing_sections"`
4042

41-
DERP derphealth.Report`json:"derp"`
42-
AccessURLAccessURLReport`json:"access_url"`
43-
WebsocketWebsocketReport`json:"websocket"`
44-
DatabaseDatabaseReport`json:"database"`
43+
DERP derphealth.Report`json:"derp"`
44+
AccessURLAccessURLReport`json:"access_url"`
45+
WebsocketWebsocketReport`json:"websocket"`
46+
DatabaseDatabaseReport`json:"database"`
47+
WorkspaceProxyWorkspaceProxyReport`json:"workspace_proxy"`
4548

4649
// The Coder version of the server that the report was generated on.
4750
CoderVersionstring`json:"coder_version"`
4851
}
4952

5053
typeReportOptionsstruct {
51-
AccessURLAccessURLReportOptions
52-
DatabaseDatabaseReportOptions
53-
DerpHealth derphealth.ReportOptions
54-
WebsocketWebsocketReportOptions
54+
AccessURLAccessURLReportOptions
55+
DatabaseDatabaseReportOptions
56+
DerpHealth derphealth.ReportOptions
57+
WebsocketWebsocketReportOptions
58+
WorkspaceProxyWorkspaceProxyReportOptions
5559

5660
CheckerChecker
5761
}
@@ -78,6 +82,11 @@ func (defaultChecker) Database(ctx context.Context, opts *DatabaseReportOptions)
7882
returnreport
7983
}
8084

85+
func (defaultChecker)WorkspaceProxy(ctx context.Context,opts*WorkspaceProxyReportOptions) (reportWorkspaceProxyReport) {
86+
report.Run(ctx,opts)
87+
returnreport
88+
}
89+
8190
funcRun(ctx context.Context,opts*ReportOptions)*Report {
8291
var (
8392
wg sync.WaitGroup
@@ -136,6 +145,18 @@ func Run(ctx context.Context, opts *ReportOptions) *Report {
136145
report.Database=opts.Checker.Database(ctx,&opts.Database)
137146
}()
138147

148+
wg.Add(1)
149+
gofunc() {
150+
deferwg.Done()
151+
deferfunc() {
152+
iferr:=recover();err!=nil {
153+
report.WorkspaceProxy.Error=ptr.Ref(fmt.Sprint(err))
154+
}
155+
}()
156+
157+
report.WorkspaceProxy=opts.Checker.WorkspaceProxy(ctx,&opts.WorkspaceProxy)
158+
}()
159+
139160
report.CoderVersion=buildinfo.Version()
140161
wg.Wait()
141162

@@ -153,6 +174,9 @@ func Run(ctx context.Context, opts *ReportOptions) *Report {
153174
if!report.Database.Healthy {
154175
report.FailingSections=append(report.FailingSections,SectionDatabase)
155176
}
177+
if!report.WorkspaceProxy.Healthy {
178+
report.FailingSections=append(report.FailingSections,SectionWorkspaceProxy)
179+
}
156180

157181
report.Healthy=len(report.FailingSections)==0
158182

@@ -171,6 +195,9 @@ func Run(ctx context.Context, opts *ReportOptions) *Report {
171195
ifreport.Database.Severity.Value()>report.Severity.Value() {
172196
report.Severity=report.Database.Severity
173197
}
198+
ifreport.WorkspaceProxy.Severity.Value()>report.Severity.Value() {
199+
report.Severity=report.WorkspaceProxy.Severity
200+
}
174201
return&report
175202
}
176203

‎coderd/healthcheck/healthcheck_test.go

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ import (
1212
)
1313

1414
typetestCheckerstruct {
15-
DERPReport derphealth.Report
16-
AccessURLReport healthcheck.AccessURLReport
17-
WebsocketReport healthcheck.WebsocketReport
18-
DatabaseReport healthcheck.DatabaseReport
15+
DERPReport derphealth.Report
16+
AccessURLReport healthcheck.AccessURLReport
17+
WebsocketReport healthcheck.WebsocketReport
18+
DatabaseReport healthcheck.DatabaseReport
19+
WorkspaceProxyReport healthcheck.WorkspaceProxyReport
1920
}
2021

2122
func (c*testChecker)DERP(context.Context,*derphealth.ReportOptions) derphealth.Report {
@@ -34,6 +35,10 @@ func (c *testChecker) Database(context.Context, *healthcheck.DatabaseReportOptio
3435
returnc.DatabaseReport
3536
}
3637

38+
func (c*testChecker)WorkspaceProxy(context.Context,*healthcheck.WorkspaceProxyReportOptions) healthcheck.WorkspaceProxyReport {
39+
returnc.WorkspaceProxyReport
40+
}
41+
3742
funcTestHealthcheck(t*testing.T) {
3843
t.Parallel()
3944

@@ -62,6 +67,10 @@ func TestHealthcheck(t *testing.T) {
6267
Healthy:true,
6368
Severity:health.SeverityOK,
6469
},
70+
WorkspaceProxyReport: healthcheck.WorkspaceProxyReport{
71+
Healthy:true,
72+
Severity:health.SeverityOK,
73+
},
6574
},
6675
healthy:true,
6776
severity:health.SeverityOK,
@@ -85,6 +94,10 @@ func TestHealthcheck(t *testing.T) {
8594
Healthy:true,
8695
Severity:health.SeverityOK,
8796
},
97+
WorkspaceProxyReport: healthcheck.WorkspaceProxyReport{
98+
Healthy:true,
99+
Severity:health.SeverityOK,
100+
},
88101
},
89102
healthy:false,
90103
severity:health.SeverityError,
@@ -109,6 +122,10 @@ func TestHealthcheck(t *testing.T) {
109122
Healthy:true,
110123
Severity:health.SeverityOK,
111124
},
125+
WorkspaceProxyReport: healthcheck.WorkspaceProxyReport{
126+
Healthy:true,
127+
Severity:health.SeverityOK,
128+
},
112129
},
113130
healthy:true,
114131
severity:health.SeverityWarning,
@@ -132,6 +149,10 @@ func TestHealthcheck(t *testing.T) {
132149
Healthy:true,
133150
Severity:health.SeverityOK,
134151
},
152+
WorkspaceProxyReport: healthcheck.WorkspaceProxyReport{
153+
Healthy:true,
154+
Severity:health.SeverityOK,
155+
},
135156
},
136157
healthy:false,
137158
severity:health.SeverityWarning,
@@ -155,6 +176,10 @@ func TestHealthcheck(t *testing.T) {
155176
Healthy:true,
156177
Severity:health.SeverityOK,
157178
},
179+
WorkspaceProxyReport: healthcheck.WorkspaceProxyReport{
180+
Healthy:true,
181+
Severity:health.SeverityOK,
182+
},
158183
},
159184
healthy:false,
160185
severity:health.SeverityError,
@@ -178,12 +203,44 @@ func TestHealthcheck(t *testing.T) {
178203
Healthy:false,
179204
Severity:health.SeverityError,
180205
},
206+
WorkspaceProxyReport: healthcheck.WorkspaceProxyReport{
207+
Healthy:true,
208+
Severity:health.SeverityOK,
209+
},
181210
},
182211
healthy:false,
183212
severity:health.SeverityError,
184213
failingSections: []string{healthcheck.SectionDatabase},
185214
}, {
186-
name:"AllFail",
215+
name:"ProxyFail",
216+
checker:&testChecker{
217+
DERPReport: derphealth.Report{
218+
Healthy:true,
219+
Severity:health.SeverityOK,
220+
},
221+
AccessURLReport: healthcheck.AccessURLReport{
222+
Healthy:true,
223+
Severity:health.SeverityOK,
224+
},
225+
WebsocketReport: healthcheck.WebsocketReport{
226+
Healthy:true,
227+
Severity:health.SeverityOK,
228+
},
229+
DatabaseReport: healthcheck.DatabaseReport{
230+
Healthy:true,
231+
Severity:health.SeverityOK,
232+
},
233+
WorkspaceProxyReport: healthcheck.WorkspaceProxyReport{
234+
Healthy:false,
235+
Severity:health.SeverityError,
236+
},
237+
},
238+
severity:health.SeverityError,
239+
healthy:false,
240+
failingSections: []string{healthcheck.SectionWorkspaceProxy},
241+
}, {
242+
name:"AllFail",
243+
healthy:false,
187244
checker:&testChecker{
188245
DERPReport: derphealth.Report{
189246
Healthy:false,
@@ -201,14 +258,18 @@ func TestHealthcheck(t *testing.T) {
201258
Healthy:false,
202259
Severity:health.SeverityError,
203260
},
261+
WorkspaceProxyReport: healthcheck.WorkspaceProxyReport{
262+
Healthy:false,
263+
Severity:health.SeverityError,
264+
},
204265
},
205-
healthy:false,
206266
severity:health.SeverityError,
207267
failingSections: []string{
208268
healthcheck.SectionDERP,
209269
healthcheck.SectionAccessURL,
210270
healthcheck.SectionWebsocket,
211271
healthcheck.SectionDatabase,
272+
healthcheck.SectionWorkspaceProxy,
212273
},
213274
}} {
214275
c:=c
@@ -228,6 +289,8 @@ func TestHealthcheck(t *testing.T) {
228289
assert.Equal(t,c.checker.AccessURLReport.Healthy,report.AccessURL.Healthy)
229290
assert.Equal(t,c.checker.AccessURLReport.Severity,report.AccessURL.Severity)
230291
assert.Equal(t,c.checker.WebsocketReport.Healthy,report.Websocket.Healthy)
292+
assert.Equal(t,c.checker.WorkspaceProxyReport.Healthy,report.WorkspaceProxy.Healthy)
293+
assert.Equal(t,c.checker.WorkspaceProxyReport.Warnings,report.WorkspaceProxy.Warnings)
231294
assert.Equal(t,c.checker.WebsocketReport.Severity,report.Websocket.Severity)
232295
assert.Equal(t,c.checker.DatabaseReport.Healthy,report.Database.Healthy)
233296
assert.Equal(t,c.checker.DatabaseReport.Severity,report.Database.Severity)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp