build-golden v2.1.0 — bake EVERY infra image, asked from the controller
Enabling Megosztás on a fresh box pulled felhom-samba from the registry with zero feedback — minutes of silent nothing. Observed live, twice. Cause: this script carried its own hand-maintained array of three image tags, with a comment telling the reader to keep it in sync with the controller's internal/infra constants. It drifted the moment a fourth stack was added. felhom-samba was never added here, so the golden baked 3 of 4. The fix is structural rather than a fourth copy of the list: it now comes from the controller image the bake just pulled (--print-infra-images, backed by infra.Images(), which derives from the pins themselves). The golden bakes exactly what THAT controller version will request, so the two cannot disagree. Ordering fix this exposed: docker logout ran immediately after the controller pull, but felhom-samba is on the same private registry, so the infra loop would have 401'd. Logout moved after the loop, plus a hard assertion that no credential remains in the guest before it is archived. Pre-0.147.0 controllers have no such flag; the bake falls back to the historical 3-image list and says so loudly — the fallback IS the drift-prone thing being removed, so it must never pass silently. No agent version bump: build tooling only. Effective at the next golden build; the current golden is not rebuilt for this. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Nn3VgQk9iwEGgyx6QJ2NvE
This commit is contained in:
@@ -1,3 +1,28 @@
|
|||||||
|
## build tooling — the golden bakes EVERY infra image, asked from the controller (2026-07-19)
|
||||||
|
|
||||||
|
**No agent version bump: `configs/build-golden.sh` only (v2.0.0 → v2.1.0). Effective at the NEXT
|
||||||
|
golden build — the current golden is NOT rebuilt for this.**
|
||||||
|
|
||||||
|
- **The bug, observed live twice.** Enabling Megosztás on a fresh box pulled `felhom-samba` from the
|
||||||
|
registry with zero feedback: minutes of silent nothing. Cause: this script carried its own
|
||||||
|
hand-maintained array of three image tags, with a comment instructing the reader to keep it in sync
|
||||||
|
with the controller's `internal/infra` constants. It drifted the moment a fourth stack was added —
|
||||||
|
`felhom-samba` was never added here, so the golden baked **3 of 4**.
|
||||||
|
- **The fix is structural, not another copy.** The list now comes from the controller image the bake
|
||||||
|
just pulled: `docker run --rm <controller> --print-infra-images` (backed by `infra.Images()`, which
|
||||||
|
derives from the pins themselves). The golden therefore bakes exactly what **that** controller
|
||||||
|
version will request, and the two cannot disagree by construction. A controller-side test parses
|
||||||
|
the const block out of the source and fails if a pin is added without reaching `Images()`.
|
||||||
|
- **Ordering fix that this exposed.** `docker logout` + `config.json` removal ran immediately after
|
||||||
|
the controller pull. `felhom-samba` lives on the **same private registry**, so the infra loop would
|
||||||
|
have 401'd. The logout moved to **after** the loop, with an added hard assertion that no credential
|
||||||
|
remains in the guest before it is archived — the credential is still never baked.
|
||||||
|
- **Fallback, loudly.** A controller older than v0.147.0 has no `--print-infra-images`; the bake falls
|
||||||
|
back to the historical 3-image list and prints three WARN lines saying felhom-samba will not be
|
||||||
|
baked and Megosztás will pull at runtime. The fallback is exactly the drift-prone thing this change
|
||||||
|
removes, so it announces itself rather than passing silently.
|
||||||
|
- **ROADMAP:** golden **≥ 0.147.x** carries all four infra images.
|
||||||
|
|
||||||
## v0.90.1 — R-39 hotfix: PBS reconcile must not pass `--server` to `pvesm set` (2026-07-18)
|
## v0.90.1 — R-39 hotfix: PBS reconcile must not pass `--server` to `pvesm set` (2026-07-18)
|
||||||
|
|
||||||
**Config-only fix (wrapper + red-proof); the Go binary is unchanged.** Ship the wrapper with the
|
**Config-only fix (wrapper + red-proof); the Go binary is unchanged.** Ship the wrapper with the
|
||||||
|
|||||||
+37
-14
@@ -39,7 +39,7 @@ set -euo pipefail
|
|||||||
|
|
||||||
# Script provenance — logged into every bake transcript next to the baked controller tag, so an
|
# Script provenance — logged into every bake transcript next to the baked controller tag, so an
|
||||||
# archive can always be traced to the script that produced it. Bump on any behavior change.
|
# archive can always be traced to the script that produced it. Bump on any behavior change.
|
||||||
GOLDEN_SCRIPT_VERSION="2.0.0"
|
GOLDEN_SCRIPT_VERSION="2.1.0"
|
||||||
|
|
||||||
VMID="${1:-9100}"
|
VMID="${1:-9100}"
|
||||||
TEMPLATE="${2:-local:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst}"
|
TEMPLATE="${2:-local:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst}"
|
||||||
@@ -136,29 +136,52 @@ if [ -n "${REGISTRY_USER:-}" ] && [ -n "${REGISTRY_TOKEN:-}" ]; then
|
|||||||
pct exec "$VMID" -- bash -c "systemctl start docker; sleep 1; echo '$REGISTRY_TOKEN' | docker login '$REGISTRY_HOST' -u '$REGISTRY_USER' --password-stdin >/dev/null"
|
pct exec "$VMID" -- bash -c "systemctl start docker; sleep 1; echo '$REGISTRY_TOKEN' | docker login '$REGISTRY_HOST' -u '$REGISTRY_USER' --password-stdin >/dev/null"
|
||||||
fi
|
fi
|
||||||
pct exec "$VMID" -- bash -c "docker pull '$CONTROLLER_IMAGE'"
|
pct exec "$VMID" -- bash -c "docker pull '$CONTROLLER_IMAGE'"
|
||||||
pct exec "$VMID" -- bash -c "docker logout '$REGISTRY_HOST' >/dev/null 2>&1 || true; rm -f /root/.docker/config.json"
|
|
||||||
# Record the baked image ref for the bootstrap unit (so the unit needs no login/pull).
|
# Record the baked image ref for the bootstrap unit (so the unit needs no login/pull).
|
||||||
pct exec "$VMID" -- bash -c "printf '%s\n' '$CONTROLLER_IMAGE' > /etc/felhom-controller-image"
|
pct exec "$VMID" -- bash -c "printf '%s\n' '$CONTROLLER_IMAGE' > /etc/felhom-controller-image"
|
||||||
|
|
||||||
# Bake the base-infrastructure images (traefik, cloudflared, filebrowser) so the controller's
|
# Bake EVERY controller-managed infra image so enabling an infra stack on a fresh box is near-instant
|
||||||
# first-boot bring-up (EnsureBaseStack) is OFFLINE-capable — no registry pull at deploy. These are
|
# instead of a multi-minute silent registry pull.
|
||||||
# PUBLIC Docker Hub images (no cred needed). The PINNED tags MUST match the controller's
|
#
|
||||||
# internal/infra constants (TraefikImage / CloudflaredImage / FileBrowserImage); a drift means the
|
# THE LIST COMES FROM THE CONTROLLER WE JUST PULLED, not from a copy here. This script used to carry
|
||||||
# golden bakes one image and the controller requests another (→ a pull at deploy, defeating the goal).
|
# a hand-maintained array of three tags with a comment telling the reader to keep it in sync with the
|
||||||
INFRA_IMAGES=(
|
# controller's internal/infra constants. It drifted the moment a fourth stack was added: felhom-samba
|
||||||
"traefik:v3.6.7"
|
# was never added here, so the golden baked 3 of 4 and turning on Megosztás pulled from the registry
|
||||||
"cloudflare/cloudflared:2026.6.0"
|
# with zero UI feedback — observed live, twice. Asking the binary (`--print-infra-images`, backed by
|
||||||
"gtstef/filebrowser:1.3.3-stable"
|
# infra.Images()) makes golden-vs-controller drift structurally impossible: the golden bakes exactly
|
||||||
)
|
# what THIS controller version will request.
|
||||||
echo "[golden] baking base-infra images: ${INFRA_IMAGES[*]} …"
|
echo "[golden] asking the controller which infra images it manages …"
|
||||||
|
INFRA_LIST="$(pct exec "$VMID" -- bash -c "docker run --rm --entrypoint /usr/local/bin/felhom-controller '$CONTROLLER_IMAGE' --print-infra-images 2>/dev/null" || true)"
|
||||||
|
mapfile -t INFRA_IMAGES < <(printf '%s\n' "$INFRA_LIST" | grep -E '^[a-z0-9._/-]+:[A-Za-z0-9._-]+$' || true)
|
||||||
|
if [ "${#INFRA_IMAGES[@]}" -eq 0 ]; then
|
||||||
|
# Controllers older than v0.147.0 have no --print-infra-images. Fall back to the historical list so
|
||||||
|
# an old-controller bake still works — but say so loudly, because the fallback is exactly the
|
||||||
|
# drift-prone thing this change removed, and it CANNOT know about stacks added after it was written.
|
||||||
|
echo "[golden] WARN: '$CONTROLLER_IMAGE' does not support --print-infra-images (pre-0.147.0)."
|
||||||
|
echo "[golden] WARN: falling back to the historical 3-image list. felhom-samba will NOT be baked,"
|
||||||
|
echo "[golden] WARN: so enabling Megosztás on this golden will pull at runtime. Bake >=0.147.0."
|
||||||
|
INFRA_IMAGES=(
|
||||||
|
"traefik:v3.6.7"
|
||||||
|
"cloudflare/cloudflared:2026.6.0"
|
||||||
|
"gtstef/filebrowser:1.3.3-stable"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
echo "[golden] baking infra images (${#INFRA_IMAGES[@]}): ${INFRA_IMAGES[*]} …"
|
||||||
for img in "${INFRA_IMAGES[@]}"; do
|
for img in "${INFRA_IMAGES[@]}"; do
|
||||||
# Hard gate: fail loudly BEFORE pulling if a pinned tag doesn't resolve (a bad pin otherwise fails
|
# Hard gate: fail loudly BEFORE pulling if a pinned tag doesn't resolve (a bad pin otherwise fails
|
||||||
# mid-bake with a confusing error).
|
# mid-bake with a confusing error).
|
||||||
pct exec "$VMID" -- bash -c "docker manifest inspect '$img' >/dev/null 2>&1" \
|
pct exec "$VMID" -- bash -c "docker manifest inspect '$img' >/dev/null 2>&1" \
|
||||||
|| { echo "[golden] FATAL: pinned base-infra image does not resolve: $img"; exit 1; }
|
|| { echo "[golden] FATAL: pinned infra image does not resolve: $img"; exit 1; }
|
||||||
pct exec "$VMID" -- bash -c "docker pull '$img'"
|
pct exec "$VMID" -- bash -c "docker pull '$img'"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Log out LAST — not right after the controller pull. felhom-samba lives on the same private registry
|
||||||
|
# as the controller, so the infra loop above needs the credential; logging out first made that pull
|
||||||
|
# 401. The credential is still never archived: the logout + config.json removal happen before the
|
||||||
|
# guest is stopped and templated.
|
||||||
|
pct exec "$VMID" -- bash -c "docker logout '$REGISTRY_HOST' >/dev/null 2>&1 || true; rm -f /root/.docker/config.json"
|
||||||
|
pct exec "$VMID" -- bash -c '[ ! -s /root/.docker/config.json ]' \
|
||||||
|
|| { echo "[golden] FATAL: registry credential still present in the guest — refusing to archive"; exit 1; }
|
||||||
|
|
||||||
echo "[golden] baking the controller-bootstrap unit (deploys the BAKED controller from the config mount) …"
|
echo "[golden] baking the controller-bootstrap unit (deploys the BAKED controller from the config mount) …"
|
||||||
pct push "$VMID" /dev/stdin /usr/local/sbin/felhom-controller-bootstrap.sh --perms 700 <<'BOOTSH'
|
pct push "$VMID" /dev/stdin /usr/local/sbin/felhom-controller-bootstrap.sh --perms 700 <<'BOOTSH'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|||||||
Reference in New Issue
Block a user