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:
2026-06-28 08:38:26 +02:00
parent d65b2f74ea
commit 39ef64e128
11 changed files with 707 additions and 49 deletions
+3 -1
View File
@@ -23,8 +23,9 @@ func TestTemplates_FloorRender(t *testing.T) {
// configs.html — the list page data shape used by handleConfigList.
cfgData := struct {
Customers []customerListEntry
Customers []customerListEntry
GlobalFloor string
Artifacts store.ArtifactManifest
ActiveNav string
Flash string
CSRFToken string
@@ -35,6 +36,7 @@ func TestTemplates_FloorRender(t *testing.T) {
ControllerVersion: "0.86.0", HasConfig: true,
}},
GlobalFloor: "0.86.0",
Artifacts: store.ArtifactManifest{AgentVersion: "0.43.0", GoldenVersion: "0.85.1"},
ActiveNav: "configs",
}
var buf bytes.Buffer