diff --git a/CHANGELOG.md b/CHANGELOG.md index ec01ef4..38d3429 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,9 @@ demo boxes got them by hand. demo-hp, so they cannot be told apart). Armed: `kernel.panic = 10`. After the 2nd unclean boot within 60 min it TRIPS (`kernel.panic = 0`), so the 3rd crash within the hour leaves the box off; it re-arms after 24 h of normal running or `felhom-crash-guard rearm`. State in `/var/lib/felhom-crash-guard/state.json` (0644; read by facts). +- **After the tag (main only, not shipped to boxes): `configs/build-golden.sh` 3.1.0** — the golden's `daemon.json` + carries `"live-restore": true` with a fail-closed assertion, and `GOLDEN_DOCKER_PKGS` pins the approved Docker engine + set (all six `name=version`); without it the bake log warns that the set is the newest, not an approved one. - Tests: wrapper 76 (DockerLane, LiveRestore, Facts, RealSignatureCheck with a throwaway key), crash guard 9, Go leg + executor; red-proofs `felhom.eu/documentation/audits/os-docker-crash-2026-10-04/partB/agent-redproofs.txt` (17 caught). diff --git a/configs/build-golden.sh b/configs/build-golden.sh index db41ffa..1128186 100644 --- a/configs/build-golden.sh +++ b/configs/build-golden.sh @@ -61,7 +61,7 @@ set -euo pipefail # 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. -GOLDEN_SCRIPT_VERSION="3.0.0" +GOLDEN_SCRIPT_VERSION="3.1.0" VMID="${1:-9100}" TEMPLATE="${2:-local:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst}" @@ -112,7 +112,15 @@ for i in $(seq 1 30); do if pct exec "$VMID" -- getent hosts download.docker.com >/dev/null 2>&1; then break; fi sleep 1 done -pct exec "$VMID" -- bash -c ' +# v3.1.0 (`11` §5.8): GOLDEN_DOCKER_PKGS pins the APPROVED Docker engine set (the hub's newest Docker release, all six +# "name=version"); without it the newest stable set is installed and the bake log says so. +GOLDEN_DOCKER_PKGS="${GOLDEN_DOCKER_PKGS:-}" +if [[ -n "$GOLDEN_DOCKER_PKGS" ]]; then + echo "[golden] Docker engine set PINNED to the approved release: $GOLDEN_DOCKER_PKGS" +else + echo "[golden] WARNING: GOLDEN_DOCKER_PKGS not set — installing the newest stable Docker set, not an approved one" +fi +pct exec "$VMID" -- env GOLDEN_DOCKER_PKGS="$GOLDEN_DOCKER_PKGS" bash -c ' set -e export DEBIAN_FRONTEND=noninteractive apt-get update -qq @@ -122,7 +130,12 @@ pct exec "$VMID" -- bash -c ' echo "deb [signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian trixie stable" \ > /etc/apt/sources.list.d/docker.list apt-get update -qq - apt-get install -y -qq docker-ce docker-ce-cli containerd.io >/dev/null + if [ -n "$GOLDEN_DOCKER_PKGS" ]; then + apt-get install -y -qq $GOLDEN_DOCKER_PKGS >/dev/null + else + apt-get install -y -qq docker-ce docker-ce-cli containerd.io >/dev/null + fi + dpkg-query -W containerd.io docker-buildx-plugin docker-ce docker-ce-cli docker-ce-rootless-extras docker-compose-plugin 2>/dev/null | sed "s/^/ installed: /" ' echo "[golden] baking daemon.json: classic overlay2 driver (containerd-snapshotter OFF) + log rotation …" # containerd-snapshotter (Docker 28+/29 default) keeps the IMAGE content store under @@ -135,9 +148,12 @@ echo "[golden] baking daemon.json: classic overlay2 driver (containerd-snapshott # layout (a container's `df /` reports the single volume, phase-0 spike). Since v3.0.0 /var/lib/docker # is a BIND of /docker rather than the mp0 mount itself, wired immediately below; data-root # still needs no override because the path is unchanged. Log caps kill the most common runaway. +# v3.1.0: "live-restore": true (`09` decision 87) — a Docker engine update then restarts no app (`11` C5). A box made +# from this golden never needs the agent's one-time live-restore-on step. NEVER removed by a plain restart (R-835). pct exec "$VMID" -- bash -c 'mkdir -p /etc/docker; cat > /etc/docker/daemon.json </dev/null | sed -n "s/.*Storage Driver: //p"); [ "$drv" = "overlay2" ] || { echo "[golden] FATAL: storage driver is $drv, expected overlay2 — images would not land on the data volume"; exit 1; }' +# v3.1.0 ASSERTION: live-restore is ON in the running daemon (decision 87), or the bake fails closed. +pct exec "$VMID" -- bash -c 'lr=$(docker info --format "{{.LiveRestoreEnabled}}" 2>/dev/null); [ "$lr" = "true" ] && echo " live-restore: on" || { echo "[golden] FATAL: live-restore is $lr, expected true (decision 87)"; exit 1; }' # ASSERTION 1 (RETARGETED v3.0.0, not removed). /var/lib/docker must be a real mount — now the V-c # bind of /docker rather than the mp0 mount itself. Still fails closed on the same failure: # if the bind did not take, Docker's data-root silently sits on the OS rootfs and the golden ships