diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-09 23:41:41 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-09 23:41:41 -0500 |
| commit | 39b4a8bc5cac3a2092122f6c4fbede9bf0139286 (patch) | |
| tree | 189bbce6c25921bd9bf4f6392f4b232cb5e98ddc | |
| parent | 5e43d8c4ad8685e88331ac78641ca84666cb9e7a (diff) | |
| download | archangel-39b4a8bc5cac3a2092122f6c4fbede9bf0139286.tar.gz archangel-39b4a8bc5cac3a2092122f6c4fbede9bf0139286.zip | |
feat(build): inject the AUR repo into the profile and live ISO
Wire build-aur.sh into build.sh. After the pacoloco block, build the AUR repo and append a build-host [aur] stanza to profile/pacman.conf with an absolute file:// Server, so mkarchiso installs the baked packages into airootfs. The stanza lands after the pacoloco rewrite so its file:// path isn't redirected to localhost.
Add the audited official extra packages and the baked AUR names to packages.x86_64, both sourced from build-aur.sh so the list never drifts from the build array. Ship the repo into airootfs and write a complete live /etc/pacman.conf: the pristine releng config with [aur] appended, not an [aur]-only file, since this replaces the live system's stock config and an AUR-only one would strip the official repos. Copy the manifest beside the ISO in out/.
--skip-aur skips the build, the stanza, the AUR names, and the live config. The three injection points also guard on the repo dir existing, so the documented empty-set path can't point mkarchiso at a missing repo. Moved BUILD_LOG creation ahead of the AUR build so its output is captured too.
A unit test reproduces the live-config construction and asserts core, extra, the mirrorlist, and [aur] all survive. The end-to-end proof that mkarchiso installs from the build-host repo needs a real root build and is tracked as manual verification.
| -rwxr-xr-x | build.sh | 108 | ||||
| -rw-r--r-- | tests/unit/test_build_aur.bats | 20 |
2 files changed, 117 insertions, 11 deletions
@@ -13,6 +13,11 @@ WORK_DIR="$SCRIPT_DIR/work" OUT_DIR="$SCRIPT_DIR/out" INSTALLER_DIR="$SCRIPT_DIR/installer" +# AUR local-repo build helpers (build_aur_packages, stanza/manifest/package +# helpers). See docs/aur-local-repo-spec.org. +# shellcheck source=build-aur.sh +source "$SCRIPT_DIR/build-aur.sh" + # Live ISO root password (for SSH access during testing/emergencies) LIVE_ROOT_PASSWORD="archangel" @@ -80,6 +85,17 @@ cleanup_on_exit() { } trap cleanup_on_exit EXIT INT TERM +# Argument parsing. --skip-aur skips the whole AUR local-repo path (build, +# profile injection, live config) so the normal ISO builds fast when the AUR +# set isn't what's being worked on. +SKIP_AUR=false +for arg in "$@"; do + case "$arg" in + --skip-aur) SKIP_AUR=true ;; + *) error "Unknown argument: $arg (supported: --skip-aur)" ;; + esac +done + # Preflight checks [[ $EUID -ne 0 ]] && error "This script must be run as root" [[ -f /etc/arch-release ]] || error "This script must be run on Arch Linux" @@ -94,6 +110,17 @@ command -v mkarchiso >/dev/null 2>&1 || { pacman -Sy --noconfirm archiso } +# Pre-create the build log in out/ so it survives work/ cleanup and captures +# both the AUR build and mkarchiso. Owned by SUDO_USER from the start so a +# failed build leaves a user-readable log; tee writes to it as root, but the +# file mode stays as set. +BUILD_LOG="$OUT_DIR/build-$(date +%Y-%m-%d-%H%M).log" +mkdir -p "$OUT_DIR" +touch "$BUILD_LOG" +if [[ -n "${SUDO_USER:-}" ]]; then + chown "$SUDO_USER:$SUDO_USER" "$BUILD_LOG" +fi + # Clean previous builds (using safe cleanup to handle any leftover mounts) if [[ -d "$WORK_DIR" ]]; then warn "Removing previous work directory..." @@ -180,6 +207,24 @@ else info "pacoloco not detected — using upstream mirrors directly" fi +# Build the AUR local repository and expose it to mkarchiso. build_aur_packages +# compiles the v1 AUR set under $SUDO_USER into $SCRIPT_DIR/aur-packages with a +# manifest; the build-host [aur] stanza points pacman at that dir with an +# absolute file:// path so mkarchiso installs the packages into airootfs. Added +# after the pacoloco block so the file:// Server isn't rewritten to localhost. +if [[ "$SKIP_AUR" != true ]]; then + info "Building AUR local repository..." + build_aur_packages 2>&1 | tee -a "$BUILD_LOG" + # Guard on the dir: build_aur_packages skips repo creation for an empty + # AUR set, and a stanza pointing at a missing dir would fail mkarchiso. + if [[ -d "$SCRIPT_DIR/aur-packages" ]]; then + info "Adding build-host [aur] repository for mkarchiso..." + aur_repo_stanza "file://$SCRIPT_DIR/aur-packages" >> "$PROFILE_DIR/pacman.conf" + fi +else + info "Skipping AUR local repository (--skip-aur)" +fi + # Add ZFS and our custom packages info "Adding ZFS and custom packages..." cat >> "$PROFILE_DIR/packages.x86_64" << 'EOF' @@ -289,6 +334,24 @@ w3m EOF +# Audited official extra packages (reclassified out of the AUR — installed +# from the normal repos, not built) plus, unless skipped, the baked +# genuine-AUR set (resolved from the build-host [aur] repo during mkarchiso). +# Package names come from build-aur.sh so the build array, this list, and the +# manifest never drift. +{ + echo "" + echo "# Audited official extra utilities" + aur_official_packages + # AUR names only when the repo was actually built — otherwise mkarchiso + # would try to install them with no [aur] repo to resolve from. + if [[ "$SKIP_AUR" != true ]] && [[ -d "$SCRIPT_DIR/aur-packages" ]]; then + echo "" + echo "# Baked genuine-AUR packages (local [aur] repo)" + aur_v1_packages + fi +} >> "$PROFILE_DIR/packages.x86_64" + # Get kernel version for ISO naming info "Querying kernel version..." KERNEL_VER=$(pacman -Si linux-lts 2>/dev/null | grep "^Version" | awk '{print $3}' | cut -d- -f1) @@ -313,6 +376,26 @@ mkdir -p "$PROFILE_DIR/airootfs/usr/local/bin" mkdir -p "$PROFILE_DIR/airootfs/code" mkdir -p "$PROFILE_DIR/airootfs/etc/systemd/system/multi-user.target.wants" +# Ship the baked AUR repo into the live ISO and give it a complete runtime +# pacman.conf. archangel ships no airootfs pacman.conf today, so this file +# REPLACES the live system's stock /etc/pacman.conf — it must keep the normal +# repos and mirrorlist (copied from the pristine releng config, not the +# pacoloco-rewritten profile config) and only append [aur]. An [aur]-only file +# would break live pacman and the installer's pacstrap. The runtime Server +# resolves /usr/share/aur-packages inside the live system. +if [[ "$SKIP_AUR" != true ]] && [[ -d "$SCRIPT_DIR/aur-packages" ]]; then + info "Shipping AUR repo into the live ISO..." + mkdir -p "$PROFILE_DIR/airootfs/usr/share/aur-packages" + cp -r "$SCRIPT_DIR/aur-packages/." \ + "$PROFILE_DIR/airootfs/usr/share/aur-packages/" + + info "Creating live pacman.conf with [aur] (normal repos preserved)..." + cp /usr/share/archiso/configs/releng/pacman.conf \ + "$PROFILE_DIR/airootfs/etc/pacman.conf" + aur_repo_stanza "file:///usr/share/aur-packages" \ + >> "$PROFILE_DIR/airootfs/etc/pacman.conf" +fi + # Enable SSH on live ISO info "Enabling SSH on live ISO..." ln -sf /usr/lib/systemd/system/sshd.service \ @@ -502,17 +585,9 @@ rm -f /var/cache/pacman/pkg/zfs-utils-*.pkg.tar.zst* rm -f /var/cache/pacoloco/pkgs/archzfs/zfs-dkms-*.pkg.tar.zst* rm -f /var/cache/pacoloco/pkgs/archzfs/zfs-utils-*.pkg.tar.zst* -# Pre-create the build log in out/ so it survives work/ cleanup. Owned -# by SUDO_USER from the start so a failed build leaves a user-readable -# log; tee writes to it as root, but the file mode stays as set. -BUILD_LOG="$OUT_DIR/build-$(date +%Y-%m-%d-%H%M).log" -mkdir -p "$OUT_DIR" -touch "$BUILD_LOG" -if [[ -n "${SUDO_USER:-}" ]]; then - chown "$SUDO_USER:$SUDO_USER" "$BUILD_LOG" -fi - -mkarchiso -v -w "$WORK_DIR" -o "$OUT_DIR" "$PROFILE_DIR" 2>&1 | tee "$BUILD_LOG" +# BUILD_LOG was pre-created right after the archiso preflight (above) so the +# AUR build could append to it; mkarchiso appends here too. +mkarchiso -v -w "$WORK_DIR" -o "$OUT_DIR" "$PROFILE_DIR" 2>&1 | tee -a "$BUILD_LOG" # Restore ownership to the user who invoked sudo # mkarchiso runs as root and creates root-owned files @@ -532,6 +607,17 @@ if [[ -f "$ISO_FILE" ]]; then mv "$BUILD_LOG" "$RENAMED_LOG" BUILD_LOG="$RENAMED_LOG" + # Drop the AUR manifest beside the ISO so a given ISO's exact AUR set + # (version + commit + SHA256) is auditable without mounting it. + if [[ -f "$SCRIPT_DIR/aur-packages/manifest.tsv" ]]; then + cp "$SCRIPT_DIR/aur-packages/manifest.tsv" \ + "$OUT_DIR/${ISO_BASENAME}-aur-manifest.tsv" + if [[ -n "${SUDO_USER:-}" ]]; then + chown "$SUDO_USER:$SUDO_USER" \ + "$OUT_DIR/${ISO_BASENAME}-aur-manifest.tsv" 2>/dev/null || true + fi + fi + echo "" info "Build complete!" info "ISO location: $ISO_FILE" diff --git a/tests/unit/test_build_aur.bats b/tests/unit/test_build_aur.bats index 06a78aa..4da66fe 100644 --- a/tests/unit/test_build_aur.bats +++ b/tests/unit/test_build_aur.bats @@ -82,6 +82,26 @@ setup() { [[ "$output" != *"/usr/share/aur-packages"* ]] } +# Guards the reviewer's core concern: the live pacman.conf build.sh ships must +# be a COMPLETE config (releng base + [aur] appended), not an [aur]-only file +# that would strip the official repos from the live system. Reproduces the +# build.sh construction (cp releng config, append the stanza) and asserts the +# official repos, the mirrorlist Include, and [aur] all survive. +@test "live pacman.conf base plus [aur] preserves core, extra, and the mirrorlist" { + local releng=/usr/share/archiso/configs/releng/pacman.conf + [ -f "$releng" ] || skip "releng pacman.conf not installed" + local f + f=$(mktemp) + cp "$releng" "$f" + aur_repo_stanza "file:///usr/share/aur-packages" >> "$f" + grep -q '^\[core\]' "$f" + grep -q '^\[extra\]' "$f" + grep -q '^\[aur\]' "$f" + grep -q '^Include = /etc/pacman.d/mirrorlist' "$f" + grep -q '^Server = file:///usr/share/aur-packages' "$f" + rm -f "$f" +} + ############################# # aur_manifest_header / aur_manifest_row — TSV manifest formatting ############################# |
