mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 19:01:54 +00:00
In job 91983553540 all five lab nodes derived the same pool name, infinito_ci_unknown, and the run died on `cannot destroy 'infinito_ci_unknown': pool is busy`. The name came from `hostname`, which returns non-zero inside the node containers, so the `|| echo unknown` fallback answered for every one of them. One node won the race and created the pool; the others found it, took it for a leftover, and tried to tear down a pool a sibling was actively using.234c1158calready fixed this collision class three days ago by deriving the name from `hostname` instead of a constant, and its message named the zfs exclusion in resolve.sh as the only thing keeping the collision out of sight. That fix was never exercised, because the exclusion stayed up untiled1121053removed it - and it does not work, because the call it rests on fails in the containers it was written for. Guessing the identity is the defect; the playbook has known it all along as inventory_hostname, and ci/one.sh knows its own deploy mode. Both now state it, as a required fourth argument with no default, the way SIZE is already stated. verdict() stops guessing too: every row it wrote into the job summary said `unknown`, which is why the summary was never worth reading. The second half is independent of the naming. reclaim_stale_pool ran `zpool destroy -f` as a bare command under `set -euo pipefail`, the only failure path in this script that bypassed decline(). A pool that refuses to be destroyed is by definition not a leftover - something holds it - so that case now declines through the usual contract: a drawn pick falls back and reports, a stated one fails loudly as required-but-unavailable. A reclaim can no longer be more destructive than the state it exists to clean up. Verified over the real invocation path rather than a model of it: an ansible-playbook run using the same `script:` task and docker connection as compose/swarm/playbook.yml, against three containers in one play, has each node address its own pool - infinito_ci_race-mgr-01, -wrk-01, -nfs-01 - with failed=0 throughout. A stubbed-pool harness covers the paths that need a kernel module this machine does not have: a sibling holding the pool declines with rc 0 instead of ending the run, the same case with a stated pick exits 1 through the contract, a genuine leftover is still destroyed, and a missing identity is a hard error. The earlier replacement harness (ext4 recognised, btrfs replacing it, no loop leaked) still passes against the stricter signature. Pool names now carry dashes, which zfs_namecheck.c accepts; at 42 characters they sit far inside the 240 limit and match no reserved prefix. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CI Deploy Scripts
This directory holds the executable CI deploy flows under scripts/tests/deploy/ci/.
For local deploy flows, use ../local/README.md.
Entry Points
| Script | What it does | Notes |
|---|---|---|
all.sh |
Runs one app across all selected distros, serially. | Uses dedicated.sh for the per-distro deploy loop. |
dedicated.sh |
Deploys one app on one distro twice against the same stack. | Performs the full CI cleanup after the run. |