Files
felhom-agent/REPORT.md
T
2026-07-01 08:19:14 +02:00

5.9 KiB
Raw Blame History

REPORT — operator-opt-in CPU/RAM cap for the provisioned guest (agent v0.52.0)

Date: 2026-07-01 · Repo: felhom-agent · Class: Implementation (additive CLI→spec plumbing)

Colleague-safety batch #3 (agent half). New -cores/-memory flags let an operator cap the provisioned guest's CPU cores + RAM at provision time, before first boot, so a trial appliance on a colleague's SHARED production Proxmox doesn't pressure his existing guests. Pure CLI→spec wiring — the reconcile engine already applied the cap.

1. Confirmed baseline

Repo main @ commit Current → Target
felhom-agent 1502ca6 v0.51.0 v0.52.0

2. Files changed + commit

  • cmd/felhom-agent/main.go-cores/-memory flags; Cores/MemoryMB on bringUpSizing; passed in both dispatch literals + both BringUpSpec{} builds (runSelftestBringUp, runSelftestProvision); -selftest usage string updated; version 0.51.00.52.0.
  • internal/reconcile/bringup_test.go — new TestBuildBringUpConfig_ResourceCaps.
  • internal/reconcile/bringup.gonot changed (mechanism already correct; used only for the red-proof, reverted).
  • CHANGELOG.md, README.md — updated.
  • Commit 0573ec9 on main (parent 1502ca6).

3. Green gate

  • Local (Go 1.26.0, Windows) and build server 192.168.0.180 (Go 1.26.0, linux): go build ./... OK, go vet ./... OK.
  • go test ./...all packages pass EXCEPT a pre-existing flake in internal/escrow (TestGenerateRecoveryCode_EntropyAndFormat): the random recovery code occasionally contains a hyphenated wordlist entry (e.g. "yo-yo"), so the test's --split counts 11 "words" instead of 10. Confirmed flaky by re-running 5×: 1 fail / 4 pass. It is in a package this task did NOT touch and is unrelated to the cap change (see Observations). My package internal/reconcile and everything else pass deterministically.

4. Test + omit-when-zero red-proof (§10)

  • TestBuildBringUpConfig_ResourceCaps PASS: buildBringUpConfig(Cores:2,MemoryMB:4096)cores="2",memory="4096"; buildBringUpConfig(Cores:0,MemoryMB:0) → both keys absent.
  • Red-proof: temporarily replaced the if spec.Cores > 0 {…} guard with an unconditional params["cores"]=strconv.Itoa(spec.Cores) → the omit-when-zero assertion FAILED as designed (bringup_test.go:115: cores must be ABSENT when unset (golden default), got "0"). Reverted; test passes again; git diff shows bringup.go clean (no net change).

5. Deployed version + T-A scratch live proof (felhom-pve)

  • Built felhom-agent 0.52.0 on 180 (sha256 5bfc690c421b7799…); deployed to felhom-pve (backup /usr/local/bin/felhom-agent.bak-0.51.0, install -m0755, systemctl restart). Verified: felhom-agent --version = 0.52.0, systemctl is-active = active, journal clean (normal host-report + sudo pct/docker activity).
  • T-A (Scenario A, cap pre-boot) — PASS. Ran the SAFE scratch bring-up on a free vmid 9300:
    felhom-agent --config /etc/felhom-agent/agent.json --selftest=bring-up -mode provision \
      -archive local:backup/vzdump-lxc-9100-2026_06_27-11_42_51.tar.zst -vmid 9300 \
      -cores 1 -memory 1024 -keep
    → bring-up record: Pass=true, Verified="boot+running", 18s
    pct config 9300:
        cores: 1
        memory: 1024
        rootfs: local-lvm:vm-9300-disk-0,size=32G
    pct destroy 9300 → DESTROYED (confirmed gone)
    
    The guest booted+ran with cores:1/memory:1024 = the cap was written into the pre-start config PUT (guest never ran uncapped). Scratch guest torn down; guest 9201 untouched.

6. Served/published + hub manifest

  • Gitea generic package published: admin/generic/felhom-agent/0.52.0/felhom-agent, sha256 5bfc690c421b7799f4e0640f13559c41e5933ee60962bf80471eca7eae0e94cb. Publish did delete-then-PUT + a round-trip GET sha verify (fetchable + intact end-to-end). Re-fetched independently: 12 964 463 bytes, sha 5bfc690c….
  • Hub artifact manifest — NOT fully bumped (required operator follow-up). The env fallback on the hub deploy was set to ARTIFACT_AGENT_VERSION=0.52.0 / the new sha (live pod confirms). BUT the hub seeds env only into an empty DB field (cmd/hub/main.go L164 if m.AgentVersion == ""), and the stored manifest already holds 0.43.0, which wins. GET /api/v1/artifacts/{customer} therefore still returns agent 0.43.0. The only in-app editor is the password-gated operator UI (Configs → Day-0 artifacts / handleSetArtifacts), which I cannot submit; the alternative (a direct write to the live operator-backend DB — no sqlite3 in the pure-Go hub image) is beyond this task's risk envelope. ACTION REQUIRED before a colleague uses --cores/--memory on a fresh install: an operator must set the artifact manifest to agent 0.52.0 / sha 5bfc690c421b7799f4e0640f13559c41e5933ee60962bf80471eca7eae0e94cb in the hub UI (the binary + env fallback are already in place).

7. NOT yet live-validated — awaiting supervised run

  • A capped real customer --selftest=provision (full slice-8A chain with -cores/-memory against a real customer/guest). The T-A scratch bring-up above is the safe mechanism proof; a real capped customer provision is the supervised step (colleague's box).

8. Observations (noticed, NOT acted on)

  • Pre-existing flake internal/escrow/TestGenerateRecoveryCode_EntropyAndFormat — the wordlist contains hyphenated entries (e.g. "yo-yo"); the test derives word count via strings.Split(code,"-"), so a hyphenated word inflates the count to 11 and the == 10 assertion fails ~1/5 runs. Fix is a test/wordlist concern in a package outside this task's scope; left untouched.
  • The hub artifact manifest was already stale (0.43.0) before this task — fresh installs were fetching an old agent regardless. Bumping it (item 6) also resolves that lag.