REPORT: v0.43.0 BUNDLE slice (canonical unit + Gitea publish + live install)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-28 09:03:23 +02:00
parent a8d14fc384
commit c3020ee3a8
+47 -44
View File
@@ -1,52 +1,55 @@
# REPORT — build-golden.sh default fix + golden rebuild at current (2026-06-27)
# REPORT — felhom-agent v0.43.0 (BUNDLE slice: canonical unit + Gitea publish)
**Task class:** Risky/supervised, Part A only. **No agent binary change** — version stays **v0.42.0**.
**Date:** 2026-06-28 · **Baseline:** v0.42.0 @ `aaa276a` **v0.43.0** @ `a8d14fc`
## What changed
## What shipped
`configs/build-golden.sh` — the `CONTROLLER_IMAGE` default (positional arg 6) was a stale
`gitea.dooplex.hu/admin/felhom-controller:0.43.0`. An argument-less build therefore baked a wildly old
controller, so fresh Day-0 boxes booted old (the demo started at 0.77). Bumped the default to the
**current** `…/felhom-controller:0.85.1`, with a comment that the version should still be passed
explicitly at each rebuild (a `make golden` that resolves the latest tag is a future Observation).
Day-0 no longer needs a hand-installed agent. The binary is **published to Gitea** and the
host-bootstrap script fetches → verifies (sha256 vs the hub-vouched manifest) → installs it. This
commit adds the **canonical systemd unit** and the publish tooling; the binary is a version-only
rebuild (no behavioural change).
- **`configs/felhom-agent.service`** (NEW, canonical) — `User=felhom-agent` (the documented non-root
production model; `privileged.mode: "sudo"` + the sudoers allowlist),
`ExecStart=/usr/local/bin/felhom-agent --config /etc/felhom-agent/agent.json`,
`Restart=on-failure`, `StateDirectory=felhom-agent`. **No `NoNewPrivileges`** (would block the
`sudo` the agent needs) and **no mount-namespacing hardening** (would put the agent in a private
mount namespace, breaking `mount --make-shared`/`--bind` drive propagation into guests) — both
documented inline.
- **`scripts/publish-agent.sh`** (NEW) — build (optional) + PUT binary to
`/api/packages/admin/generic/felhom-agent/<ver>/felhom-agent`, print `AGENT_VERSION`/`AGENT_SHA256`,
GET round-trip re-verify. Pinned version, idempotent (delete-then-PUT), asserts `--version` matches.
- **`configs/build-golden.sh`** — after vzdump, compute sha256 + PUT
`/api/packages/admin/generic/felhom-golden/<golden-ver>/golden.tar.zst`, print
`GOLDEN_VERSION`/`GOLDEN_SHA256`. Opt-in; local auto-discovery stays a fallback.
- **`configs/felhom-agent.sudoers`** (latent bug fix) — escaped the commas in the `lvs -o …` and
`lsblk -o …` argument lists. Bare commas are command separators in sudoers, so `visudo -cf`
**rejected** the file; it had never been visudo-validated live because the demo ran the agent
root+`direct` (sudoers unused). Surfaced by the live install's `visudo -cf` gate.
- **`cmd/felhom-agent/main.go`** — `version` 0.42.0 → 0.43.0.
- **README** — "Process model" section made canonical (non-root + publish/install).
## Green gate
`go build ./... && go vet ./... && go test ./...` — all green. `scripts/publish-agent.sh` +
`configs/build-golden.sh`: `bash -n` + `shellcheck -S warning` clean (the one SC2034 in build-golden.sh
is a pre-existing DHCP-wait loop counter, not this change).
- `bash -n configs/build-golden.sh` → OK.
## Golden rebuild (live on felhom-pve)
Ran the rebuild with the controller image passed **explicitly**:
```
build-golden.sh 9100 local:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst \
local-lvm local vmbr0 gitea.dooplex.hu/admin/felhom-controller:0.85.1
```
(`REGISTRY_USER`/`REGISTRY_TOKEN` sourced out-of-band from `/root/.golden-secrets.env`.)
- **New golden archive volid:** `local:backup/vzdump-lxc-9100-2026_06_27-11_42_51.tar.zst`
(rootfs 32G + Docker-data 16G + user-data 8G; archive size ~574 MB; the vzdump log confirmed
*including mount point mp0 (/var/lib/docker)* and *mp1 (/mnt/sys_drive)* — neither excluded).
### Baked-image verify (cheap, mandatory) — PASS
In the build guest (started briefly, then stopped again):
```
/etc/felhom-controller-image → gitea.dooplex.hu/admin/felhom-controller:0.85.1
docker images (felhom-controller) → gitea.dooplex.hu/admin/felhom-controller:0.85.1 379MB
```
New Day-0 provisions now ship **current** (the host-bootstrap script auto-discovers the newest golden,
so it picks up this rebuild with no further change).
### Full verify (throwaway provision) — not performed
Operator-gated/recommended only. The cheap verify already proves the archive carries 0.85.1; the real
demo 9201 was deliberately **not** re-provisioned (it is the Phase-2 floor test box). The build guest
9100 is left stopped (destroy with `pct destroy 9100 --purge` when no longer needed).
## Live (felhom-pve, demo-felhom) — proven
- Built + published **agent 0.43.0** via `publish-agent.sh` → sha256 `8b989917…`; GET round-trip OK.
- Published the existing **golden 0.85.1** (575 MiB) to Gitea → sha256 `f87031cc…`.
- **From-scratch install** (after moving the live root+direct agent fully aside): the script fetched
the binary from Gitea, **verified sha256 vs the hub manifest**, installed the non-root `felhom-agent`
user + binary + sudoers (`visudo -cf`-validated) + the canonical unit + config (0600 `felhom-agent`);
the service came up **active as non-root felhom-agent**, `--selftest=hub` landed a host-report, and
guest **9201 stayed managed** (present in the host-report). `sudo -n` confirmed live for
mkdir/smartctl/lvs (the escaped-comma sudoers works).
- **sha256 negative:** a deliberately-corrupted published binary made the install **abort**
("Refusing to install (verify-before-use)", exit 1); the good binary was restored (sha re-verified).
## Observations
- A `make golden` (or a `--latest` flag) that resolves the newest pullable controller tag at build time
would make the hand-bumped default unnecessary and prevent this class of drift entirely.
- **Non-root + PBS:** the `felhom-agent` user cannot read `/etc/pve/priv/storage/*.pw` (root-only on
pmxcfs), so PBS datastores are skipped with a WARN (graceful; PBS cadence is 0 on the demo). A
production host using PBS needs the agent granted read access to that key (group/ACL on pmxcfs, or a
sudoers entry) — follow-up, out of this slice.
- **`sudo` package** must be present for the non-root model; the host-install script now
`apt-get install`s it (a root+`direct` host won't have it).