feat: master/agent phase 3 — webhook and auto mode (#8) #22

Merged
shcizo merged 5 commits from feat/master-agent-webhook-8 into main 2026-10-12 20:03:26 +00:00
Owner

Summary

  • POST /update on the master (outside OIDC, bearer UPDATER_API_KEY; unset → 503). Matches image against image_repo on all agents, marks available_* on every match, starts webhook-triggered jobs for auto services targeting <image_repo>:<tag> (followed tag when no tag is given), and waits for them up to UPDATE_TIMEOUT (default 5m). 404 on no match, 500 if any auto job failed or timed out, otherwise 200.
  • Manual/auto toggle per service on the overview and service page (POST /services/{id}/mode, CSRF); auto is blocked for self, build: and container services with the reason shown. "Update available" badge and an "Available" row.
  • FinishJob clears available_* only when the successful job was created for that exact ref, after it was reported. Migration 0003_webhook.sql, phase-3 plan doc, README / gitea-action README / CLAUDE.md / deploy example updated. action.yml unchanged.

Closes #8

Behaviour changes for CI

  • Mixed results now return 500 (the old 207 is gone); no match returns 404 instead of 200.
  • With a tag, Compose services get pinned to <image_repo>:<tag> via compose.override.yaml; the tag must be a pushed tag.
  • busy (job already active) and refused (not updatable) are reported but return 200.
  • The reverse proxy read timeout must exceed UPDATE_TIMEOUT.

Test plan

  • go test ./... and go test -race ./internal/agent/... ./internal/master/... ./internal/e2e/
  • go test -tags integration ./internal/master/store/ against throwaway Postgres
  • UI verified in browser (mode toggle, disabled reason, badge via SSE, Available row)
  • Manual: webhook with manual service → marked + badge
  • Manual: webhook with auto service → waits, succeeded, badge cleared, override pinned
  • Manual: wrong token 401, unknown image 404, offline agent 500
  • Gitea action pointed at the master's /update in a real CI run
## Summary - `POST /update` on the master (outside OIDC, bearer `UPDATER_API_KEY`; unset → 503). Matches `image` against `image_repo` on all agents, marks `available_*` on every match, starts webhook-triggered jobs for `auto` services targeting `<image_repo>:<tag>` (followed tag when no tag is given), and waits for them up to `UPDATE_TIMEOUT` (default 5m). 404 on no match, 500 if any auto job failed or timed out, otherwise 200. - Manual/auto toggle per service on the overview and service page (`POST /services/{id}/mode`, CSRF); auto is blocked for self, `build:` and container services with the reason shown. "Update available" badge and an "Available" row. - `FinishJob` clears `available_*` only when the successful job was created for that exact ref, after it was reported. Migration `0003_webhook.sql`, phase-3 plan doc, README / gitea-action README / CLAUDE.md / deploy example updated. `action.yml` unchanged. Closes #8 ## Behaviour changes for CI - Mixed results now return 500 (the old 207 is gone); no match returns 404 instead of 200. - With a `tag`, Compose services get pinned to `<image_repo>:<tag>` via `compose.override.yaml`; the tag must be a pushed tag. - `busy` (job already active) and `refused` (not updatable) are reported but return 200. - The reverse proxy read timeout must exceed `UPDATE_TIMEOUT`. ## Test plan - [x] `go test ./...` and `go test -race ./internal/agent/... ./internal/master/... ./internal/e2e/` - [x] `go test -tags integration ./internal/master/store/` against throwaway Postgres - [x] UI verified in browser (mode toggle, disabled reason, badge via SSE, Available row) - [ ] Manual: webhook with manual service → `marked` + badge - [ ] Manual: webhook with auto service → waits, `succeeded`, badge cleared, override pinned - [ ] Manual: wrong token 401, unknown image 404, offline agent 500 - [ ] Gitea action pointed at the master's `/update` in a real CI run
shcizo added 5 commits 2026-10-12 18:53:39 +00:00
Clear available_* only when the deployed ref equals it, drop the unused
poll source, stop leaking internal errors to CI, use the request-scoped
logger, validate X-Request-ID, re-read jobs once after the timeout,
report refused when no target ref exists, and tidy UI, deploy and docs.
shcizo merged commit 41a619b316 into main 2026-10-12 20:03:26 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: shcizo/package-updater#22