Commit 0cd1e73
fork-bootstrap: emit overlay host_vars next to overlay inventory (#35)
* fork-bootstrap: register converge-site in workflow catalog
Stage 5 of `make bootstrap` (introduced 2026-04-09) calls
`make preflight WORKFLOW=converge-site`, but the workflow was never
added to config/workflow-catalog.json. Every fresh-host bootstrap
attempt failed with "Unknown workflow: converge-site" the moment
Stages 2-4 finished green.
Register converge-site as a sibling of live-apply-site:
- requires bootstrap_ssh_private_key + controller-local-base manifest
- mutation execution_class
- 5400s budget for full-platform converge across 32 hosts
Why a new workflow rather than reusing live-apply-site: the live-apply
target also runs check-canonical-truth, vulnerability_budget, and
service_redundancy gates, all of which assume a steady-state platform.
Stage 5 must succeed on a freshly bootstrapped host before any of
those gates can be satisfied; live-apply remains the right path for
day-2 reconverges.
Part of ADR 0424 fork-clone validation.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fork-bootstrap: multi-inventory + bypass scope runner for converge-site
Three gaps that blocked Stage 5 of `make bootstrap` on a fresh host
when PLATFORM_IDENTITY_OVERLAY is set (ADR 0437 / ADR 0424):
1. ansible_scope_runner rejected multi-inventory CLI
`--inventory A -i B` silently dumped the `-i B` tail into the
`ansible_args` REMAINDER and the planner only saw the first
inventory. argparse's REMAINDER eats anything beginning with `-`
once the first positional slot is filled.
Fix: pre-normalise `-i PATH` -> `--inventory PATH` before argparse
runs (stopping at the first `--` sentinel so downstream passthroughs
stay untouched), switch `--inventory` to an appendable list, and
thread `inventory_paths` end-to-end through plan_playbook_execution,
run_planned_playbook, and discover_target_hosts so every
ansible-playbook/inventory subprocess gets every `-i`.
2. converge-site cannot be planned by the scope catalog
site.yml composes nested `import_playbook` + Jinja2 ternaries that
the scope runner's hosts-expression grammar can't resolve. For the
bootstrap path we need to run the full collection site playbook
unmediated; otherwise the planner errors out before a single task
runs. This is the same trade-off live-apply-site already accepts.
Fix: converge-site now calls `ansible-playbook` directly with both
inventories, `proxmox_guest_ssh_connection_mode=proxmox_host_jump`,
the overlay extra-vars wiring, and the bootstrap key. Preflight and
validate workflow wiring unchanged.
3. PLATFORM_IDENTITY_OVERLAY was resolved relative to the worktree
Worktrees intentionally lack `.local/` (ADR 0376), so a value like
`.local/identity.yml.0fork` crashed with "Could not find or access"
even though the overlay existed at the main repo's `.local/`.
Fix: if PLATFORM_IDENTITY_OVERLAY is a relative path starting with
`.local/`, rewrite it through LOCAL_OVERLAY_ROOT (which already
resolves to the main repo's `.local/` in worktree context).
Stage 5 run #4 with this stack applied is now actively converging
through the proxmox_network role on fork-pve-01 -- the first time the
one-command bootstrap has crossed into Stage 5 on a fresh host.
Workstream manifest: add the two scoped-runner files to
ws_0424_overlay_aware_bootstrap.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fork-bootstrap: emit overlay host_vars next to overlay inventory
Stage 4 (guest provisioning) on a fresh host consulted the committed
inventory/host_vars/proxmox-host.yml (which has production 10.10.10.X
guest IPs) instead of the fork's .local/host_vars/proxmox-host.yml
(which intended 10.20.10.X for subnet isolation). Cloud-init baked
10.10.10.X into the 17 guests, while the generated overlay inventory
declared ansible_host=10.20.10.X for SSH — so Stage 5 tried to reach
hosts that did not exist and timed out with "Connection closed by
UNKNOWN port 65535".
Root cause: Ansible only auto-discovers host_vars from directories
co-located with the inventory file. The fork layout has
.local/inventory/hosts.yml (discovered) but .local/host_vars/ (NOT
discovered because it is parallel, not child).
Fix: when generate_inventory.py is invoked with --host-vars-overlay
(overlay mode), it now also writes the merged host_vars to
<out_dir>/host_vars/proxmox-host.yml — so a typical
`.local/inventory/hosts.yml` output also produces
`.local/inventory/host_vars/proxmox-host.yml`. Ansible then sees the
fork's proxmox_guests wholesale, and Stage 4 provisions guests in the
correct subnet from the start.
Net effect: `PLATFORM_IDENTITY_OVERLAY=<path> make generate-inventory`
is now a single self-contained emission; no manual symlink or copy
into .local/inventory/host_vars/ is needed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>1 parent dece3ce commit 0cd1e73
1 file changed
Lines changed: 32 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
499 | 499 | | |
500 | 500 | | |
501 | 501 | | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
502 | 534 | | |
503 | 535 | | |
504 | 536 | | |
| |||
0 commit comments