v0.43.0: canonical systemd unit + publish agent binary + golden to Gitea (BUNDLE slice)

- configs/felhom-agent.service: canonical non-root unit (User=felhom-agent, sudo model);
  deliberately NO NoNewPrivileges (breaks sudo) and NO mount-namespacing hardening (breaks
  the intermediary-mount drive propagation into guests) — documented inline.
- scripts/publish-agent.sh: build (optional) + PUT binary to Gitea generic + sha256 +
  GET round-trip. Pinned version, idempotent (delete-then-PUT).
- configs/build-golden.sh: after vzdump, compute sha256 + PUT golden.tar.zst to Gitea
  generic (version = baked controller version). Opt-in; local auto-discovery stays fallback.
- cmd/felhom-agent/main.go: version 0.42.0 -> 0.43.0.
- README: process model now canonical (non-root + publish/install).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-28 08:38:01 +02:00
parent aaa276a7b9
commit 29aeaa6bb4
6 changed files with 243 additions and 5 deletions
+35
View File
@@ -3,6 +3,41 @@
All notable changes to **felhom-agent** are recorded here. Update on every code
change that gets pushed.
## v0.43.0 — canonical systemd unit + binary published to Gitea (BUNDLE slice) (2026-06-28)
Day-0 no longer needs a hand-installed agent. The agent binary is now PUBLISHED to Gitea as a generic
package and the host-bootstrap script fetches → verifies (sha256 vs the hub-vouched manifest) →
installs it. This commit adds the **canonical systemd unit** (was hand-made per host) and the publish
tooling; the binary itself is a version-only rebuild (no behavioural change).
- **`configs/felhom-agent.service` (NEW, canonical):** `User=felhom-agent`/`Group=felhom-agent` (the
documented non-root production model — README "Process model"; `privileged.mode: "sudo"` + the
narrow sudoers allowlist), `ExecStart=/usr/local/bin/felhom-agent --config
/etc/felhom-agent/agent.json`, `After=network-online.target pve-cluster.service pveproxy.service`,
`Restart=on-failure`, `StateDirectory=felhom-agent`. **Deliberately NO sandboxing**, with the reasons
documented inline:
- `NoNewPrivileges` is NOT set — it would block the setuid `sudo` the agent needs for every host-root
op (mount/format/pct/dnsmasq), silently killing all privileged capability.
- NO mount-namespacing hardening (`ProtectHome`/`ProtectSystem`/`PrivateTmp`/…) — any of those give the
unit a PRIVATE mount namespace, and the intermediary-mount drive model relies on `mount
--make-shared`/`--bind` propagating into the running guest; in a private namespace every drive
enrollment would silently break. The agent shares the host mount namespace; the sudoers allowlist is
the security boundary.
- **`scripts/publish-agent.sh` (NEW):** builds (optional) + PUTs the binary to
`/api/packages/admin/generic/felhom-agent/<ver>/felhom-agent` (Gitea generic), prints
`AGENT_VERSION` + `AGENT_SHA256`, and does a GET round-trip (re-fetch + sha256 re-check) to prove the
artifact is fetchable + intact. Pinned to a version (never `:latest`); idempotent (delete-then-PUT);
asserts the binary's `--version` matches the publish version. Creds via `GITEA_USER/GITEA_TOKEN`
(falls back to `REGISTRY_USER/REGISTRY_TOKEN`).
- **`configs/build-golden.sh`:** after the vzdump archive is produced, computes its sha256 and PUTs it
to `/api/packages/admin/generic/felhom-golden/<golden-version>/golden.tar.zst` (`<golden-version>` =
the baked controller version), printing `GOLDEN_VERSION` + `GOLDEN_SHA256`. Opt-in (only when the
Gitea creds are set); the local-golden auto-discovery stays as a fallback.
- **`cmd/felhom-agent/main.go`:** `version` 0.42.0 → 0.43.0.
- The operator records the printed agent + golden version+sha256 in the hub (Configs → "Day-0
artifacts"); the host-bootstrap script verifies fetched artifacts against those before installing.
- `go build/vet/test ./...` green.
## build-golden.sh — default controller image bumped to current; golden rebuilt at 0.85.1 (2026-06-27)
**Operational + a default fix (no agent binary change — version stays v0.42.0).**