boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

mkrelease.sh (6308B)


      1 #!/bin/sh
      2 ## mkrelease.sh — package a per-arch boot2 release tarball.
      3 ##
      4 ## A release tarball is a self-contained bundle that lets anyone
      5 ## reproduce the full boot0..boot6 chain off the bundled inputs and
      6 ## byte-compare the outputs against a hash manifest. Layout:
      7 ##
      8 ##   boot2-<arch>[-<rev>].tar.gz
      9 ##     boot2-<arch>[-<rev>]/
     10 ##       README.md             extract + run instructions
     11 ##       verify.sh             drives boot0..boot6 + diffs OUTPUT_MANIFEST
     12 ##       INPUT_MANIFEST.txt    sha256 of every input under src/ + boot/
     13 ##       OUTPUT_MANIFEST.txt   sha256 of expected per-stage artifacts
     14 ##                             (driver-agnostic; the project's seed-accept
     15 ##                              harness verifies podman vs seed equivalence)
     16 ##       src/                  the sealed source tree (from
     17 ##                             build/<arch>/src/, produced by prep-src.sh)
     18 ##       boot/                 boot0..boot6 stage drivers + libs +
     19 ##                             containers/Containerfile.*
     20 ##
     21 ## The output manifest is generated from the current build outputs in
     22 ## build/<arch>/<driver>/boot{0..6}/. mkrelease.sh does NOT rebuild;
     23 ## prereqs (`make all ARCH=<arch>`) must already have run.
     24 ##
     25 ## Usage: tools/mkrelease.sh <arch>
     26 ##   <arch> ∈ {aarch64, amd64, riscv64}
     27 ## Env:
     28 ##   DRIVER  podman (default) | seed   — which build tree to hash for the
     29 ##                                       output manifest. The manifest is
     30 ##                                       claimed driver-agnostic regardless.
     31 ##
     32 ## The tarball name is `boot2-<arch>.tar.gz` — deliberately rev-free, so
     33 ## the tarball's sha256 reflects content and nothing else. Provenance
     34 ## (git rev, build timestamp) lives in a sidecar produced by the
     35 ## validated mint path (tools/release.sh), not inside the tarball.
     36 
     37 set -eu
     38 
     39 ARCH=${1:-}
     40 case "$ARCH" in
     41     aarch64|amd64|riscv64) ;;
     42     *) echo "usage: $0 <aarch64|amd64|riscv64>" >&2; exit 2 ;;
     43 esac
     44 
     45 DRIVER=${DRIVER:-podman}
     46 case "$DRIVER" in
     47     podman|seed) ;;
     48     *) echo "[mkrelease] unknown DRIVER=$DRIVER (expected podman|seed)" >&2; exit 2 ;;
     49 esac
     50 
     51 ROOT=$(cd "$(dirname "$0")/.." && pwd)
     52 cd "$ROOT"
     53 
     54 case "$ARCH" in
     55     aarch64) KERNEL_NAME=Image ;;
     56     amd64)   KERNEL_NAME=kernel.elf ;;
     57     riscv64) KERNEL_NAME=kernel.elf ;;
     58 esac
     59 
     60 NAME=boot2-$ARCH
     61 
     62 SRC_TREE=build/$ARCH/src
     63 BUILD_TREE=build/$ARCH/$DRIVER
     64 REL_DIR=build/$ARCH/release
     65 STAGING=$REL_DIR/$NAME
     66 TARBALL=$REL_DIR/$NAME.tar.gz
     67 
     68 [ -d "$SRC_TREE" ]                || { echo "[mkrelease] missing $SRC_TREE — run bootprep/prep-src.sh $ARCH" >&2; exit 1; }
     69 [ -f "$BUILD_TREE/boot6/$KERNEL_NAME" ] || { echo "[mkrelease] missing $BUILD_TREE/boot6/$KERNEL_NAME — run 'make all ARCH=$ARCH DRIVER=$DRIVER'" >&2; exit 1; }
     70 
     71 # Portable sha256. Use sha256sum if present; else shasum -a 256.
     72 if command -v sha256sum >/dev/null 2>&1; then
     73     sha256() { sha256sum "$1" | awk '{print $1}'; }
     74 else
     75     sha256() { shasum -a 256 "$1" | awk '{print $1}'; }
     76 fi
     77 
     78 echo "[mkrelease] staging -> $STAGING"
     79 rm -rf "$STAGING"
     80 mkdir -p "$STAGING"
     81 
     82 # ── (1) sealed source tree ────────────────────────────────────────────
     83 cp -R "$SRC_TREE" "$STAGING/src"
     84 
     85 # ── (2) boot drivers (boot/*.sh, lib-*.sh, containers/Containerfile.*) ─
     86 cp -R boot "$STAGING/boot"
     87 
     88 # ── (3) README + verify.sh templates ──────────────────────────────────
     89 cp tools/release/README.md "$STAGING/README.md"
     90 cp tools/release/verify.sh "$STAGING/verify.sh"
     91 chmod +x "$STAGING/verify.sh"
     92 
     93 # Substitute @ARCH@ / @KERNEL_NAME@ into shipped docs/scripts. No git
     94 # rev is embedded — content stays rev-free so sha256 reflects content.
     95 for f in "$STAGING/README.md" "$STAGING/verify.sh"; do
     96     sed -i.bak \
     97         -e "s/@ARCH@/$ARCH/g" \
     98         -e "s/@KERNEL_NAME@/$KERNEL_NAME/g" \
     99         "$f"
    100     rm -f "$f.bak"
    101 done
    102 
    103 # ── (4) INPUT_MANIFEST.txt ────────────────────────────────────────────
    104 echo "[mkrelease] input manifest"
    105 INMAN=$STAGING/INPUT_MANIFEST.txt
    106 tools/release/input-manifest.sh "$STAGING/src" "$STAGING/boot" "$INMAN"
    107 n_in=$(wc -l < "$INMAN" | tr -d ' ')
    108 
    109 # ── (5) OUTPUT_MANIFEST.txt ───────────────────────────────────────────
    110 # Per-stage key artifacts (mirrors the stamp-anchored declarations in
    111 # the top-level Makefile). Driver-agnostic.
    112 gen_outputs() {
    113     cat <<EOF
    114 boot0/hex2
    115 boot0/catm
    116 boot0/M0
    117 boot1/M1pp
    118 boot1/hex2pp
    119 boot2/catm
    120 boot2/scheme1
    121 boot3/tcc0
    122 boot3/libc.P1pp
    123 boot3/tcc.flat.P1pp
    124 boot4/tcc1
    125 boot4/tcc2
    126 boot4/hello
    127 boot4/crt1.o
    128 boot4/libc.a
    129 boot4/libtcc1.a
    130 boot5/libc.a
    131 boot5/crt1.o
    132 boot5/crti.o
    133 boot5/crtn.o
    134 boot5/hello
    135 boot6/$KERNEL_NAME
    136 EOF
    137 }
    138 
    139 echo "[mkrelease] output manifest (from $BUILD_TREE)"
    140 OUTMAN=$STAGING/OUTPUT_MANIFEST.txt
    141 : > "$OUTMAN"
    142 rm -f "$OUTMAN.missing"
    143 gen_outputs | while read -r rel; do
    144     [ -n "$rel" ] || continue
    145     f=$BUILD_TREE/$rel
    146     if [ -e "$f" ]; then
    147         h=$(sha256 "$f")
    148         printf '%s  %s\n' "$h" "$rel" >> "$OUTMAN"
    149     else
    150         printf '%s\n' "$rel" >> "$OUTMAN.missing"
    151     fi
    152 done
    153 if [ -s "$OUTMAN.missing" ]; then
    154     echo "[mkrelease] FAIL: missing expected outputs under $BUILD_TREE:" >&2
    155     sed 's/^/  /' "$OUTMAN.missing" >&2
    156     echo "[mkrelease]   run 'make all ARCH=$ARCH DRIVER=$DRIVER' (and boot5) first" >&2
    157     rm -f "$OUTMAN.missing"
    158     exit 1
    159 fi
    160 n_out=$(wc -l < "$OUTMAN" | tr -d ' ')
    161 
    162 # ── (6) tarball — deterministic ──────────────────────────────────────
    163 echo "[mkrelease] tar -> $TARBALL"
    164 TARBALL_ABS=$PWD/$TARBALL
    165 tools/release/tar-payload.sh "$STAGING" "$TARBALL_ABS"
    166 
    167 # Tarball digest (echoed for release notes; not embedded in the tar).
    168 TAR_SHA=$(sha256 "$TARBALL")
    169 printf '%s  %s\n' "$TAR_SHA" "$NAME.tar.gz" > "$REL_DIR/$NAME.tar.gz.sha256"
    170 
    171 bytes=$(wc -c < "$TARBALL" | tr -d ' ')
    172 echo "[mkrelease] OK"
    173 echo "[mkrelease]   tarball : $TARBALL  ($bytes bytes)"
    174 echo "[mkrelease]   sha256  : $TAR_SHA"
    175 echo "[mkrelease]   inputs  : $n_in files"
    176 echo "[mkrelease]   outputs : $n_out artifacts"