Merge nucleic/olive-ember-seal-q7vk into dev
This commit is contained in:
Executable
+110
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env bash
|
||||
# narOS rootfs builder (NAROS.md §2.2): mmdebstrap against the pinned Debian snapshot,
|
||||
# plus (optionally) the local Nucleic package pool. Produces a rootfs tar that CI turns
|
||||
# into an OCI image (naros-base/…) or the VM payload tarball.
|
||||
#
|
||||
# build-rootfs.sh <tier> <arch> [--pool DIR] [--out DIR] [--channel edge|stable]
|
||||
#
|
||||
# Needs mmdebstrap and either root or an unshare-capable user. The snapshot mirror serves
|
||||
# stale Release files by design, hence Check-Valid-Until off (standard snapshot practice).
|
||||
set -euo pipefail
|
||||
|
||||
OS_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
TIER="${1:?usage: build-rootfs.sh <tier> <arch> [--pool DIR] [--out DIR] [--channel C]}"
|
||||
ARCH="${2:?missing arch (arm64|amd64)}"
|
||||
shift 2
|
||||
|
||||
POOL="" OUT="$OS_DIR/dist" CHANNEL="${NAROS_CHANNEL:-edge}"
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--pool) POOL="$(cd "$2" && pwd)"; shift 2 ;;
|
||||
--out) OUT="$2"; shift 2 ;;
|
||||
--channel) CHANNEL="$2"; shift 2 ;;
|
||||
*) echo "unknown arg: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
VERSION="$(cat "$OS_DIR/VERSION")"
|
||||
SNAPSHOT="$(cat "$OS_DIR/SNAPSHOT")"
|
||||
SUITE="trixie"
|
||||
MIRROR="https://snapshot.debian.org/archive/debian/${SNAPSHOT}/"
|
||||
PROFILE="$OS_DIR/mkimage/profiles/$TIER.pkgs"
|
||||
[ -f "$PROFILE" ] || { echo "no profile for tier '$TIER' ($PROFILE)" >&2; exit 2; }
|
||||
|
||||
pkg_list() { grep -vE '^\s*(#|$)' "$1" | tr '\n' ',' | sed 's/,$//'; }
|
||||
INCLUDE="$(pkg_list "$PROFILE")"
|
||||
|
||||
SOURCES=("deb [check-valid-until=no] $MIRROR $SUITE main")
|
||||
if [ -n "$POOL" ]; then
|
||||
# Flat file:// repo over the pool; trusted because it is CI's own just-built artifact —
|
||||
# end-user trust comes from the signed hosted repo (repo/publish.sh), not this path.
|
||||
if [ ! -f "$POOL/Packages" ] || [ -n "$(find "$POOL" -name '*.deb' -newer "$POOL/Packages" 2>/dev/null)" ]; then
|
||||
(cd "$POOL" && dpkg-scanpackages --multiversion . > Packages)
|
||||
fi
|
||||
# Late packages (profiles/<tier>.late-pkgs) install via a finish hook AFTER every
|
||||
# Debian package is configured — mandatory for nash-default-shell: apt's configure
|
||||
# order is not deterministic, so a mid-transaction divert would run the remaining
|
||||
# Debian postinsts under nash (observed: ca-certificates' UTF-8 filenames mangled).
|
||||
# The divert must be the image's final configure step.
|
||||
LATE_DEBS=()
|
||||
LPROFILE="$OS_DIR/mkimage/profiles/$TIER.late-pkgs"
|
||||
if [ -f "$LPROFILE" ]; then
|
||||
while IFS= read -r pkg; do
|
||||
deb="$(ls "$POOL/${pkg}_"*.deb 2>/dev/null | head -1)"
|
||||
if [ -n "$deb" ]; then
|
||||
LATE_DEBS+=("$deb")
|
||||
elif [ "${NAROS_STRICT:-0}" = "1" ]; then
|
||||
echo "ERROR: late package $pkg absent from pool" >&2; exit 1
|
||||
else
|
||||
echo "WARNING: late package $pkg absent from pool — building WITHOUT it" >&2
|
||||
fi
|
||||
done < <(grep -vE '^\s*(#|$)' "$LPROFILE")
|
||||
fi
|
||||
|
||||
NPROFILE="$OS_DIR/mkimage/profiles/$TIER.naros-pkgs"
|
||||
if [ -f "$NPROFILE" ]; then
|
||||
# Only request packages the pool actually carries: local builds legitimately lack
|
||||
# some (e.g. naros-keyring without the signing key). Loud per-package warning;
|
||||
# NAROS_STRICT=1 (CI) turns any gap into a hard failure.
|
||||
while IFS= read -r pkg; do
|
||||
if grep -qx "Package: $pkg" "$POOL/Packages"; then
|
||||
INCLUDE="$INCLUDE,$pkg"
|
||||
elif [ "${NAROS_STRICT:-0}" = "1" ]; then
|
||||
echo "ERROR: $pkg requested by $TIER tier but absent from pool" >&2; exit 1
|
||||
else
|
||||
echo "WARNING: $pkg absent from pool — building WITHOUT it" >&2
|
||||
fi
|
||||
done < <(grep -vE '^\s*(#|$)' "$NPROFILE")
|
||||
fi
|
||||
SOURCES+=("deb [trusted=yes] copy://$POOL ./")
|
||||
fi
|
||||
|
||||
mkdir -p "$OUT"
|
||||
TAR="$OUT/naros-$TIER-$VERSION-$ARCH.tar"
|
||||
|
||||
export NAROS_TIER="$TIER" NAROS_VERSION="$VERSION" NAROS_ARCH="$ARCH" \
|
||||
NAROS_CHANNEL="$CHANNEL" NAROS_SNAPSHOT="$SNAPSHOT" NAROS_SUITE="$SUITE"
|
||||
|
||||
HOOKS=()
|
||||
if [ "${#LATE_DEBS[@]}" -gt 0 ]; then
|
||||
LATE_ARGS=""
|
||||
for deb in "${LATE_DEBS[@]}"; do
|
||||
b="$(basename "$deb")"
|
||||
HOOKS+=(--customize-hook="copy-in $deb /tmp")
|
||||
LATE_ARGS="$LATE_ARGS /tmp/$b"
|
||||
done
|
||||
HOOKS+=(--customize-hook="chroot \"\$1\" dpkg -i$LATE_ARGS")
|
||||
HOOKS+=(--customize-hook="rm -f$(printf ' "$1"%s' $LATE_ARGS)")
|
||||
fi
|
||||
HOOKS+=(--customize-hook="$OS_DIR/mkimage/hooks/00-identity.sh"' "$1"')
|
||||
|
||||
echo "narOS $VERSION/$CHANNEL: tier=$TIER arch=$ARCH snapshot=$SNAPSHOT pool=${POOL:-none}"
|
||||
mmdebstrap \
|
||||
--architectures="$ARCH" \
|
||||
--variant=apt \
|
||||
--include="$INCLUDE" \
|
||||
--aptopt='Acquire::Check-Valid-Until "false"' \
|
||||
"${HOOKS[@]}" \
|
||||
"$SUITE" "$TAR" "${SOURCES[@]}"
|
||||
|
||||
echo "built $TAR"
|
||||
Reference in New Issue
Block a user