hub v0.16.0 + host-install v1.1.0: Day-0 artifact manifest + self-install the agent (BUNDLE slice)
Hub (v0.16.0):
- store: ArtifactManifest{agent,golden version+sha256} in hub_settings; Get/SetArtifactManifest.
- handler: GET /api/v1/artifacts/{id} (passphrase auth, mirrors config-retrieve). Unset => 200 empty.
- web: operator UI "Day-0 artifacts" card (POST /configs/artifacts), semver + 64-hex validation.
- artifact_test.go: returned-verbatim / unset-empty / 401 / 404 / store round-trip.
host-install (v1.1.0):
- new step 5/8 agent-install: manifest + git token (config-retrieve) -> fetch binary from Gitea ->
verify sha256 vs hub manifest (abort on mismatch) -> install non-root felhom-agent user + binary +
sudoers (visudo -cf) + canonical unit. Idempotent.
- new step 7/8 golden: local fallback else fetch+verify+import from Gitea (--force-gitea-golden).
- agent now runs non-root (privileged.mode sudo), config chowned to the service user.
- README prerequisites trimmed to: install PVE + create customer.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,32 @@
|
||||
# Felhom Hub — Changelog
|
||||
|
||||
## v0.16.0 — Day-0 artifact manifest (hub-vouched agent + golden checksums) (2026-06-28)
|
||||
|
||||
The hub now serves a passphrase-authed **artifact manifest** so the host-bootstrap script can
|
||||
**fetch-then-verify** the agent binary + golden archive from Gitea before installing them. The hub is
|
||||
the checksum **trust root** — a different root than Gitea (which only stores the bytes). Part of the
|
||||
BUNDLE slice that lets a fresh PVE box self-install the agent (no more manual binary/unit step).
|
||||
|
||||
- **`store.go`:** `ArtifactManifest{agent_version, agent_sha256, golden_version, golden_sha256}` with
|
||||
`Get/SetArtifactManifest`, persisted as four discrete rows in the existing `hub_settings` key/value
|
||||
table (no schema change — same mechanism as the controller-version floor; survives restarts; partial
|
||||
sets round-trip). Added generic `getSetting/setSetting` helpers.
|
||||
- **`handler.go`:** new `GET /api/v1/artifacts/{customer_id}` — auth mirrors `handleConfigRetrieve`
|
||||
EXACTLY (`X-Retrieval-Password`, 404-then-401 order, constant-time compare). Returns
|
||||
`{"agent":{version,sha256},"golden":{version,sha256}}`. An unset manifest returns **200 with empty
|
||||
fields** (not an error) so the script falls back to the local golden / fails clearly on a missing
|
||||
binary. v0.16.0 returns the GLOBAL current set for every customer (per-customer pinning is a future
|
||||
hook).
|
||||
- **`configs.go` + `configs.html` (operator UI):** a "Day-0 artifacts — agent & golden" card beside the
|
||||
managed-update floor controls, with version + sha256 fields for each artifact. `POST /configs/artifacts`
|
||||
(CSRF-protected); versions validated as bare semver (reusing the floor validator), sha256s as 64-hex,
|
||||
blank-to-clear.
|
||||
- **Tests (`artifact_test.go`):** recorded set returned verbatim; unset → 200 empty; wrong/missing
|
||||
passphrase → 401; unknown customer → 404; store partial-set round-trip. Plus the floor-render smoke
|
||||
test updated for the new list-page data field.
|
||||
- Reuse: no new auth path (passphrase, like config-retrieve + host-enroll); no new table (hub_settings);
|
||||
no new fetch credential downstream (the script reuses the config-retrieve git token).
|
||||
|
||||
## v0.15.0 — Phase 2 managed updates: per-customer controller-version floor (2026-06-27)
|
||||
|
||||
The operator can now set a **minimum controller version** (FLOOR) — per-customer, defaulting to a
|
||||
|
||||
Reference in New Issue
Block a user