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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H2LLuid8PFhBqBPcxXxkQU
This commit is contained in:
Mikhail Chusavitin
2026-09-03 15:32:33 +03:00
co-authored by Claude Sonnet 5
parent 76db45ee95
commit d0ed1bda91
+22 -11
View File
@@ -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_ABI_FILE="${FULL_BUILD_STATE_DIR}/kernel-abi"
FULL_BUILD_OVERLAY_MANIFEST="${FULL_BUILD_STATE_DIR}/overlay.manifest" FULL_BUILD_OVERLAY_MANIFEST="${FULL_BUILD_STATE_DIR}/overlay.manifest"
# Hashes the content of every "heavy" config input (VERSIONS, package lists, # Hashes the content of every "heavy" build input: the build scripts themselves
# hooks, archives, auto/config, Dockerfile). Bootloader templates are excluded: # (build.sh, build-in-container.sh, the build-*.sh helpers, lib/*.sh) plus
# the fast path regenerates the complete outer ISO layer from them. Deliberately content- # VERSIONS, package lists, hooks, archives, auto/, and the Dockerfile. If any of
# based rather than mtime-based: mtimes get reset by git checkouts, rsync, and # 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 # 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 # since the last full build", which previously let needs_full_build() silently
# take the fast path (reusing an old squashfs built against different package # take the fast path (reusing an old squashfs) with no error.
# pins) with no error.
hash_heavy_config() { hash_heavy_config() {
( (
cd "${BUILDER_DIR}" cd "${BUILDER_DIR}"
find \ find . -type f \
VERSIONS auto/config Dockerfile \ \( -name '*.sh' \
config/package-lists config/hooks config/archives \ -o -path './VERSIONS' \
-type f -print0 2>/dev/null | -o -path './Dockerfile' \
sort -z | -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 xargs -0 -r sha256sum
) | sha256sum | awk '{print $1}' ) | sha256sum | awk '{print $1}'
} }