33e3443545
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.9 KiB
5.9 KiB
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/-memoryflags;Cores/MemoryMBonbringUpSizing; passed in both dispatch literals + bothBringUpSpec{}builds (runSelftestBringUp,runSelftestProvision);-selftestusage string updated; version0.51.0→0.52.0.internal/reconcile/bringup_test.go— newTestBuildBringUpConfig_ResourceCaps.internal/reconcile/bringup.go— not changed (mechanism already correct; used only for the red-proof, reverted).CHANGELOG.md,README.md— updated.- Commit
0573ec9onmain(parent1502ca6).
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 ininternal/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 packageinternal/reconcileand everything else pass deterministically.
4. Test + omit-when-zero red-proof (§10)
TestBuildBringUpConfig_ResourceCapsPASS: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 unconditionalparams["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 diffshowsbringup.goclean (no net change).
5. Deployed version + T-A scratch live proof (felhom-pve)
- Built
felhom-agent 0.52.0on 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:
The guest booted+ran with
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)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, sha2565bfc690c421b7799f4e0640f13559c41e5933ee60962bf80471eca7eae0e94cb. Publish did delete-then-PUT + a round-trip GET sha verify (fetchable + intact end-to-end). Re-fetched independently: 12 964 463 bytes, sha5bfc690c…. - 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.goL164if 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 — nosqlite3in the pure-Go hub image) is beyond this task's risk envelope. ACTION REQUIRED before a colleague uses--cores/--memoryon 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/-memoryagainst 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 viastrings.Split(code,"-"), so a hyphenated word inflates the count to 11 and the== 10assertion 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.