verify.sh (4117B)
1 #!/bin/sh 2 ## verify.sh — drive boot0..boot6 off the bundled inputs and compare 3 ## the outputs against OUTPUT_MANIFEST.txt. 4 ## 5 ## This script ships inside a boot2-@ARCH@ release tarball. It 6 ## stages the sealed src/ tree at build/@ARCH@/src/ (the layout every 7 ## boot/bootN.sh expects), runs the chain end-to-end, then diffs each 8 ## per-stage artifact's sha256 against the bundled manifest. 9 ## 10 ## Usage: 11 ## ./verify.sh # build + verify (DRIVER=podman default) 12 ## DRIVER=seed ./verify.sh # re-run inside the boot6-built kernel 13 ## # (requires one prior DRIVER=podman pass) 14 ## ./verify.sh --check-only # skip build; just diff existing outputs 15 ## 16 ## Env passthrough: BOOT3_TIMEOUT, BOOT4_TIMEOUT, BOOT5_TIMEOUT, 17 ## BOOT6_TIMEOUT, QEMU_MEM — see boot/boot.sh --help. 18 19 set -eu 20 21 ARCH=@ARCH@ 22 KERNEL_NAME=@KERNEL_NAME@ 23 DRIVER=${DRIVER:-podman} 24 25 CHECK_ONLY=0 26 case "${1:-}" in 27 --check-only) CHECK_ONLY=1 ;; 28 -h|--help) 29 sed -n '2,18p' "$0" | sed 's/^## \{0,1\}//' 30 exit 0 31 ;; 32 '') ;; 33 *) echo "verify.sh: unknown argument '$1' (try --help)" >&2; exit 2 ;; 34 esac 35 36 case "$DRIVER" in 37 podman|seed) ;; 38 *) echo "[verify] unknown DRIVER=$DRIVER (expected podman|seed)" >&2; exit 2 ;; 39 esac 40 41 ROOT=$(cd "$(dirname "$0")" && pwd) 42 cd "$ROOT" 43 44 # Portable sha256. 45 if command -v sha256sum >/dev/null 2>&1; then 46 sha256() { sha256sum "$1" | awk '{print $1}'; } 47 else 48 sha256() { shasum -a 256 "$1" | awk '{print $1}'; } 49 fi 50 51 # ── (0) macOS/podman preflight ──────────────────────────────────────── 52 # `podman machine` on macOS only shares /Users/ from the host. Extracting 53 # the tarball under /tmp (= /private/tmp) or anywhere outside /Users/ 54 # makes the bind mounts invisible to the VM and boot0 fails with a 55 # cryptic `Error: statfs ... no such file or directory`. Catch it here 56 # with a clearer message. 57 if [ "$CHECK_ONLY" = 0 ] && [ "$DRIVER" = podman ] && [ "$(uname -s)" = Darwin ]; then 58 case "$ROOT" in 59 /Users/*) ;; 60 *) cat >&2 <<EOF 61 [verify] this tarball was extracted to: 62 [verify] $ROOT 63 [verify] on macOS, the podman VM only shares /Users/ from the host. 64 [verify] Bind mounts under any other path (incl. /tmp, /private/tmp) 65 [verify] will fail at runtime. Re-extract somewhere under \$HOME and 66 [verify] run ./verify.sh from there. 67 EOF 68 exit 2 ;; 69 esac 70 fi 71 72 # ── (1) stage sealed src tree into expected layout ──────────────────── 73 mkdir -p "build/$ARCH" 74 if [ ! -d "build/$ARCH/src" ]; then 75 echo "[verify] staging src/ -> build/$ARCH/src/" 76 cp -R src "build/$ARCH/src" 77 fi 78 79 # ── (2) drive boot0..boot6 ──────────────────────────────────────────── 80 if [ "$CHECK_ONLY" = 0 ]; then 81 export DRIVER 82 for s in 0 1 2 3 4 5 6; do 83 echo "[verify] boot$s" 84 ./boot/boot$s.sh "$ARCH" 85 done 86 fi 87 88 # ── (3) diff outputs vs OUTPUT_MANIFEST.txt ─────────────────────────── 89 BUILD_TREE=build/$ARCH/$DRIVER 90 echo "[verify] diff $BUILD_TREE vs OUTPUT_MANIFEST.txt" 91 fail=0 92 ok=0 93 miss=0 94 while IFS= read -r line; do 95 case "$line" in 96 ''|\#*) continue ;; 97 esac 98 want=$(printf '%s' "$line" | awk '{print $1}') 99 rel=$(printf '%s' "$line" | awk '{print $2}') 100 f=$BUILD_TREE/$rel 101 if [ ! -e "$f" ]; then 102 printf 'MISSING %s\n' "$rel" 103 miss=$((miss + 1)) 104 fail=$((fail + 1)) 105 continue 106 fi 107 got=$(sha256 "$f") 108 if [ "$got" = "$want" ]; then 109 printf 'OK %s\n' "$rel" 110 ok=$((ok + 1)) 111 else 112 printf 'DIFFER %s\n' "$rel" 113 printf ' want %s\n' "$want" 114 printf ' got %s\n' "$got" 115 fail=$((fail + 1)) 116 fi 117 done < OUTPUT_MANIFEST.txt 118 119 echo "[verify] ok=$ok missing=$miss differ=$((fail - miss)) (driver=$DRIVER)" 120 if [ "$fail" -gt 0 ]; then 121 echo "[verify] FAIL" >&2 122 exit 1 123 fi 124 echo "[verify] PASS"