Add README with deploy instructions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,120 @@
|
|||||||
|
# Provisioning
|
||||||
|
|
||||||
|
Central control plane for a Proxmox homelab cluster. Handles PXE booting bare metal, unattended Proxmox installation, cluster join, and host lifecycle management.
|
||||||
|
|
||||||
|
## What it does
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
Admin dashboard shows real-time progress via SSE.
|
||||||
|
|
||||||
|
## 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`
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /opt/provisioning/keys
|
||||||
|
cd /opt/provisioning
|
||||||
|
|
||||||
|
# Log in to the container registry
|
||||||
|
docker login gitea.thewrightserver.net
|
||||||
|
|
||||||
|
# Pull the compose file
|
||||||
|
curl -sO https://gitea.thewrightserver.net/josh/Provisioning/raw/branch/main/docker-compose.yml
|
||||||
|
|
||||||
|
# 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.ssh_public_key` — public key injected into new hosts
|
||||||
|
- `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
|
||||||
|
|
||||||
|
Edit `server-types.yaml` with your actual hardware types.
|
||||||
|
|
||||||
|
### Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Dashboard at `http://<host>:8080`.
|
||||||
|
|
||||||
|
### Update
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose pull
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run tests
|
||||||
|
go test ./...
|
||||||
|
|
||||||
|
# Run locally (PXE disabled)
|
||||||
|
cp deploy/provisioning.example.yaml provisioning.yaml
|
||||||
|
cp deploy/server-types.example.yaml server-types.yaml
|
||||||
|
# Edit provisioning.yaml: set pxe.enabled=false, infrastructure.base_url=""
|
||||||
|
go run ./cmd/provisioning -config provisioning.yaml
|
||||||
|
|
||||||
|
# Build binary
|
||||||
|
make build
|
||||||
|
|
||||||
|
# Build Docker image locally
|
||||||
|
make docker
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
infra/ Infrastructure API client
|
||||||
|
api/ HTTP handlers (JSON API + dashboard)
|
||||||
|
httpserver/ chi router assembly
|
||||||
|
web/ Embedded static assets (CSS, JS)
|
||||||
|
```
|
||||||
|
|
||||||
|
## CI/CD
|
||||||
|
|
||||||
|
Gitea Actions workflow (`.gitea/workflows/build.yml`):
|
||||||
|
- Runs `go test` and `go vet` on every push to main
|
||||||
|
- Builds Docker image and pushes to `gitea.thewrightserver.net/josh/provisioning:latest`
|
||||||
Reference in New Issue
Block a user