docs: REPORT for host-install v1.5.0 (felhom pool default + --adopt-pool)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-01 11:49:34 +02:00
parent 482dbec913
commit b0e6d72bf8
+57 -58
View File
@@ -4,80 +4,79 @@
---
# REPORT — Day-0 artifact manifest: version dropdowns + auto-derived sha (hub v0.29.0)
# REPORT — `felhom` pool as a Day-0 default (+ `--adopt-pool` retrofit + uninstall teardown) (host-install v1.5.0)
**Date:** 2026-07-01 · **Repo:** `felhom.eu` (`hub/` + `manifests/`)
**Date:** 2026-07-01 · **Repo:** `felhom.eu` (`scripts/` only)
Removes the hand-copied sha256 from the Day-0 artifact manifest UI. The operator now **picks a version**
from a dropdown of what's actually in Gitea, and the hub **reads that version's sha256 from Gitea itself**
— no transcription, no stale checksums — while keeping the deliberate human "which version is approved"
gate (never auto-promotes "latest") and the hub as the checksum trust root.
Colleague-safety batch **#4 phase a**. Every Felhom-managed guest now joins a dedicated **`felhom`
pool** (fleet uniformity + the environment 3b will spike the pool-scoped ACL against). Script-only, all
pool ops run as `root@pam` from the installer → **NO agent/token/ACL change, zero permission risk**
(`PVE_PRIVS` untouched; the `FelhomAgent` token stays scoped at `/`).
## 1. Baseline → target
## 1. Confirmed baseline
hub `v0.28.0` @ `ce26c9d`**`v0.29.0`**. (Follow-up to the colleague-safety batch; motivated by the
manual manifest-bump toil flagged in the prior task.)
| Repo | `main` @ commit | Current | → Target |
|------|-----------------|---------|----------|
| felhom.eu (`scripts/felhom-host-install.sh`) | `6148e61` | script **v1.4.0** | **v1.5.0** |
## 2. Feasibility verified against live Gitea (before coding)
PVE 9 `pveum pool` syntax + `/pools` JSON shape confirmed live before wiring: `pveum pool add <id>
[--comment]` / `pool delete <id>` / `pool modify <id> --vms <ids>` (additive); `pvesh get /pools`
`[{poolid,comment}]`, `pvesh get /pools/<id>``{poolid,comment,members:[{vmid,type,status,…}]}`.
- **List versions:** `GET /api/v1/packages/admin?type=generic&q=<pkg>` returns name+version — reflects
what's actually present (pruned olders gone). Live: felhom-agent `[0.52.0, 0.43.0]`, felhom-golden `[0.85.1]`.
- **sha without downloading:** `GET /api/v1/packages/admin/generic/<pkg>/<ver>/files` returns `sha256`
in metadata (agent `5bfc690c…`, golden file `golden.tar.zst` `f87031cc…`) — so the ~GB golden is
never fetched just to hash it.
## 2. Files changed + commit
## 3. Files changed + commits (on `main`)
- `scripts/felhom-host-install.sh` (v1.4.0 → **v1.5.0**) — the only code file.
- `scripts/CHANGELOG.md` — v1.5.0 entry.
- `REPORT.md` — this file (overwritten).
- Commit **`482dbec`** on `main` (parent `6148e61`).
- `hub/internal/gitea/gitea.go` (new) — read-only Gitea packages client: `ListVersions` (semver-desc),
`FileSHA256` (metadata, no download). `hub/internal/gitea/gitea_test.go` — httptest unit tests.
- `hub/internal/web/server.go``gitea` field + `SetGiteaClient`; `artifactChoices` helper; pkg/file
consts; `handleConfiguration` passes `AgentChoices`/`GoldenChoices`.
- `hub/internal/web/configs.go``handleSetArtifacts` reworked to derive the sha from Gitea
authoritatively (`resolveArtifactSHA`); refuses the save on a lookup failure.
- `hub/internal/web/templates/configuration.html` — version `<select>` dropdowns + read-only sha display
+ inline sync script; broadened the sha-failure flash.
- `hub/cmd/hub/main.go` — wires `SetGiteaClient` when registry creds are present.
- `manifests/hub.yaml` — image `0.28.0``0.29.0`.
- Commits: **`079a2cd`** (code + CHANGELOG), **`585f12e`** (manifest tag).
## 3. What was implemented
- **Part 1 — pool default:** const `PVE_POOL="felhom"`; helpers `pool_exists` / `pool_members`
(`.members[].vmid`) / `ensure_felhom_pool` / `pool_add_guest` (skip-if-member). `step_provision`
ensures the pool then adds the guest after a successful provision (dry-run prints both).
- **Part 2 — `--adopt-pool`:** early root-only dispatch + `run_adopt_pool` — resolves the vmid
(`--vmid` else recorded `provisioned_vmid`), requires the guest to exist, ours-checks the
`/etc/felhom-bootstrap` mount (refuse non-Felhom unless `--force`), ensures the pool, adds the guest.
Membership-only; never reconfigures/restarts the guest; no hub contact.
- **Part 3 — uninstall teardown (step 5b):** after the pveum removal, `pveum pool delete felhom` **only
if empty**; otherwise `log_skip` naming the members. Summary line notes the pool when removed. Not
reached on the Spec-1 safe-skip path.
- Usage header gains a "Retrofit" group; every pool mutation goes through `run()` (dry-run-aware).
## 4. Green gate
`go build ./...`, `go vet ./...`, `go test ./...` — all clean (new `internal/gitea` tests pass:
filter+semver-sort, preferred-file match + fallback, non-200 → error).
- `bash -n scripts/felhom-host-install.sh` → OK (local + felhom-pve).
- `shellcheck v0.10.0`**2× SC2015 (info)** at lines 1286 & 1296, both the *pre-existing* `step_verify`
`A && B || C` lines. **0 new warnings.**
## 5. Behaviour
## 5. Tests → §7 mapping (felhom-pve; dry-run + SAFE live)
- Operator picks a version → the read-only sha field mirrors that version's Gitea sha (inline JS). On
save the hub **re-derives the sha from Gitea** (a client-submitted sha is ignored) and stores it. A
Gitea lookup failure REFUSES the save (never stores a version with a wrong/blank checksum).
- "— none —" clears an artifact.
- **Graceful degradation:** without registry creds the form falls back to the previous manual text
inputs (keeps `render_test` + any credential-less deploy working).
- Trust model unchanged: the operator still deliberately chooses the version; the hub stays the checksum
trust root; "latest" is never auto-promoted (rationale in the design discussion — auto-latest would
move the trust root back to Gitea and could promote an RC/broken build).
| # | Scenario | Result |
|---|----------|--------|
| T-A | fresh install (dry-run) | **PASS**`--customer-id demo-felhom --vmid 9300 --dry-run` at step 8/8 prints `[DRY-RUN] pveum pool add felhom --comment Felhom-managed guests` + `[DRY-RUN] add guest 9300 to pool felhom`. |
| T-B | **live adopt of 9201** | **PASS**`--adopt-pool --vmid 9201` → ours-check passes, `guest 9201 added to pool felhom`. `pvesh get /pools/felhom``members:[{…,"vmid":9201,"status":"running","type":"lxc"}]`; **9201 still `running`, config unchanged** (membership-only). The demo node is now pool-uniform. |
| T-D | idempotency | **PASS** — re-run `--adopt-pool --vmid 9201``[SKIP] pool felhom already exists` + `[SKIP] guest 9201 already in pool felhom` (no-op). |
| T-B' | ours red-proof | **PASS**`--adopt-pool --vmid 9001` (no bootstrap mount) → `die` "does not look like a Felhom-provisioned guest … Refusing to adopt. Pass --force", exit 1, pool membership unchanged. |
| T-C | uninstall empty-guard | **PASS**`--uninstall --vmid 9201 --dry-run``[SKIP] pool felhom not empty (members: 9201) — leaving it` (guest not destroyed in dry-run, so the pool retains 9201 → the delete-only-if-empty guard is proven). |
## 6. Deploy + validation
## 6. Served-copy version
- Image `gitea.dooplex.hu/admin/felhom-hub:0.29.0` built + pushed on 192.168.0.180; `manifests/hub.yaml`
bumped; ArgoCD `felhom` app hard-refreshed + synced → **Synced / Healthy**; `deploy/hub` rolled out to
`0.29.0`.
- Startup log confirms **`[INFO] Gitea artifact browser enabled (Day-0 version dropdowns)`** (registry
creds present → the client initialized).
- **Prior follow-up RESOLVED:** the served manifest is now **agent 0.52.0** / sha `5bfc690c…` (saved via
the operator UI earlier this session; `GET /api/v1/artifacts/demo-felhom` confirms). Fresh
`--cores`/`--memory` installs now fetch the cap-capable agent.
```
curl -fsSL https://felhom.eu/scripts/felhom-host-install.sh | grep SCRIPT_VERSION
```
**`SCRIPT_VERSION="1.5.0"`** (confirmed ~1 min after push).
## 7. NOT yet visually confirmed — awaiting operator login
## 7. NOT yet live-validated — awaiting supervised run
The hub pod restart cleared the in-memory session, logging the browser out; entering the operator
password is the operator's action (CC must not type credentials). **Please log in at
`https://hub.felhom.eu/configuration`** so the version fields can be visually confirmed as dropdowns
(agent `0.52.0`/`0.43.0`, golden `0.85.1`) with a read-only sha. All server-side signals (deploy healthy,
gitea client enabled, live API returns versions+sha, unit tests) are green.
- A live **`--uninstall`** (now also deletes the pool when empty) — the destroy path remains the
supervised STOP carried over from Spec 1; the pool-delete-if-empty branch is proven only in dry-run.
## 8. Observations
## 8. Observations (for 3b, not acted on)
- Registry creds + the `ARTIFACT_*` env survived the ArgoCD sync (present on the live deploy).
- The `ARTIFACT_*` env remains a seed-only fallback (fills an empty DB field); the DB value (set via the
now-dropdown UI) is authoritative.
- **`/pools` API shape confirmed for 3b:** list = `[{poolid,comment}]`; detail = `{members:[{vmid,type,
status,node,…}]}`. `pveum pool modify <id> --vms <ids>` is additive (a `--delete 1` variant removes;
`--allow-move` if a guest is already in another pool).
- 3b (the actual permission change) will add a `/pool/felhom`-scoped ACL + `Pool.Allocate` and make the
agent restore INTO the pool under a scoped token — deliberately NOT attempted here (spike-gated).
- The demo `felhom` pool now exists with 9201 as its member — a ready environment for the 3b spike.