# Felhom host scripts Operator-side scripts for standing up a Felhom Proxmox host. ## `felhom-host-install.sh` — Day-0 host bootstrap (operator-deploy) Run on a **freshly-PVE-installed** box to fully automate Day-0: Proxmox API token → hub host enrollment (single secret) → agent config → guest provision → verify. It composes already-proven mechanisms (the `pveum` role/token sequence, the hub `POST /host-enroll` enrollment from option C, and `felhom-agent --selftest=provision`). The agent renders `bootstrap.json` into the guest and the **controller pulls its own `controller.yaml`** in-guest — the script never fetches it. Grounding: [`documentation/audits/SPIKE-day0-firstboot-handshake-2026-06-26.md`](../documentation/audits/SPIKE-day0-firstboot-handshake-2026-06-26.md). ### Prerequisites (manual, before running) 1. **Install Proxmox VE 9.x** on the box. During the installer, use **Advanced → LVM** sizing so `local-lvm` (the `pve/data` thin pool) has enough room for the appliance volumes — a useful box wants **≥ ~120 GiB** free on `local-lvm` (rootfs 32G + Docker-data ~200G + user-data ~50G after grows). The script refuses below the hard minimum. 2. **SSH into the box as root.** 3. **Create the customer in the hub first** (hub UI → new customer). The customer's **retrieval passphrase** (a 5-word Hungarian phrase) is the only secret you carry to the box. 4. A **golden archive** must exist on the archive storage (newest `vzdump-lxc-`). If none exists, build one with `felhom-agent/configs/build-golden.sh` first. 5. The **felhom-agent binary** + its systemd unit installed (the script auto-detects the unit's `-config` path; if the binary is absent it tells you to install it). ### Usage ```bash curl -fsSL https://felhom.eu/scripts/felhom-host-install.sh -o felhom-host-install.sh chmod +x felhom-host-install.sh # secure no-echo passphrase prompt: sudo ./felhom-host-install.sh --customer-id # or from a 0600 file (no prompt): sudo ./felhom-host-install.sh --customer-id --passphrase-file /root/.pass # preview every mutating command without executing: sudo ./felhom-host-install.sh --customer-id --dry-run # resume after a fixed mid-way failure (skips completed steps): sudo ./felhom-host-install.sh --customer-id --resume ``` The passphrase is read **no-echo** or from a **0600 file** — never a CLI argument, never echoed, never written to the state file or logs. The minted Proxmox-token secret and the per-host hub api_key live **only** in the agent config (`0600`, root). ### Key options | Option | Default | Purpose | |--------|---------|---------| | `--customer-id ID` | (required) | customer (must already exist in the hub) | | `--vmid N` | `9201` | guest VMID to provision | | `--golden VOLID` | newest `vzdump-lxc-` | golden archive | | `--rootfs/--datavol/--sysdata-grow N` | auto-compute | volume grows (GiB over the golden base 32/16/8) | | `--passphrase-file PATH` | no-echo prompt | read passphrase from a 0600 file | | `--preserve-from PATH` | — | merge non-Day-0 sections (PBS/local_api/privileged/authz) from an existing config | | `--dry-run` / `--resume` / `--force` | off | preview / resume / clobber an existing vmid | | `--mode provision\|dr` | `provision` | `dr` is a documented 10D stub (not implemented) | ### Behaviour notes - **Idempotent + resumable.** A step-state file (`/var/lib/felhom-install/state.json`) records completed steps; `--resume` skips them. A plain re-run **refuses** to clobber an existing `--vmid` (pass `--force` to override). - **Single-secret enrollment.** `POST /host-enroll` mints on first call (201) and **reuses** the credential on later calls (200) — re-running never orphans a running agent's key. The global operator key is never used. - **Token automation.** Creates/normalises the 16-priv `FelhomAgent` role, the `felhom-agent@pve` user + privsep token, and **both** ACL grants (user **and** token — the ACL is applied *after* the token exists, because `pveum user token remove` purges it). - **DR mode** (`--mode dr`) is a documented seam only — it restores the customer's **own** PBS whole-CT snapshot instead of the golden. Not implemented (10D). ### Productionization hooks (not done here) - **Serving:** place this file where the felhom.eu site serves it at `https://felhom.eu/scripts/felhom-host-install.sh` (a static route; verify on deploy). - **Agent binary delivery:** the script expects the agent pre-installed; a fetch-from-release step is the documented hook. - **Golden delivery:** the test used a local golden; central download + checksum verify is the remaining hook.