From ca6e8661fc31dce9b33c844135fb4b104b18e71f Mon Sep 17 00:00:00 2001 From: josh Date: Sun, 3 May 2026 21:17:37 -0400 Subject: [PATCH] Update README with full API reference and ephemeral key docs Co-Authored-By: Claude Opus 4.6 --- README.md | 111 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 84 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 5bba2b1..cc6e63a 100644 --- a/README.md +++ b/README.md @@ -6,28 +6,39 @@ Central control plane for a Proxmox homelab cluster. Handles PXE booting bare me 1. Operator registers a host (MAC address + server type) 2. Operator triggers "rebuild with Proxmox" -3. Host PXE boots → dnsmasq responds → iPXE chain-loads the Proxmox installer -4. Installer fetches a per-host answer file (TOML) from Provisioning -5. Proxmox installs unattended → post-install webhook fires -6. Host reboots → first-boot script phones home with IP + hardware ID -7. Provisioning SSHes into the new host → `pvecm add` joins the cluster -8. Host registered in Infrastructure → marked ready +3. Provisioning generates an ephemeral SSH key pair for this rebuild +4. Host PXE boots → dnsmasq responds → iPXE chain-loads the Proxmox installer +5. Installer fetches a per-host answer file (TOML) with the ephemeral public key +6. Proxmox installs unattended → post-install webhook fires +7. Host reboots → first-boot script phones home with IP + hardware ID +8. Provisioning SSHes in using the ephemeral key → `pvecm add` joins the cluster +9. Ephemeral key removed from both the host and database +10. Host registered in Infrastructure → marked ready Admin dashboard shows real-time progress via SSE. +## Host States + +``` +registered → pxe_ready → pxe_booted → installing → installed → first_boot → joining → ready + ↓ + failed +``` + ## Deploy ### Prerequisites - Docker + Docker Compose on the target host - Host must be on the same network as the bare-metal nodes (for PXE/DHCP) -- SSH key pair for root access to new Proxmox nodes - Registry access to `gitea.thewrightserver.net` +No static SSH keys required — Provisioning generates ephemeral keys per rebuild automatically. + ### Setup ```bash -mkdir -p /opt/provisioning/keys +mkdir -p /opt/provisioning cd /opt/provisioning # Log in to the container registry @@ -39,25 +50,41 @@ curl -sO https://gitea.thewrightserver.net/josh/Provisioning/raw/branch/main/doc # Pull example configs curl -s https://gitea.thewrightserver.net/josh/Provisioning/raw/branch/main/deploy/provisioning.example.yaml -o provisioning.yaml curl -s https://gitea.thewrightserver.net/josh/Provisioning/raw/branch/main/deploy/server-types.example.yaml -o server-types.yaml - -# Copy your SSH key pair -cp /path/to/id_ed25519 ./keys/ ``` ### Configure Edit `provisioning.yaml`: -- `server.public_url` — LAN-reachable URL (e.g. `http://192.168.1.100:8080`) -- `pxe.interface` — NIC name on the host (e.g. `eth0`, `enp2s0`) -- `pxe.subnet` — LAN CIDR for proxy-DHCP -- `proxmox.existing_node` — IP of any current cluster member -- `proxmox.join_fingerprint` — from `pvecm status` on an existing node -- `credentials.root_password_hash` — `mkpasswd -m sha-512` -- `infrastructure.base_url` — URL of the Infrastructure service -- `infrastructure.server_type_map` — maps local type keys to Infrastructure IDs +| Key | Description | +|-----|-------------| +| `server.public_url` | LAN-reachable URL (e.g. `http://192.168.1.100:8080`) | +| `pxe.interface` | NIC name on the host (e.g. `eth0`, `enp2s0`) | +| `pxe.subnet` | LAN CIDR for proxy-DHCP | +| `proxmox.existing_node` | IP of any current cluster member | +| `proxmox.join_fingerprint` | From `pvecm status` on an existing node | +| `credentials.root_password_hash` | Generate with `mkpasswd -m sha-512` | +| `infrastructure.base_url` | URL of the Infrastructure service | +| `infrastructure.server_type_map` | Maps local type keys to Infrastructure IDs | -Edit `server-types.yaml` with your actual hardware types. +Edit `server-types.yaml` with your actual hardware types: + +```yaml +server_types: + minisforum-ms-01: + display_name: "Minisforum MS-01" + boot_disk: "/dev/nvme0n1" + management_nic: "enp2s0" + gpu: false + hostname_prefix: "pve-ms" + + minisforum-um790: + display_name: "Minisforum UM790 Pro" + boot_disk: "/dev/nvme0n1" + management_nic: "enp1s0" + gpu: true + hostname_prefix: "pve-um" +``` ### Run @@ -74,6 +101,36 @@ docker compose pull docker compose up -d ``` +## API + +### Host Management + +| Method | Path | Description | +|--------|------|-------------| +| GET | `/api/hosts` | List all hosts | +| GET | `/api/hosts/{id}` | Get host details | +| POST | `/api/hosts` | Register host (`hostname`, `mac`, `server_type`) | +| DELETE | `/api/hosts/{id}` | Remove host | +| POST | `/api/hosts/{id}/rebuild` | Start rebuild operation | + +### Boot Flow (called by PXE-booting hosts) + +| Method | Path | Description | +|--------|------|-------------| +| GET | `/ipxe/{mac}` | iPXE boot script | +| POST | `/api/boot/answer` | Proxmox answer file (TOML) | +| POST | `/api/hosts/{id}/installed` | Post-install webhook | +| GET | `/api/hosts/{id}/first-boot-script` | First-boot shell script | +| POST | `/api/hosts/{id}/phone-home` | First-boot reports IP + hardware ID | + +### Dashboard + +| Method | Path | Description | +|--------|------|-------------| +| GET | `/` | Host grid with live state tiles | +| GET | `/hosts/{id}` | Host detail + operation history | +| GET | `/events` | SSE stream | + ## Development ```bash @@ -98,16 +155,16 @@ make docker ``` cmd/provisioning/ Entry point, wiring, shutdown internal/ - config/ YAML config + hot-reloaded server types - db/ SQLite (WAL, embedded migrations) - model/ Domain types - store/ Hand-written SQL (hosts, operations, locks, images) + config/ YAML config + hot-reloaded server types (fsnotify) + db/ SQLite (WAL mode, embedded migrations) + model/ Domain types (Host, Operation, Image, ServerType) + store/ SQL stores (hosts, operations, locks, images) statemachine/ Table-driven host state machine events/ SSE fan-out hub - pxe/ dnsmasq supervisor, iPXE scripts, answer files - orchestrator/ Lifecycle driver (state transitions, cluster join) + pxe/ dnsmasq supervisor, iPXE scripts, answer files, first-boot + orchestrator/ Lifecycle driver (ephemeral keys, cluster join, infra registration) infra/ Infrastructure API client - api/ HTTP handlers (JSON API + dashboard) + api/ HTTP handlers (JSON API + HTML dashboard) httpserver/ chi router assembly web/ Embedded static assets (CSS, JS) ```