Files
felhom.eu/REPORT.md
T

6.6 KiB

felhom.eu — task reports

Overwrite this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in hub/CHANGELOG.md; the scripts history lives in scripts/CHANGELOG.md.


REPORT — S2: box-facing WG registration + wireguard desired-state block + /offsite UI (2026-07-04)

Doc-06 roadmap row S2 shipped: hub v0.32.1 → v0.33.0 live on k3s; peersync script v1.0.0 → v1.0.1 redeployed to the dev endpoint. The agent was NOT touched; the S3 contract travels via the new golden only.

1. Baselines

Start: felhom.eu @ 740cc42 (hub v0.32.1, peersync v1.0.0), felhom-agent @ 4ba1b14 (v0.63.0, read-only). Live baseline captured before validation: demo-felhom-01 at generation 2, desired-state {"guests":[]}, WG registry empty, guest 9201 running (controller 0.98.3 healthy), agent v0.63.0, poll interval 900 s.

2. Files created/modified

  • hub/internal/store/store.go (partial unique index idx_wg_peers_host; BumpHostDesired), hub/internal/store/wg.go (+allocateWGPeerTx extraction, RegisterWGPeerForHost, GetWGPeerForHost, WGPeer.CreatedAt), wg_test.go (Group A)
  • hub/internal/api/wg.go (handleRegisterHostWG, mergeWireguard, delete-bumps-owner), handler.go (routing case; merge call in handleGetDesiredState; wireguard-key rejection in handleAdminSetDesiredState), wg_test.go (Group B), NEW testdata/desired-state-wireguard.golden.json (S3 cross-repo contract)
  • hub/internal/web/offsite.go + templates/offsite.html + offsite_test.go (Group C); server.go routing; Offsite nav link in all 9 page templates
  • scripts/felhom-peersync.sh v1.0.1 (exit-swallow fix)
  • manifests/hub.yaml (image 0.33.0), hub/CHANGELOG.md, scripts/CHANGELOG.md, documentation/architecture/06-offsite-connectivity.md (§3.2 concrete wire shape + S2 row SHIPPED), CONTEXT.md, this REPORT

3. Commits (pushed to main)

  1. fcf84a0 store: host binding + index + BumpHostDesired
  2. ba52005 API: registration + merge-at-read + hub-owned-key guard + golden
  3. 13203c2 web: /offsite page + nav
  4. (script commit) peersync v1.0.1 + 5e... manifest 0.33.0 bump
  5. (this commit) docs

4. Tests + the five §10 red-proofs

cd hub && go build ./... && go vet ./... && go test ./... — all green (12 packages). New: 6 store tests (Group A), 5 API tests (Group B), 2 web render tests (Group C). TestDesiredStateGolden_RoundTripsThroughHub passes UNMODIFIED; the S1 suites pass unmodified through the allocator extraction.

Red-proofs, each run → FAILED as required → reverted:

  • (a) self-scope check dropped → cross-host register = 200, want 403
  • (b) merge made unconditional → caught by the no-peer-serves-no-block assertion (GET serves a wireguard block that was never legitimately registered); the golden test itself survived only via the fail-safe unmerged path (endpoint record absent in its setup) — the pass-through property is covered either way
  • (c) wireguard-key rejection dropped → PUT with wireguard key = 200, want 400
  • (d) bump-on-idempotent → both negatives fail (gen=2 want 1, push count 2 want 1)
  • (e) script exit-swallow (sandbox, stub wg-quick exit-1-after-partial + recording stub wg): pre-fix shape invoked wg with rc=0 despite the strip failure; fixed shape errors first, wg never invoked

5. Deploy + live validation (real pipeline, secrets redacted)

  • hub 0.33.0 rolled out via ArgoCD (deployment "hub" successfully rolled out, image felhom-hub:0.33.0, [INFO] WG peer-sync enabled); peersync v1.0.1 on the endpoint (head shows the v1.0.1 header), shellcheck-clean on 180.
  • Registration through the REAL per-host auth path (curl run ON felhom-pve; its key never left the box; throwaway keypair minted + private key shredded unused): {"assigned_ip":"10.77.0.2/32","existed":false,"generation":3,"sync":"ok"} — gen 2→3.
  • Served desired-state carried exactly the golden-shaped block (endpoint coords + pubkey + assigned_ip) alongside the untouched guests key; endpoint wg show wg0 listed the pubkey with 10.77.0.2/32.
  • Old-agent tolerance (the S3 fleet-safety gate), verbatim journal: time=2026-07-04T01:04:29.267+02:00 level=INFO msg="desired: updated from hub" generation=3 guests=0 — the v0.63.0 typed parse dropped the unknown key; guest count unchanged; NO error/warn from the desired/reconcile path (the only WARN in the window is the pre-existing, documented pbs: cannot read token secret non-root permission issue — unrelated to S2). Guest-state re-capture = byte-identical to baseline (9201 running, controller 0.98.3 healthy).
  • Removal: DELETE → {"status":"ok","sync":"ok"} → generation 4; desired-state back to the pure operator blob ({"guests":[]}, no wireguard key); registry {"peers":[]}; endpoint wg show 0 peers. Gen-4 clean fetch by the agent, verbatim: time=2026-07-04T01:19:29.228+02:00 level=INFO msg="desired: updated from hub" generation=4 guests=0 — no errors; the box is fully back to baseline except the two expected generation increments.
  • /offsite route wired + auth-gated live (302 → /login); page rendering proven by Group C unit tests — the live view is operator-password-gated (eyeball on next login).

Generation accounting for demo-felhom-01: baseline 2 → 3 (registration) → 4 (removal) — exactly the two expected increments; desired_json blob never modified (byte-identity asserted in tests; live blob returned to the identical {"guests":[]}).

6. NOT yet live-validated — awaiting S3+

  • Agent keygen/registration/wg-felhom service + IdentityBundle escrow join + CGNAT/mobile smoke (S3, risky/supervised).
  • A real PBS backup over the tunnel into a namespace (S4).
  • DR re-establishment consuming the escrowed WG key (S5).
  • UI mutations + tunnel-health columns (S3/S6).

7. Observations (noticed, not acted on)

  • The agent's 900 s poll makes desired-state validation slow-loop (two ≤16-min waits in this run) — S3 test plans should budget for it or temporarily shorten the interval on the test box.
  • hub-config's report_api_key doubles as the only global admin key; a scoped operator token would narrow the blast radius of the endpoint-mutation surface (pre-existing, S6-adjacent).
  • The pre-existing pbs: cannot read token secret WARN on felhom-pve (non-root agent vs /etc/pve/priv/storage/felhom-pbs.pw) fires every cycle — known BUNDLE-slice issue, gets resolved naturally when S4 points PBS at the tunnel with per-customer tokens.