Menu
BifrOSt
publicLatest change 2470f865b919f6a226354bc329a8ee630f90cd70 - Fix black-screen boot by normalizing installed /etc permissions by Ólafur Búi Ólafsson
#!/usr/bin/env bash
#
# build-iso.sh - Build the BifrOSt live/install ISO with archiso/mkarchiso.
#
# Runs the full local ISO build pipeline from a repository checkout:
#
# 1. Verify the signed installer package seed is present and valid
# (prepare-installer-cache.py --require). A verified seed is mandatory
# before an ISO build.
# 2. Optionally restage installed-system release metadata when a source
# revision is supplied (generate-release-metadata.py --prepare-installed).
# The tracked profile already carries staged metadata, so this step is
# opt-in and only needed when cutting a new revision.
# 3. Validate the profile, sources, and release contract (validate-build.py)
# unless --skip-validate is given.
# 4. Build the ISO with mkarchiso.
# 5. Print the resulting ISO path, size, and SHA-256.
#
# Builds run on Titan, never on a laptop. mkarchiso requires root, so run this
# script with sudo (or as root). Scratch and output live under the repository's
# .tmp/ per the workspace temporary-work policy. See docs/build-iso.md.
#
set -Eeuo pipefail
REPO_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
WORK_DIR="$REPO_ROOT/.tmp/iso-work"
OUT_DIR="$REPO_ROOT/.tmp/iso-out"
PROFILE_DIR="$REPO_ROOT/profile"
SKIP_VALIDATE=0
KEEP_WORK=0
SOURCE_REVISION=""
SOURCE_DATE_EPOCH_ARG=""
usage() {
cat <<'USAGE'
Usage: sudo ./build-iso.sh [options]
Build the BifrOSt live/install ISO from a repository checkout.
Pipeline:
1. Verify the installer package seed (prepare-installer-cache.py --require)
2. Optionally restage release metadata (generate-release-metadata.py)
3. Validate profile and release contract (validate-build.py)
4. Build the ISO (mkarchiso -v -r)
5. Report the ISO path, size, and SHA-256
Options:
-w, --work-dir DIR Scratch build directory (default: .tmp/iso-work)
-o, --out-dir DIR ISO output directory (default: .tmp/iso-out)
-p, --profile DIR archiso profile directory (default: profile)
--source-revision REV Restage installed release metadata for REV (40/64 hex)
--source-date-epoch N Epoch for metadata restaging (default: REV commit time)
--skip-validate Skip validate-build.py (not recommended)
--keep-work Keep the scratch work directory after building
-h, --help Show this help and exit
mkarchiso requires root; run with sudo. Builds run on Titan, never a laptop.
USAGE
}
die() { printf 'build-iso: %s\n' "$*" >&2; exit 1; }
log() { printf '\n==> %s\n' "$*"; }
while (( $# )); do
case "$1" in
-w|--work-dir) [[ $# -ge 2 ]] || die "$1 needs a value"; WORK_DIR="$2"; shift 2 ;;
-o|--out-dir) [[ $# -ge 2 ]] || die "$1 needs a value"; OUT_DIR="$2"; shift 2 ;;
-p|--profile) [[ $# -ge 2 ]] || die "$1 needs a value"; PROFILE_DIR="$2"; shift 2 ;;
--source-revision) [[ $# -ge 2 ]] || die "$1 needs a value"; SOURCE_REVISION="$2"; shift 2 ;;
--source-date-epoch) [[ $# -ge 2 ]] || die "$1 needs a value"; SOURCE_DATE_EPOCH_ARG="$2"; shift 2 ;;
--skip-validate) SKIP_VALIDATE=1; shift ;;
--keep-work) KEEP_WORK=1; shift ;;
-h|--help) usage; exit 0 ;;
*) usage >&2; die "unknown argument: $1" ;;
esac
done
(( EUID == 0 )) || die "must run as root (mkarchiso needs root); use: sudo $0"
command -v mkarchiso >/dev/null || die "mkarchiso not found; install it: pacman -S --needed archiso"
command -v python3 >/dev/null || die "python3 not found"
[[ -f "$PROFILE_DIR/profiledef.sh" ]] || die "not an archiso profile: $PROFILE_DIR"
cd "$REPO_ROOT"
log "Verifying installer package seed"
python3 "$REPO_ROOT/prepare-installer-cache.py" --require \
|| die "installer seed is absent or invalid; run prepare-installer-cache.py to build it"
if [[ -n "$SOURCE_REVISION" ]]; then
log "Restaging installed release metadata for $SOURCE_REVISION"
epoch="$SOURCE_DATE_EPOCH_ARG"
if [[ -z "$epoch" ]]; then
epoch="$(git -C "$REPO_ROOT" show -s --format=%ct "$SOURCE_REVISION" 2>/dev/null || true)"
fi
[[ -n "$epoch" ]] || die "could not determine --source-date-epoch; pass it explicitly"
python3 "$REPO_ROOT/generate-release-metadata.py" \
--prepare-installed "$PROFILE_DIR/airootfs/usr/share/bifrost/installed-root/usr/share/bifrost/release.json" \
--source-revision "$SOURCE_REVISION" \
--source-date-epoch "$epoch" \
|| die "release metadata staging failed"
fi
if (( SKIP_VALIDATE )); then
log "Skipping profile validation (--skip-validate)"
else
log "Validating profile, sources, and release contract"
python3 "$REPO_ROOT/validate-build.py" "$REPO_ROOT" || die "validate-build.py failed"
fi
log "Building ISO with mkarchiso (work=$WORK_DIR out=$OUT_DIR)"
mkdir -p "$OUT_DIR"
rm -rf -- "$WORK_DIR"
mkarchiso_args=(-v -w "$WORK_DIR" -o "$OUT_DIR")
# mkarchiso -r deletes the working directory when the build finishes.
(( KEEP_WORK )) || mkarchiso_args=(-r "${mkarchiso_args[@]}")
mkarchiso "${mkarchiso_args[@]}" "$PROFILE_DIR"
(( KEEP_WORK )) && log "Kept scratch work directory: $WORK_DIR"
iso="$(ls -t "$OUT_DIR"/*.iso 2>/dev/null | head -n1 || true)"
[[ -n "$iso" ]] || die "build finished but no ISO was found in $OUT_DIR"
log "ISO built: $iso"
printf ' size: %s\n' "$(du -h "$iso" | cut -f1)"
printf ' sha256: %s\n' "$(sha256sum "$iso" | cut -d' ' -f1)"