feat(nodes): agent self-upgrade (#57)

POST /agents/:id/upgrade enqueues a self_upgrade command carrying the
target platform, the sha256 the server computed over its bundled binary,
and the server version. The agent downloads the replacement from the
existing /api/agents/download/:platform endpoint, verifies the checksum,
sanity-checks the new binary (--version), atomically swaps its own
executable, reports the command result, then re-execs via syscall.Exec —
no supervisor or restart plumbing required.

Agents stamp main.version via ldflags at image build, expose --version,
and now send version at register so node_agents.version refreshes on
re-register (older agents without the field keep their stored value).
The server rejects upgrades for offline nodes and for platforms with no
bundled binary (linux-amd64/linux-arm64 ship in the image).

Surfaces: nodes upgrade CLI, containr_nodes_upgrade MCP (confirm-gated),
node-detail page button, OpenAPI. Verified live: v0.0.3 agent upgraded
to v0.0.4 in place, re-registered with the new version; offline node
returns 409 NODE_OFFLINE.

Generated with [Devin](https://devin.ai)

Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomáš DvořákandDevin authored and GitHub committed 2026-10-09 17:15:58 +02:00
1 parent dd5ce80ce2
commit 9de586f177
12 files changed
+337 -14

No files matched your search

+12
View File
@@ -301,6 +301,18 @@ and wired refs, one click or one CLI call.
documented ceilings. Remaining: `scheduling_rules` affinity
policies, deployment status reported back from agent
results, spread weighting by real capacity.
- [x] **Agent self-upgrade** — `POST /agents/:id/upgrade` enqueues a
`self_upgrade` command carrying platform + sha256 + server version;
the agent downloads its replacement from `GET /agents/download/
:platform`, verifies the checksum, sanity-checks `--version`,
atomically swaps its own executable, reports the result, then
re-execs (`syscall.Exec`) — no supervisor needed. Agents now stamp
`main.version` via ldflags at image build and report it at
register/heartbeat (`node_agents.version` refreshes on re-register;
older agents keep their stored value). Surfaces: `nodes upgrade`
CLI, `containr_nodes_upgrade` MCP (confirm-gated), node-detail page
button (online-gated). Ceilings: linux amd64/arm64 only; agents on
other platforms get a `NO_BINARY` 409.
- [🟡] **Build-on-node** — private registry pulls shipped: the dispatch
payload carries the project owner's `registries` credentials for the
image host; the agent `docker login`s for the pull and logs out after,