#!/bin/bash set -e # Packages installed into the Arch container used to build the ISO. pacman-key --init pacman --noconfirm -Sy archlinux-keyring pacman --noconfirm -Sy archiso git sudo base-devel jq grub imagemagick neovim nodejs npm tree-sitter-cli # Pre-import the omarchy signing key (so pacman trusts our [omarchy] repo # during the build without keyserver lookups). pacman-key --add /builder/omarchy.gpg pacman-key --lsign-key 40DFB630FF42BCFFB047046CF0134EE680CAC571 # omarchy-keyring is needed inside the offline mirror too. pacman --config /configs/pacman-online-${OMARCHY_MIRROR}.conf --noconfirm -Sy omarchy-keyring pacman-key --populate omarchy # Append the [omarchy] repo to the container's /etc/pacman.conf so subsequent # tools (notably makepkg in build-omarchy-packages.sh) can resolve omarchy- # only build deps like limine-snapper-sync and limine-mkinitcpio-hook. if ! grep -q '^\[omarchy\]' /etc/pacman.conf; then awk '/^\[omarchy\]/,/^$/' /configs/pacman-online-${OMARCHY_MIRROR}.conf >> /etc/pacman.conf fi # Build locations build_cache_dir=/var/cache offline_mirror_dir="$build_cache_dir/airootfs/var/cache/omarchy/mirror/offline" mkdir -p "$build_cache_dir" "$offline_mirror_dir" # Seed from the official Arch releng profile. cp -r /archiso/configs/releng/* "$build_cache_dir/" rm "$build_cache_dir/airootfs/etc/motd" # We rely on the global CDN; drop reflector. rm -rf "$build_cache_dir/airootfs/etc/systemd/system/multi-user.target.wants/reflector.service" rm -rf "$build_cache_dir/airootfs/etc/systemd/system/reflector.service.d" rm -rf "$build_cache_dir/airootfs/etc/xdg/reflector" # Bring in our archiso profile additions. cp -r /configs/* "$build_cache_dir/" echo "$OMARCHY_MIRROR" > "$build_cache_dir/airootfs/root/omarchy_mirror" if [[ ${OMARCHY_INSTALL_DEBUG:-} == "1" ]]; then mkdir -p "$build_cache_dir/airootfs/usr/share/omarchy-iso" touch "$build_cache_dir/airootfs/usr/share/omarchy-iso/install-debug" { echo "debug=1" echo "built_at=$(date -Is)" echo "mirror=$OMARCHY_MIRROR" if [[ -d /omarchy-source ]]; then echo "omarchy_source=/omarchy-source" git -c safe.directory=/omarchy-source -C /omarchy-source rev-parse HEAD 2>/dev/null | sed 's/^/omarchy_commit=/' || true git -c safe.directory=/omarchy-source -C /omarchy-source status --short 2>/dev/null | sed 's/^/omarchy_status=/' || true fi if [[ -d /omarchy-pkgs ]]; then echo "omarchy_pkgs_source=/omarchy-pkgs" git -c safe.directory=/omarchy-pkgs -C /omarchy-pkgs rev-parse HEAD 2>/dev/null | sed 's/^/omarchy_pkgs_commit=/' || true git -c safe.directory=/omarchy-pkgs -C /omarchy-pkgs status --short 2>/dev/null | sed 's/^/omarchy_pkgs_status=/' || true fi } > "$build_cache_dir/airootfs/usr/share/omarchy-iso/build-info" fi # When --local-source is in effect, build omarchy* from the mounted source # trees and drop them in the offline mirror. Otherwise pacman -Syw below # downloads the published versions from the omarchy network mirror. if [[ -d /omarchy-source && -d /omarchy-pkgs ]]; then bash /builder/build-omarchy-packages.sh "$offline_mirror_dir" LOCAL_OMARCHY_BUILD=1 fi # Node.js binary for offline mise install. NODE_DIST_URL="https://nodejs.org/dist/latest" NODE_SHASUMS=$(curl -fsSL "$NODE_DIST_URL/SHASUMS256.txt") NODE_FILENAME=$(echo "$NODE_SHASUMS" | grep "linux-x64.tar.gz" | awk '{print $2}') NODE_SHA=$(echo "$NODE_SHASUMS" | grep "linux-x64.tar.gz" | awk '{print $1}') curl -fsSL "$NODE_DIST_URL/$NODE_FILENAME" -o "/tmp/$NODE_FILENAME" echo "$NODE_SHA /tmp/$NODE_FILENAME" | sha256sum -c - mkdir -p "$build_cache_dir/airootfs/opt/packages/" cp "/tmp/$NODE_FILENAME" "$build_cache_dir/airootfs/opt/packages/" # Packages installed into the live ISO environment itself (NOT the target system). # omarchy-settings is needed here so its post_install hook drops Omarchy's # plymouthd.conf into /etc/plymouth before mkarchiso builds the live initramfs. arch_packages=(linux-t2 git gum jq openssl plymouth python-terminaltexteffects tzupdate omarchy-keyring omarchy-settings lvm2 cryptsetup parted) printf '%s\n' "${arch_packages[@]}" >> "$build_cache_dir/packages.x86_64" # Build the offline mirror: everything pacstrap might want during the target # install. With --local-source, the omarchy* packages we just built are # already in the mirror and we filter them out below. Without it, pacman -Syw # pulls the published omarchy* from the network mirror like any other package. if [[ -d /omarchy-source ]]; then base_pkg_lists=(/omarchy-source/install/omarchy-base.packages /omarchy-source/install/omarchy-other.packages) else # Pull the same package lists out of the freshly-downloaded omarchy package # so we don't need a local checkout in the non-local-source path. pacman --config /configs/pacman-online-${OMARCHY_MIRROR}.conf --noconfirm -Sw omarchy --cachedir /tmp --dbpath /tmp/offlinedb-bootstrap >/dev/null omarchy_pkg=$(ls /tmp/omarchy-*.pkg.tar.zst | head -1) mkdir -p /tmp/omarchy-pkglists bsdtar -xf "$omarchy_pkg" -C /tmp/omarchy-pkglists usr/share/omarchy/install/omarchy-base.packages usr/share/omarchy/install/omarchy-other.packages base_pkg_lists=(/tmp/omarchy-pkglists/usr/share/omarchy/install/omarchy-base.packages /tmp/omarchy-pkglists/usr/share/omarchy/install/omarchy-other.packages) fi mkdir -p "$build_cache_dir/airootfs/usr/share/omarchy-iso" cp "${base_pkg_lists[0]}" "$build_cache_dir/airootfs/usr/share/omarchy-iso/omarchy-base.packages" cp "${base_pkg_lists[1]}" "$build_cache_dir/airootfs/usr/share/omarchy-iso/omarchy-other.packages" # Collect every package we want available in the offline mirror. declare -a all_packages mapfile -t all_packages < <( { cat "$build_cache_dir/packages.x86_64" grep -hv '^#\|^$' "${base_pkg_lists[@]}" grep -hv '^#\|^$' /builder/archinstall.packages # Always include the Omarchy packages so the target install can find # the runtime and companion packages in the offline mirror. printf 'omarchy\nomarchy-settings\nomarchy-nvim\n' } | sort -u ) # With --local-source we already built these omarchy* packages directly into # the mirror; strip them from the pacman -Syw list so it doesn't try to fetch # the published versions on top. if [[ -n ${LOCAL_OMARCHY_BUILD:-} ]]; then all_packages=($(printf '%s\n' "${all_packages[@]}" | grep -vE '^(omarchy|omarchy-settings|omarchy-nvim)$')) fi mkdir -p /tmp/offlinedb pacman --config /configs/pacman-online-${OMARCHY_MIRROR}.conf --noconfirm -Syw \ "${all_packages[@]}" --cachedir "$offline_mirror_dir/" --dbpath /tmp/offlinedb --needed prune_stale_package_versions() { local dir="$1" local pkgfile name version cmp local -a stale=() declare -A newest_file=() declare -A newest_version=() while IFS= read -r pkgfile; do read -r name version < <(pacman -Qp "$pkgfile" 2>/dev/null) || continue [[ -n $name && -n $version ]] || continue if [[ -z ${newest_version[$name]+x} ]]; then newest_version[$name]="$version" newest_file[$name]="$pkgfile" continue fi cmp=$(vercmp "$version" "${newest_version[$name]}") if (( cmp > 0 )); then stale+=("${newest_file[$name]}") newest_version[$name]="$version" newest_file[$name]="$pkgfile" else stale+=("$pkgfile") fi done < <(find "$dir" -maxdepth 1 -type f -name '*.pkg.tar.*' ! -name '*.sig' -print | sort) if (( ${#stale[@]} > 0 )); then echo "Pruning stale package versions from offline mirror:" for pkgfile in "${stale[@]}"; do echo " $(basename "$pkgfile")" rm -f "$pkgfile" "$pkgfile.sig" done fi } # Rebuild the offline repo db from scratch so size/checksum/depends entries # always reflect the current package files. The persistent cache can contain # multiple versions of the same package; repo-add keeps the last one it sees, # which is lexical glob order, not version order (e.g. pkgrel -9 can override # -15). Prune to one newest version per package before indexing. prune_stale_package_versions "$offline_mirror_dir" rm -f "$offline_mirror_dir"/offline.db* "$offline_mirror_dir"/offline.files* repo-add "$offline_mirror_dir/offline.db.tar.gz" "$offline_mirror_dir/"*.pkg.tar.zst # mkarchiso expects the mirror at /var/cache/omarchy/mirror/offline inside the # container (the airootfs path); symlink rather than duplicate. mkdir -p /var/cache/omarchy/mirror ln -sf "$offline_mirror_dir" /var/cache/omarchy/mirror/offline # Live ISO uses the same offline pacman.conf. cp "$build_cache_dir/pacman-offline.conf" "$build_cache_dir/airootfs/etc/pacman.conf" # Build the ISO. mkarchiso -v -w "$build_cache_dir/work/" -o /out/ "$build_cache_dir/" # Match host UID/GID on output. if [[ -n $HOST_UID && -n $HOST_GID ]]; then chown -R "$HOST_UID:$HOST_GID" /out/ fi