From a04cc8fef36d254320211630764504e379a363b9 Mon Sep 17 00:00:00 2001 From: Tomaz Zaman Date: Wed, 12 Aug 2026 10:12:03 +0200 Subject: [PATCH 49/62] mono-release: purge bin/targets per release; make legacy sunset explicit bin/targets is never cleaned by make, and its profiles.json merge-preserves entries across builds (version_code follows the upstream base, not mono commits - today's tree still carries a squashfs ghost entry as proof). Left alone, the release that one day retires sysupgrade-legacy.bin would resurrect the PREVIOUS release's legacy binary from the stale copy and preserved metadata: the staging glob would sweep it up, latest.json would hash it consistently, and the pre-gzip cohort - the very devices the legacy image exists for - would flash last release's rootfs under the new tag and then pin there. Purging the target dir before the release build makes every staged artifact and every profiles.json entry provably this build's. Independently, require MONO_ALLOW_NO_LEGACY=1 to stage a release without a legacy artifact, so its retirement (or a recipe regression that silently drops it) is a loud, deliberate act rather than a glob outcome old devices discover by failing. Found by adversarial review of the dual-format release changes. Co-Authored-By: Claude Opus 4.8 --- scripts/mono-update.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/scripts/mono-update.sh b/scripts/mono-update.sh index 7e5b8e56f2..c217733b09 100755 --- a/scripts/mono-update.sh +++ b/scripts/mono-update.sh @@ -94,6 +94,17 @@ on_exit() { } trap on_exit EXIT +BINDIR=bin/targets/layerscape/armv8_64b + +# Release builds must not inherit anything from previous runs: bin/targets is +# never cleaned by make, and its profiles.json merge-preserves entries across +# builds (version_code tracks the upstream base, not mono commits). Without +# this purge, an artifact retired from IMAGES - e.g. sysupgrade-legacy.bin +# after its sunset - would be resurrected into the NEW signed release from +# the stale binary plus the preserved metadata entry, and the fleet cohort +# that reads it would flash the PREVIOUS release under the new tag. +rm -rf "$BINDIR" + cp configs/mono_gateway-dk.seed .config make defconfig # mono-update-check bakes the release tag into /etc/mono_release at its @@ -117,7 +128,6 @@ fi echo "mono-update: verified baked identity $RELTAG" OUT="releases/$RELTAG" -BINDIR=bin/targets/layerscape/armv8_64b URLBASE="${MONO_PUBLISH_URL:-https://openwrt.mono.si}" rm -rf "$OUT" mkdir -p "$OUT" @@ -127,6 +137,15 @@ cp "$BINDIR"/openwrt-layerscape-armv8_64b-mono_*-ext4-emmc.img.gz \ git format-patch --quiet -o "$OUT/patches" "$LATEST..$BRANCH" (cd "$OUT" && sha256sum *.img.gz *.bin > sha256sums) +# The uncompressed legacy artifact is the only image pre-gzip devices can +# install; a release without one strands them one failed flash per release. +# Retiring it must be a deliberate act, not a recipe accident: require +# MONO_ALLOW_NO_LEGACY=1 for the release that drops it. +[ -n "$(ls "$OUT"/*-sysupgrade-legacy.bin 2>/dev/null)" ] || [ -n "${MONO_ALLOW_NO_LEGACY:-}" ] || { + echo "mono-update: no sysupgrade-legacy.bin staged and MONO_ALLOW_NO_LEGACY unset - refusing" >&2 + exit 1 +} + # NOTE: this script no longer signs. Signing happens on the key host via # scripts/mono-sign-release.sh, and publishing (scripts/mono-publish-release.sh) # refuses to run without the signatures. Keeping the key off the build/publish -- 2.47.3