Update from hub: node self-update endpoint, hub push per machine / all, push-nodes CLI run by make deploy, outdated badges + Update buttons on Machines

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-09-18 12:04:31 -07:00
co-authored by Claude Fable 5.1
parent e9be94e32b
commit 254e0cdd58
8 changed files with 248 additions and 7 deletions
+11 -3
View File
@@ -190,9 +190,17 @@ something long in one, switch away and back, refresh — it's all still there.
carries WebSockets, so terminals, log tails and task output work remotely.
Frontend: `setMachine()` rewrites every `/api/…` path; the rail has a machine
switcher at the top and a Machines page to add/remove/open. Pages remount on switch;
terminals live on the node. First node: `grid`. Still to do: Phase 2 Datacenter
overview; Phase 3 `make deploy-remote` and update-from-hub; optional firewall rule
limiting a node's port to the hub.
terminals live on the node. Nodes: `grid`, `wyse`. **Phase 3 (update from hub)
shipped 2026-09-18**: node `POST /api/self-update` takes a binary, checks it answers
`version`, keeps `hamlab.prev` in the data dir, installs over the executable via
`sudo install`, replies, then restarts the service; the hub pushes its own executable
with `POST /api/machines/{name}/update` or `/api/machines-update-all` (architecture
checked first via `/api/me.arch`), the Machines page shows an **outdated** badge and
Update buttons, and `hamlab push-nodes` does the same from the CLI — `make deploy` runs
it last, so one deploy on the hub updates every machine. First install on a new host
is still by hand (scp binary + `install.sh`, `hamlab passwd`, `tls auto`). Still to
do: Phase 2 Datacenter overview; optional firewall rule limiting a node's port to
the hub; cross-architecture builds for the Mac mini.
- **Auth hardening** — WebAuthn passkeys (phone Face ID), TOTP fallback, session
list + revoke, optional NPM access list restricting to WireGuard/LAN.
- **Files tab** — **shipped 2026-09-18** (`internal/files`, `Files.tsx`): browse from