Skip to content

Commit bb5aa3e

Browse files
committed
add healthcheck type
1 parent 1947adc commit bb5aa3e

File tree

10 files changed

+378
-291
lines changed

10 files changed

+378
-291
lines changed

agent/apphealth.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func NewWorkspaceAppHealthReporter(logger slog.Logger, client *codersdk.Client)
4040
tickers := make(chan string)
4141
for _, app := range apps {
4242
if shouldStartTicker(app) {
43-
t := time.NewTicker(time.Duration(app.HealthcheckInterval) * time.Second)
43+
t := time.NewTicker(time.Duration(app.Healthcheck.Interval) * time.Second)
4444
go func() {
4545
for {
4646
select {
@@ -67,10 +67,10 @@ func NewWorkspaceAppHealthReporter(logger slog.Logger, client *codersdk.Client)
6767
}
6868

6969
client := &http.Client{
70-
Timeout: time.Duration(app.HealthcheckInterval),
70+
Timeout: time.Duration(app.Healthcheck.Interval),
7171
}
7272
err := func() error {
73-
req, err := http.NewRequestWithContext(ctx, http.MethodGet, app.HealthcheckURL, nil)
73+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, app.Healthcheck.URL, nil)
7474
if err != nil {
7575
return err
7676
}
@@ -88,7 +88,7 @@ func NewWorkspaceAppHealthReporter(logger slog.Logger, client *codersdk.Client)
8888
if err == nil {
8989
mu.Lock()
9090
failures[app.Name]++
91-
if failures[app.Name] > int(app.HealthcheckThreshold) {
91+
if failures[app.Name] > int(app.Healthcheck.Threshold) {
9292
health[app.Name] = codersdk.WorkspaceAppHealthUnhealthy
9393
}
9494
mu.Unlock()
@@ -139,7 +139,7 @@ func NewWorkspaceAppHealthReporter(logger slog.Logger, client *codersdk.Client)
139139
}
140140

141141
func shouldStartTicker(app codersdk.WorkspaceApp) bool {
142-
return app.HealthcheckURL != "" && app.HealthcheckInterval > 0 && app.HealthcheckThreshold > 0
142+
return app.Healthcheck.URL != "" && app.Healthcheck.Interval > 0 && app.Healthcheck.Threshold > 0
143143
}
144144

145145
func healthChanged(old map[string]codersdk.WorkspaceAppHealth, new map[string]codersdk.WorkspaceAppHealth) bool {

coderd/provisionerdaemons.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,10 @@ func insertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
813813

814814
for _, app := range prAgent.Apps {
815815
health := database.WorkspaceAppHealthDisabled
816-
if app.HealthcheckUrl != "" {
816+
if app.Healthcheck == nil {
817+
app.Healthcheck = &sdkproto.Healthcheck{}
818+
}
819+
if app.Healthcheck.Url != "" {
817820
health = database.WorkspaceAppHealthInitializing
818821
}
819822

@@ -832,9 +835,9 @@ func insertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
832835
Valid: app.Url != "",
833836
},
834837
RelativePath: app.RelativePath,
835-
HealthcheckUrl: app.HealthcheckUrl,
836-
HealthcheckInterval: app.HealthcheckInterval,
837-
HealthcheckThreshold: app.HealthcheckThreshold,
838+
HealthcheckUrl: app.Healthcheck.Url,
839+
HealthcheckInterval: app.Healthcheck.Interval,
840+
HealthcheckThreshold: app.Healthcheck.Threshold,
838841
Health: health,
839842
})
840843
if err != nil {

coderd/workspaceagents.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -448,14 +448,16 @@ func convertApps(dbApps []database.WorkspaceApp) []codersdk.WorkspaceApp {
448448
apps := make([]codersdk.WorkspaceApp, 0)
449449
for _, dbApp := range dbApps {
450450
apps = append(apps, codersdk.WorkspaceApp{
451-
ID: dbApp.ID,
452-
Name: dbApp.Name,
453-
Command: dbApp.Command.String,
454-
Icon: dbApp.Icon,
455-
HealthcheckURL: dbApp.HealthcheckUrl,
456-
HealthcheckInterval: dbApp.HealthcheckInterval,
457-
HealthcheckThreshold: dbApp.HealthcheckThreshold,
458-
Health: codersdk.WorkspaceAppHealth(dbApp.Health),
451+
ID: dbApp.ID,
452+
Name: dbApp.Name,
453+
Command: dbApp.Command.String,
454+
Icon: dbApp.Icon,
455+
Healthcheck: codersdk.Healthcheck{
456+
URL: dbApp.HealthcheckUrl,
457+
Interval: dbApp.HealthcheckInterval,
458+
Threshold: dbApp.HealthcheckThreshold,
459+
},
460+
Health: codersdk.WorkspaceAppHealth(dbApp.Health),
459461
})
460462
}
461463
return apps

coderd/workspaceagents_test.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -379,13 +379,15 @@ func TestWorkspaceAgentAppHealth(t *testing.T) {
379379
Icon: "/code.svg",
380380
},
381381
{
382-
Name: "code-server-2",
383-
Command: "some-command",
384-
Url: "http://localhost:3000",
385-
Icon: "/code.svg",
386-
HealthcheckUrl: "http://localhost:3000",
387-
HealthcheckInterval: 5,
388-
HealthcheckThreshold: 6,
382+
Name: "code-server-2",
383+
Command: "some-command",
384+
Url: "http://localhost:3000",
385+
Icon: "/code.svg",
386+
Healthcheck: &proto.Healthcheck{
387+
Url: "http://localhost:3000",
388+
Interval: 5,
389+
Threshold: 6,
390+
},
389391
},
390392
}
391393
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{

coderd/workspaceresources_test.go

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,15 @@ func TestWorkspaceResource(t *testing.T) {
8282
Icon: "/code.svg",
8383
},
8484
{
85-
Name: "code-server-2",
86-
Command: "some-command",
87-
Url: "http://localhost:3000",
88-
Icon: "/code.svg",
89-
HealthcheckUrl: "http://localhost:3000",
90-
HealthcheckInterval: 5,
91-
HealthcheckThreshold: 6,
85+
Name: "code-server-2",
86+
Command: "some-command",
87+
Url: "http://localhost:3000",
88+
Icon: "/code.svg",
89+
Healthcheck: &proto.Healthcheck{
90+
Url: "http://localhost:3000",
91+
Interval: 5,
92+
Threshold: 6,
93+
},
9294
},
9395
}
9496
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
@@ -130,18 +132,18 @@ func TestWorkspaceResource(t *testing.T) {
130132
require.EqualValues(t, app.Icon, got.Icon)
131133
require.EqualValues(t, app.Name, got.Name)
132134
require.EqualValues(t, codersdk.WorkspaceAppHealthDisabled, got.Health)
133-
require.EqualValues(t, app.HealthcheckUrl, got.HealthcheckURL)
134-
require.EqualValues(t, app.HealthcheckInterval, got.HealthcheckInterval)
135-
require.EqualValues(t, app.HealthcheckThreshold, got.HealthcheckThreshold)
135+
require.EqualValues(t, "", got.Healthcheck.URL)
136+
require.EqualValues(t, 0, got.Healthcheck.Interval)
137+
require.EqualValues(t, 0, got.Healthcheck.Threshold)
136138
got = agent.Apps[1]
137139
app = apps[1]
138140
require.EqualValues(t, app.Command, got.Command)
139141
require.EqualValues(t, app.Icon, got.Icon)
140142
require.EqualValues(t, app.Name, got.Name)
141143
require.EqualValues(t, codersdk.WorkspaceAppHealthInitializing, got.Health)
142-
require.EqualValues(t, app.HealthcheckUrl, got.HealthcheckURL)
143-
require.EqualValues(t, app.HealthcheckInterval, got.HealthcheckInterval)
144-
require.EqualValues(t, app.HealthcheckThreshold, got.HealthcheckThreshold)
144+
require.EqualValues(t, app.Healthcheck.Url, got.Healthcheck.URL)
145+
require.EqualValues(t, app.Healthcheck.Interval, got.Healthcheck.Interval)
146+
require.EqualValues(t, app.Healthcheck.Threshold, got.Healthcheck.Threshold)
145147
})
146148

147149
t.Run("Metadata", func(t *testing.T) {

codersdk/workspaceapps.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,18 @@ type WorkspaceApp struct {
2121
// Icon is a relative path or external URL that specifies
2222
// an icon to be displayed in the dashboard.
2323
Icon string `json:"icon,omitempty"`
24-
// HealthcheckURL specifies the url to check for the app health.
25-
HealthcheckURL string `json:"healthcheck_url"`
26-
// HealthcheckInterval specifies the seconds between each health check.
27-
HealthcheckInterval int32 `json:"healthcheck_interval"`
28-
// HealthcheckThreshold specifies the number of consecutive failed health checks before returning "unhealthy".
29-
HealthcheckThreshold int32 `json:"healthcheck_threshold"`
30-
// Health specifies the current status of the app's health.
31-
Health WorkspaceAppHealth `json:"health"`
24+
// Healthcheck specifies the configuration for checking app health.
25+
Healthcheck Healthcheck `json:"healthcheck"`
26+
Health WorkspaceAppHealth `json:"health"`
27+
}
28+
29+
type Healthcheck struct {
30+
// URL specifies the url to check for the app health.
31+
URL string `json:"url"`
32+
// Interval specifies the seconds between each health check.
33+
Interval int32 `json:"interval"`
34+
// Threshold specifies the number of consecutive failed health checks before returning "unhealthy".
35+
Threshold int32 `json:"threshold"`
3236
}
3337

3438
// @typescript-ignore PostWorkspaceAppHealthsRequest

provisioner/terraform/resources.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -228,14 +228,16 @@ func ConvertResources(module *tfjson.StateModule, rawGraph string) ([]*proto.Res
228228
continue
229229
}
230230
agent.Apps = append(agent.Apps, &proto.App{
231-
Name: attrs.Name,
232-
Command: attrs.Command,
233-
Url: attrs.URL,
234-
Icon: attrs.Icon,
235-
RelativePath: attrs.RelativePath,
236-
HealthcheckUrl: attrs.HealthcheckURL,
237-
HealthcheckInterval: attrs.HealthcheckInterval,
238-
HealthcheckThreshold: attrs.HealthcheckThreshold,
231+
Name: attrs.Name,
232+
Command: attrs.Command,
233+
Url: attrs.URL,
234+
Icon: attrs.Icon,
235+
RelativePath: attrs.RelativePath,
236+
Healthcheck: &proto.Healthcheck{
237+
Url: attrs.HealthcheckURL,
238+
Interval: attrs.HealthcheckInterval,
239+
Threshold: attrs.HealthcheckThreshold,
240+
},
239241
})
240242
}
241243
}

0 commit comments

Comments
 (0)