skill(build-deploy): the installer ISO — the one artifact the skill promised and omitted
gates / gates (push) Successful in 7s
gates / gates (push) Successful in 7s
The skill's own description claimed 'ANY Felhom artifact' and 'publish', and had no ISO section — a description asserting coverage that did not exist. Description corrected and a section added. POINTERS, NOT COPIES. The 13-criterion release gate stays in documentation/runbooks/iso-release-gate.md and the measurements stay in the four spike audits; duplicating them into a skill guarantees drift (the R-94/R-128 class). What the skill adds is the ROUTING that was missing: nothing told anyone the gate exists, which is R-29's exact shape. Records the two modes (--release public vs --pairing appliance) because picking the wrong one ships the wrong product, the build and publish commands (rclone env-only, so no credential file is ever written), and the round-trip verification. The traps it carries existed only in commit messages until now, and each cost a wrong diagnosis: - 'qm set --scsi0 ... --boot order=' in ONE call silently yields boot: order=net0;ide2 - after install the CD must be detached, or a COMPLETED install looks exactly like a stuck one - verify focus by screendump before every Enter (GTK Enter lands in fields, not Next) - proof installs register appliances; the verb is POST /appliances/<id>/discard, not /delete - scratch storage at the /mnt/nvme-1tb ROOT (a subdirectory reads disconnected forever) Also flags that the ISO gate is NOT wired into repo_gates.py, so nothing reminds you to run it. Docs only. python3 scripts/repo_gates.py --fast: all gates OK (rc=0).
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: felhom-build-deploy
|
name: felhom-build-deploy
|
||||||
description: Build, deploy, publish, or verify ANY Felhom artifact — felhom-controller image (guest 9201 bootstrap deploy), felhom-agent binary (felhom-pve), felhom-hub (GitOps/ArgoCD), the felhom.eu website (git-sync), or the app catalog. Use whenever the task says build, deploy, ship, release, publish, bump version, restart the controller/agent/hub, or verify what version is live. Contains the exact verified commands and the gotchas that silently break deploys.
|
description: Build, deploy, publish, or verify ANY Felhom artifact — felhom-controller image (guest 9201 bootstrap deploy), felhom-agent binary (felhom-pve), felhom-hub (GitOps/ArgoCD), the felhom.eu website (git-sync), the app catalog, or the PUBLIC installer ISO (iso.felhom.eu). Use whenever the task says build, deploy, ship, release, publish, bump version, restart the controller/agent/hub, or verify what version is live. Contains the exact verified commands and the gotchas that silently break deploys.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Felhom build & deploy runbooks
|
# Felhom build & deploy runbooks
|
||||||
@@ -75,6 +75,72 @@ Publish to Gitea (so Day-0 self-install can fetch it): `scripts/publish-agent.sh
|
|||||||
`REGISTRY_*` creds. The hub's Day-0 artifact manifest must then vouch the new version — that UI is
|
`REGISTRY_*` creds. The hub's Day-0 artifact manifest must then vouch the new version — that UI is
|
||||||
operator-password-gated (CC cannot); flag it as an operator follow-up.
|
operator-password-gated (CC cannot); flag it as an operator follow-up.
|
||||||
|
|
||||||
|
## Installer ISO (felhom.eu/scripts/iso → iso.felhom.eu) — PUBLIC, irreversible
|
||||||
|
|
||||||
|
**Two modes, and picking the wrong one ships the wrong product.**
|
||||||
|
|
||||||
|
| Mode | What it is | Menu |
|
||||||
|
|---|---|---|
|
||||||
|
| `--release` | the **public** image. No `answer.toml`, no root password, no SSH key, no disk profile. Day-0 rides a `.deb`. | TWO interactive entries, graphical default, timeout 15s |
|
||||||
|
| `--pairing` / `--bootstrap-env` | operator-built **appliance** image: baked answer file, baked root hash, a disk profile pinned to one machine | ONE automated entry |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# build the public image (clean-tree gate first — an unpushed change does not exist)
|
||||||
|
export FELHOM_ISO_OUT=$FELHOM_ROOT/felhom-iso/out
|
||||||
|
bash scripts/iso/build-felhom-iso.sh \
|
||||||
|
--pve-iso $FELHOM_ROOT/drill/proxmox-ve_9.2-1.iso \
|
||||||
|
--iso-sha256 4e88fe416df9b527624a175f24c9aa07c714d3332afb1ee3dbf3879573ef2c6c --release
|
||||||
|
# -> $FELHOM_ISO_OUT/felhom-installer-<VER>-pve<PVE>.iso + .sha256 + .manifest.txt (NO .rootpw.txt)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Before publishing, two hard gates — neither is optional and neither is a script yet:**
|
||||||
|
|
||||||
|
1. **`documentation/runbooks/iso-release-gate.md`** — 13 criteria, run against **the exact file you
|
||||||
|
will upload**, not the build inputs. It is a manual checklist; `repo_gates.py` does **not** cover
|
||||||
|
it, so nothing will remind you (R-29's shape — say so if you skip it).
|
||||||
|
2. **A proof install from the built image on BOTH menu entries** (graphical *and* Terminal UI), each
|
||||||
|
showing: package installed, unit `enabled`, unit fired on first boot, and a pairing code in
|
||||||
|
`/etc/felhom/appliance-pairing-code`. Spike 4 *reasoned* the graphical path follows from shared
|
||||||
|
`Install.pm`; the 1.26.0 run proved that reasoning insufficient in a different place — do both.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# publish — rclone in a container, env-only config, so NO credential file is ever written
|
||||||
|
source ~/.config/credentials # ISO_S3_CLIENT_AK / _SK / ISO_S3_URL — never echo, never log
|
||||||
|
docker run --rm -v $FELHOM_ISO_OUT:/data:ro \
|
||||||
|
-e RCLONE_CONFIG_R2_TYPE=s3 -e RCLONE_CONFIG_R2_PROVIDER=Cloudflare \
|
||||||
|
-e RCLONE_CONFIG_R2_ACCESS_KEY_ID="$ISO_S3_CLIENT_AK" \
|
||||||
|
-e RCLONE_CONFIG_R2_SECRET_ACCESS_KEY="$ISO_S3_CLIENT_SK" \
|
||||||
|
-e RCLONE_CONFIG_R2_ENDPOINT="$ISO_S3_URL" \
|
||||||
|
-e RCLONE_CONFIG_R2_REGION=auto -e RCLONE_CONFIG_R2_NO_CHECK_BUCKET=true \
|
||||||
|
rclone/rclone:latest copy /data R2:felhom-iso --include "felhom-installer-<VER>*" --s3-chunk-size 64M
|
||||||
|
# verify by ROUND TRIP — the downloaded bytes, not the local file
|
||||||
|
curl -fsSL -o /tmp/rt.iso https://iso.felhom.eu/felhom-installer-<VER>-pve<PVE>.iso && sha256sum /tmp/rt.iso
|
||||||
|
```
|
||||||
|
|
||||||
|
`ListBuckets` 403s — the token is object-scoped; list with `lsf R2:felhom-iso`, not `lsd R2:`.
|
||||||
|
|
||||||
|
### Proof-VM traps — every one of these cost a wrong diagnosis
|
||||||
|
|
||||||
|
- **Set `--boot` in a SEPARATE `qm set`, after the disk exists.** `qm set <id> --scsi0 … --boot order="scsi0;ide2"`
|
||||||
|
in one call silently yields `boot: order=net0;ide2`; the VM netboots, fails, falls through to the CD.
|
||||||
|
- **After the install, detach the CD** (`qm set <id> --delete ide2; qm set <id> --boot order="scsi0"`)
|
||||||
|
or the machine re-enters the installer on reboot — **a completed install looks exactly like a stuck one.**
|
||||||
|
Judge completion from `qm config` + disk usage, never from the screen.
|
||||||
|
- **Verify focus by screendump before every `Enter`.** TUI: red-highlighted button, tab order. GTK:
|
||||||
|
dashed focus ring, and `Enter` lands in text *fields*, not `Next`. Not checking once aborted an install.
|
||||||
|
- **Proof installs register unclaimed appliances at the hub — discard them** or R-131 grows:
|
||||||
|
`curl -u ":$HUB_PW" -X POST http://<hub-clusterIP>:8080/appliances/<id>/discard` → 303.
|
||||||
|
The verb is **`/discard`**, POST only (`hub/internal/web/server.go:345`); `/delete` 404s.
|
||||||
|
- Venue: `demo-hp`, scratch `dir` storage at **`/mnt/nvme-1tb` root** (a subdirectory reads
|
||||||
|
`disconnected` forever — the agent's `exactMount` check). Never `local-lvm`. Remove the storage at teardown.
|
||||||
|
|
||||||
|
**Why the shape is what it is** (do not re-derive; four spikes measured it):
|
||||||
|
`documentation/audits/SPIKE-universal-iso-{1,2,3,4}-2026-07-31.md`. In short — no udev property
|
||||||
|
distinguishes an internal disk from a customer's backup drive and a two-disk filter match silently
|
||||||
|
wipes one, so **there is no safe automated disk selection for unseen hardware**; and `[first-boot]`
|
||||||
|
is never placed on the system by an interactive install, so day-0 rides a `.deb` in
|
||||||
|
`/proxmox/packages/` instead (`Install.pm:1343-1372`).
|
||||||
|
|
||||||
## Hub (felhom.eu/hub → k3s, GitOps via ArgoCD app `felhom`)
|
## Hub (felhom.eu/hub → k3s, GitOps via ArgoCD app `felhom`)
|
||||||
|
|
||||||
**The manifest is the truth.** A code push + image build deploys NOTHING until `manifests/hub.yaml`'s
|
**The manifest is the truth.** A code push + image build deploys NOTHING until `manifests/hub.yaml`'s
|
||||||
|
|||||||
Reference in New Issue
Block a user