From d0ed1bda915139b292017d6efd58e319657f055a Mon Sep 17 00:00:00 2001 From: Mikhail Chusavitin Date: Thu, 3 Sep 2026 15:32:33 +0300 Subject: [PATCH] fix(iso): hash build scripts into the fast-path safety check needs_full_build() decided the fast path was safe by hashing only config inputs (VERSIONS, package lists, hooks, archives, auto/config, Dockerfile). It never hashed the build logic itself, so a change to build.sh or lib/fast-path.sh counted as a "light" file and the next build silently reused a squashfs produced by the old code. The merged-usr /lib fix in the previous commit only forced a full rebuild by accident (the overlay manifest saw firmware move from lib/ to usr/lib/). hash_heavy_config now covers every *.sh under iso/builder (build.sh, the build-*.sh helpers, lib/*.sh) plus auto/. A change to build logic is now as heavy as a package-list change. config/bootloaders stays excluded (the fast path regenerates the outer ISO layer from it every time). Hash is deterministic (LC_ALL=C sort). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01H2LLuid8PFhBqBPcxXxkQU --- iso/builder/lib/fast-path.sh | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/iso/builder/lib/fast-path.sh b/iso/builder/lib/fast-path.sh index 05390ae..03ffcf0 100755 --- a/iso/builder/lib/fast-path.sh +++ b/iso/builder/lib/fast-path.sh @@ -35,22 +35,33 @@ FULL_BUILD_HASH_FILE="${FULL_BUILD_STATE_DIR}/heavy-config.sha256" FULL_BUILD_ABI_FILE="${FULL_BUILD_STATE_DIR}/kernel-abi" FULL_BUILD_OVERLAY_MANIFEST="${FULL_BUILD_STATE_DIR}/overlay.manifest" -# Hashes the content of every "heavy" config input (VERSIONS, package lists, -# hooks, archives, auto/config, Dockerfile). Bootloader templates are excluded: -# the fast path regenerates the complete outer ISO layer from them. Deliberately content- -# based rather than mtime-based: mtimes get reset by git checkouts, rsync, and +# Hashes the content of every "heavy" build input: the build scripts themselves +# (build.sh, build-in-container.sh, the build-*.sh helpers, lib/*.sh) plus +# VERSIONS, package lists, hooks, archives, auto/, and the Dockerfile. If any of +# these change, the previous squashfs was produced by different logic or pins +# and the fast path is not safe — a change to build.sh or lib/fast-path.sh is as +# heavy as a package-list change, not a "light" file. +# +# Bootloader templates (config/bootloaders) are deliberately excluded: the fast +# path regenerates the complete outer ISO layer from them every time. +# +# Content-based, not mtime-based: mtimes get reset by git checkouts, rsync, and # retried builds in ways that don't track "did this content actually change # since the last full build", which previously let needs_full_build() silently -# take the fast path (reusing an old squashfs built against different package -# pins) with no error. +# take the fast path (reusing an old squashfs) with no error. hash_heavy_config() { ( cd "${BUILDER_DIR}" - find \ - VERSIONS auto/config Dockerfile \ - config/package-lists config/hooks config/archives \ - -type f -print0 2>/dev/null | - sort -z | + find . -type f \ + \( -name '*.sh' \ + -o -path './VERSIONS' \ + -o -path './Dockerfile' \ + -o -path './auto/*' \ + -o -path './config/package-lists/*' \ + -o -path './config/hooks/*' \ + -o -path './config/archives/*' \) \ + -print0 2>/dev/null | + LC_ALL=C sort -z | xargs -0 -r sha256sum ) | sha256sum | awk '{print $1}' }