Skip to content

Commit b034b06

Browse files
committed
add postWorkspaceAppHealth route
1 parent 511be13 commit b034b06

File tree

10 files changed

+132
-7
lines changed

10 files changed

+132
-7
lines changed

coderd/coderd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ func New(options *Options) *API {
412412
r.Use(httpmw.ExtractWorkspaceAgent(options.Database))
413413
r.Get("/metadata", api.workspaceAgentMetadata)
414414
r.Post("/version", api.postWorkspaceAgentVersion)
415+
r.Post("/app-healths", api.postWorkspaceAppHealths)
415416
r.Get("/gitsshkey", api.agentGitSSHKey)
416417
r.Get("/coordinate", api.workspaceAgentCoordinate)
417418
r.Get("/report-stats", api.workspaceAgentReportStats)

coderd/database/dump.sql

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
CREATE TYPE workspace_app_health AS ENUM ('intializing', 'healthy', 'unhealthy');
22

33
ALTER TABLE ONLY workspace_apps
4-
ADD COLUMN IF NOT EXISTS health workspace_app_health NOT NULL DEFAULT 'intializing';
4+
ADD COLUMN IF NOT EXISTS health workspace_app_health NOT NULL DEFAULT 'intializing',
5+
ADD COLUMN IF NOT EXISTS updated_at timestamptz NOT NULL DEFAULT '-infinity';

coderd/database/models.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

Lines changed: 31 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/workspaceapps.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,12 @@ INSERT INTO
2424
)
2525
VALUES
2626
($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *;
27+
28+
-- name: UpdateWorkspaceAppHealthByID :exec
29+
UPDATE
30+
workspace_apps
31+
SET
32+
updated_at = $2,
33+
health = $3
34+
WHERE
35+
id = $1;

coderd/workspaceapps.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ import (
77
"net/http/httputil"
88
"net/url"
99
"strings"
10+
"time"
1011

1112
"github.com/go-chi/chi/v5"
1213
"go.opentelemetry.io/otel/trace"
14+
"golang.org/x/xerrors"
1315

1416
"github.com/coder/coder/coderd/database"
1517
"github.com/coder/coder/coderd/httpapi"
@@ -254,3 +256,76 @@ func (api *API) applicationCookie(authCookie *http.Cookie) *http.Cookie {
254256
appCookie.Domain = "." + api.AccessURL.Hostname()
255257
return &appCookie
256258
}
259+
260+
func (api *API) postWorkspaceAppHealths(rw http.ResponseWriter, r *http.Request) {
261+
workspaceAgent := httpmw.WorkspaceAgent(r)
262+
var req codersdk.PostWorkspaceAppHealthsRequest
263+
if !httpapi.Read(rw, r, &req) {
264+
return
265+
}
266+
267+
apps, err := api.Database.GetWorkspaceAppsByAgentID(r.Context(), workspaceAgent.ID)
268+
if err != nil {
269+
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
270+
Message: "Error getting agent apps",
271+
Detail: err.Error(),
272+
})
273+
return
274+
}
275+
276+
var newApps []database.WorkspaceApp
277+
for name, health := range req.Healths {
278+
var found *database.WorkspaceApp
279+
for _, app := range apps {
280+
if app.Name == name {
281+
found = &app
282+
}
283+
}
284+
if found == nil {
285+
httpapi.Write(rw, http.StatusNotFound, codersdk.Response{
286+
Message: "Error setting workspace app health",
287+
Detail: xerrors.Errorf("workspace app name %s not found", name).Error(),
288+
})
289+
return
290+
}
291+
292+
switch health {
293+
case codersdk.WorkspaceAppInitializing:
294+
found.Health = database.WorkspaceAppHealthIntializing
295+
case codersdk.WorkspaceAppHealthy:
296+
found.Health = database.WorkspaceAppHealthHealthy
297+
case codersdk.WorkspaceAppUnhealthy:
298+
found.Health = database.WorkspaceAppHealthUnhealthy
299+
default:
300+
httpapi.Write(rw, http.StatusBadRequest, codersdk.Response{
301+
Message: "Error setting workspace app health",
302+
Detail: xerrors.Errorf("workspace app health %s is not a valid value", health).Error(),
303+
})
304+
return
305+
}
306+
307+
// don't save if the value hasn't changed
308+
if found.Health == database.WorkspaceAppHealth(health) {
309+
continue
310+
}
311+
312+
newApps = append(newApps, *found)
313+
}
314+
315+
for _, app := range newApps {
316+
api.Database.UpdateWorkspaceAppHealthByID(r.Context(), database.UpdateWorkspaceAppHealthByIDParams{
317+
ID: app.ID,
318+
UpdatedAt: time.Now(),
319+
Health: app.Health,
320+
})
321+
if err != nil {
322+
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
323+
Message: "Error setting workspace app health",
324+
Detail: err.Error(),
325+
})
326+
return
327+
}
328+
}
329+
330+
httpapi.Write(rw, http.StatusOK, nil)
331+
}

codersdk/workspaceapps.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,8 @@ type WorkspaceApp struct {
2222
Icon string `json:"icon,omitempty"`
2323
Status WorkspaceAppHealth `json:"health"`
2424
}
25+
26+
type PostWorkspaceAppHealthsRequest struct {
27+
// Healths is a map of the workspace app name and the status of the app.
28+
Healths map[string]WorkspaceAppHealth
29+
}

site/src/api/typesGenerated.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,11 @@ export interface PostWorkspaceAgentVersionRequest {
336336
readonly version: string
337337
}
338338

339+
// From codersdk/workspaceapps.go
340+
export interface PostWorkspaceAppHealthsRequest {
341+
readonly Healths: Record<string, WorkspaceAppHealth>
342+
}
343+
339344
// From codersdk/provisionerdaemons.go
340345
export interface ProvisionerDaemon {
341346
readonly id: string

0 commit comments

Comments
 (0)