AtlatestRepositorycore-channel
core-channel / tree / seed / scriptsverify-sources.sh
1
#!/bin/sh2
# Verify the INPUTS the seed is about to be built from.3
#4
# This script read `$seed/MANIFEST` until 2026-07-31, and MANIFEST pins the5
# seed TARBALL -- the OUTPUT. So `build-seed.sh` checked the artifact it was6
# about to overwrite and never checked a single source it was about to compile.7
# The name said "verify-sources"; the behaviour was "verify the previous8
# output". It passed every time, which is exactly why nobody noticed.9
#10
# It also could not survive a re-pin: the moment MANIFEST's hash moves ahead of11
# the tarball on disk, a rebuild refuses for a reason that has nothing to do12
# with its sources.13
#14
# MANIFEST.sources is the input pin, and it is what this verifies.15
set -eu16
seed=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)17
manifest="$seed/MANIFEST.sources"18
[ -f "$manifest" ] || { echo "verify-sources: no $manifest" >&2; exit 1; }20
checked=021
while read -r hash url file; do22
case "$hash" in ''|'#'*) continue ;; esac23
[ -f "$seed/$file" ] || {24
echo "verify-sources: missing source $file (run bootstrap or gate-crosspath.sh)" >&225
exit 126
}27
actual=$(sha256sum "$seed/$file" | awk '{print $1}')28
[ "$actual" = "$hash" ] || {29
echo "verify-sources: sha256 mismatch: $file" >&230
echo " expected $hash" >&231
echo " actual $actual" >&232
exit 133
}34
echo "verified $file"35
checked=$((checked+1))36
done < "$manifest"38
# A loop that verified nothing exits 0 and prints nothing, which reads exactly39
# like a clean run. Refuse instead.40
[ "$checked" -gt 0 ] || {41
echo "verify-sources: REFUSING: $manifest listed no sources to verify" >&242
exit 143
}44
echo "verify-sources: $checked source(s) verified against MANIFEST.sources"