feat: master/agent phase 4 — registry polling and version history (#9) #23

Merged
shcizo merged 14 commits from feat/registry-polling-version-history-9 into main 2026-10-13 07:02:38 +00:00
Owner

Summary

  • Version history: new image_versions table fed by the webhook (tag, no digest), registry polling and the agents' running inventory (well-formed sha256 digests only; a bare image is recorded as latest).
  • Registry polling: the master sends one HEAD per distinct followed repo:tag every POLL_INTERVAL (default 6h) via go-containerregistry, with credentials from DOCKER_CONFIG. A new digest becomes the available suggestion; auto services get a job. Registry-controlled text never reaches last_poll_error (status + error codes, or a fixed text per error class).
  • Version picker and rollback: the Service page lists the 10 most recent versions with a Deploy action (by version id, repo checked server-side). The agent deploys digest-pinned refs as is (protocol 3; v2 agents fail such jobs with a clear message). A rollback of an auto service stays until the registry shows a digest the tag was never deployed at (last_tag_digest).
  • Overview badges "follows no tag" and "poll failed"; README, CLAUDE.md, spec (Docker Hub HEAD verified) and phase 4 plan updated.

Closes #9

Test plan

  • gofmt, go vet ./..., go test ./..., go test -race on agent, master and e2e
  • Store integration tests against Postgres 16
  • UI verified in a browser (overview badges, polling row, versions table, Deploy POST with CSRF and version id, 390px)
  • Migration 0004 applies on the server database
  • New push of a followed tag shows "update available" (source poll) within one cycle
  • Auto service gets exactly one poll job; rollback pick holds across cycles; a newer push moves it forward
  • Private image with bad credentials shows "poll failed" with only registry answered 401 Unauthorized
## Summary - **Version history:** new `image_versions` table fed by the webhook (tag, no digest), registry polling and the agents' running inventory (well-formed `sha256` digests only; a bare image is recorded as `latest`). - **Registry polling:** the master sends one HEAD per distinct followed `repo:tag` every `POLL_INTERVAL` (default 6h) via go-containerregistry, with credentials from `DOCKER_CONFIG`. A new digest becomes the available suggestion; auto services get a job. Registry-controlled text never reaches `last_poll_error` (status + error codes, or a fixed text per error class). - **Version picker and rollback:** the Service page lists the 10 most recent versions with a Deploy action (by version id, repo checked server-side). The agent deploys digest-pinned refs as is (protocol 3; v2 agents fail such jobs with a clear message). A rollback of an auto service stays until the registry shows a digest the tag was never deployed at (`last_tag_digest`). - Overview badges "follows no tag" and "poll failed"; README, CLAUDE.md, spec (Docker Hub HEAD verified) and phase 4 plan updated. Closes #9 ## Test plan - [x] `gofmt`, `go vet ./...`, `go test ./...`, `go test -race` on agent, master and e2e - [x] Store integration tests against Postgres 16 - [x] UI verified in a browser (overview badges, polling row, versions table, Deploy POST with CSRF and version id, 390px) - [ ] Migration 0004 applies on the server database - [ ] New push of a followed tag shows "update available" (source poll) within one cycle - [ ] Auto service gets exactly one poll job; rollback pick holds across cycles; a newer push moves it forward - [ ] Private image with bad credentials shows "poll failed" with only `registry answered 401 Unauthorized`
shcizo added 14 commits 2026-10-13 07:02:27 +00:00
Adds services.last_auto_digest so the poller starts one automatic update per
registry digest, and re-reads the service before starting it. Also records a
bare image's running version as tag latest, only records well-formed
digests, and shows a digest-less version unless a digest row of its tag was
first seen at or after it.
Renames last_auto_digest to last_tag_digest. FinishJob sets it to the pinned
digest after any successful job whose to_ref had no digest, so a rollback
holds however the update was started.
shcizo merged commit 1664e47183 into main 2026-10-13 07:02:38 +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#23