Files
felhom.eu/REPORT.md
T
admin 6db68f4e45 host-install v1.3.0: --uninstall (clean revert) + pre-flight guards
Colleague-safety batch #1+#2 (script-only). Adds a guarded, dry-run-aware
--uninstall local host teardown (guest -> agent -> pveum(ACL,token,user,role)
-> golden(opt-in) -> state file), with ours-check on the /etc/felhom-bootstrap
mount, typed vmid confirm, other-Felhom-guests safe-skip, and idempotent
tolerate-absent. Records customer_id + provisioned_vmid into the install state
(_state_put/_state_get) so uninstall resolves its target automatically. Adds
three provision pre-flight guards: multi-node (--node required), archive-storage
exists, and a RAM-floor WARN. Validated dry-run-only on felhom-pve.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 07:47:34 +02:00

100 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md).
---
# REPORT — `felhom-host-install.sh --uninstall` (clean revert) + pre-flight guards (host-install v1.3.0)
**Date:** 2026-07-01 · **Repo:** `felhom.eu` (`scripts/` only)
Colleague-safety batch **#1 (`--uninstall`) + #2 (pre-flight guards)**. Script-only. A first-class,
guarded local host-teardown mode so an operator can cleanly back out of a trial install, plus three
provision pre-flight guards. Specced, built, and validated **dry-run-only** (the live `--uninstall` is a
supervised step and was deliberately NOT run — see the STOP list).
## 1. Confirmed baseline
| Repo | `main` @ commit | Current | → Target |
|------|-----------------|---------|----------|
| felhom.eu (`scripts/felhom-host-install.sh`) | `83c4f7f7` | script **v1.2.0** | **v1.3.0** |
No agent/controller/hub change in this task.
## 2. Files changed
- `scripts/felhom-host-install.sh` (v1.2.0 → **v1.3.0**) — the only code file.
- `scripts/CHANGELOG.md` — v1.3.0 entry (newest on top; this is where the v1.2.0 entry lives).
- `REPORT.md` — this file (overwritten).
## 3. Commit hash(es)
- `<COMMIT_HASH>` on `main` (filled in after push; see §Served-copy check).
## 4. What was implemented
**Part 1 — install state records vmid + customer.** New `_state_put KEY VALUE` / `_state_get KEY`
helpers (python3, dry-run-guarded like `_state_mark`, `completed[]` shape untouched). `step_preflight`
now records `customer_id`; `step_provision` records `provisioned_vmid` on success (dry-run logs only).
**Part 2 — `--uninstall` mode** (early top-level dispatch, root-required, no `--customer-id`, no hub
contact, no passphrase). `run_uninstall` reverses install order: **guest → agent(unit+.bak / sudoers /
binary+.bak / state dir / user) → pveum(ACL user, ACL token, token, user, role) → golden(opt-in) →
state file.** Every mutation via `run()` (dry-run prints, executes nothing). Guards: ours-check on the
`/etc/felhom-bootstrap` bind mount (matched by the constant guest *path*, not a slot), typed vmid
confirmation (`/dev/tty`, skipped only in dry-run), other-Felhom-guests safe-skip (keeps host-level in
place unless `--force`), state-mismatch `--force` gate, and idempotent tolerate-absent on every object.
`--remove-golden` opt-in deletes the golden vzdump (`pvesm free`). Never removes the `sudo` package;
never contacts the hub. New helper `felhom_guests()` enumerates Felhom guests by the bootstrap mount.
**Part 3 — pre-flight guards** (all inside `step_preflight`, before any mutation → fire under dry-run):
multi-node guard (`die` unless `--node` explicit via new `NODE_EXPLICIT`; no-op single-node / under
`--skip-provision`), archive-storage-exists guard (`pvesm status --storage`; no-op under
`--skip-provision`), RAM floor WARN (`MemAvailable < 2048 MiB`, never fatal).
Confirmed the PVE 9 ACL-delete syntax live before wiring it:
`pveum acl delete <path> --users|--tokens <x> --roles <role>`.
## 5. Green gate — `bash -n` + `shellcheck`
- `bash -n scripts/felhom-host-install.sh`**OK** (locally + on felhom-pve).
- `shellcheck v0.10.0` (fetched static binary on the build server; shellcheck isn't installed on any
box): **HEAD v1.2.0 baseline = 2× SC2015 (info)**; **v1.3.0 = 2× SC2015 (info)** at lines 1128 & 1138
— both in the *pre-existing* `step_verify` (`A && B || C`), untouched by this task. **0 new warnings.**
## 6. Tests → §7 mapping (dry-run transcripts / read-only live checks on felhom-pve, single-node, live guest 9201)
| # | Scenario | Result |
|---|----------|--------|
| T-A | full clean-uninstall plan (`--uninstall --vmid 9201 --dry-run`) | **PASS** — ours-check passes, prints `pct config 9201`, would-prompt for typed confirm, then the full plan: `pct stop/destroy 9201` → agent removal (unit + all `.bak-*`, sudoers, binary + all `.bak-*`, `rm -rf /var/lib/felhom-agent`, `userdel`) → `pveum acl delete` (user, then token) → token remove → user delete → **role delete last** → golden skipped → state file rm. All `[DRY-RUN]`. `sudo` package NOT touched; hub note printed. |
| T-B | other-guests detector | **PASS**`felhom_guests()` enumeration prints only `9201` (only Felhom guest on the host). Skip-branch code-reviewed (2nd Felhom guest not available live). |
| T-C | not-ours refusal (**red-proof**) | **PASS**`--uninstall --vmid 9001 --dry-run` (9001 exists, no bootstrap mount) → `die "vmid 9001 does not look like a Felhom-provisioned guest … Refusing to destroy. Pass --force to override."`, exit 1, dies before any `run()`. Nonexistent id `987654` → safe refusal ("absent and is not the recorded provisioned_vmid … --force"). |
| T-D | multi-node guard | **PASS (single-node)**`node: demo-felhom (auto)`, guard is a no-op on the 1-node host; multi-node `die` code-reviewed. Live multi-node validation deferred (see STOP). |
| T-E | storage / RAM guards | **PASS**`--dry-run --archive-storage nonesuch``die "archive storage 'nonesuch' not found (pvesm status)…"` before the passphrase prompt; normal dry-run prints the RAM line (`free RAM: ~12251 MiB`; the `<2048` WARN branch is code-reviewed — the box has 12 GiB free). |
| T-F | dry-run executes nothing | **PASS** — after all dry-runs: `pct status 9201` = running, `felhom-agent` active, binary present, `pveum` user + role present, `state.json` unchanged (no `provisioned_vmid` added — dry-run writes nothing). |
| Part 1 | `_state_put`/`_state_get` round-trip | **PASS** — isolated temp-file test: writes top-level `customer_id`/`provisioned_vmid`, preserves `completed[]`, reads both back. |
## 7. Served-copy version check (after push)
```
curl -fsSL https://felhom.eu/scripts/felhom-host-install.sh | grep SCRIPT_VERSION
# expect: SCRIPT_VERSION="1.3.0"
```
`<RESULT after push>`
## 8. NOT yet live-validated — awaiting a supervised run
- A **real live `--uninstall`** (actual guest destroy + `pveum` role/user/token/ACL removal + `userdel`
+ state wipe). Deliberately not run per the TASK STOP — do it on the colleague's box or a throwaway
scratch guest, never the demo guest 9201.
- The **multi-node guard** on an actual 2+-node cluster (felhom-pve is single-node).
- The other-Felhom-guests safe-skip branch with a second live Felhom guest present.
## 9. Observations (noticed, NOT acted on)
- In `--dry-run`, `run_uninstall` prints `[OK] guest <vmid> destroyed` after the `[DRY-RUN] pct destroy`
lines; the trailing `[DRY-RUN]: nothing above was actually executed.` clarifies it, and this mirrors
the existing dry-run success-logging pattern — left as-is (minimal change).
- Colleague-safety batch items #3 (CPU/mem cap, agent-side) and #4 (pool-scoped ACL) are separate specs;
not touched here.