236 lines
10 KiB
Bash
Executable File
236 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -e
|
|
|
|
OMARCHY_ISO_REF="${OMARCHY_ISO_REF:-quattro}"
|
|
OMARCHY_MIRROR="${OMARCHY_MIRROR:-stable}"
|
|
|
|
# Quattro, edge, dev, and local-source ISOs install the dev packages explicitly.
|
|
# Those package recipes track the quattro branch. This avoids relying on
|
|
# pacman's provides=omarchy resolution and shows the real package names being
|
|
# tested in the offline mirror and target install.
|
|
case "$OMARCHY_ISO_REF" in
|
|
quattro|edge|dev|local)
|
|
: "${OMARCHY_RUNTIME_PACKAGE:=omarchy-dev}"
|
|
: "${OMARCHY_SETTINGS_PACKAGE:=omarchy-settings-dev}"
|
|
;;
|
|
*)
|
|
: "${OMARCHY_RUNTIME_PACKAGE:=omarchy}"
|
|
: "${OMARCHY_SETTINGS_PACKAGE:=omarchy-settings}"
|
|
;;
|
|
esac
|
|
: "${OMARCHY_NVIM_PACKAGE:=omarchy-nvim}"
|
|
export OMARCHY_RUNTIME_PACKAGE OMARCHY_SETTINGS_PACKAGE OMARCHY_NVIM_PACKAGE
|
|
|
|
# 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/"
|
|
mkdir -p "$build_cache_dir/airootfs/usr/share/omarchy-iso"
|
|
echo "$OMARCHY_MIRROR" > "$build_cache_dir/airootfs/root/omarchy_mirror"
|
|
echo "$OMARCHY_ISO_REF" > "$build_cache_dir/airootfs/root/omarchy_iso_ref"
|
|
cat > "$build_cache_dir/airootfs/usr/share/omarchy-iso/package-targets" <<EOF
|
|
OMARCHY_RUNTIME_PACKAGE=$OMARCHY_RUNTIME_PACKAGE
|
|
OMARCHY_SETTINGS_PACKAGE=$OMARCHY_SETTINGS_PACKAGE
|
|
OMARCHY_NVIM_PACKAGE=$OMARCHY_NVIM_PACKAGE
|
|
EOF
|
|
|
|
if [[ ${OMARCHY_INSTALL_DEBUG:-} == "1" ]]; then
|
|
touch "$build_cache_dir/airootfs/usr/share/omarchy-iso/install-debug"
|
|
{
|
|
echo "debug=1"
|
|
echo "built_at=$(date -Is)"
|
|
echo "ref=$OMARCHY_ISO_REF"
|
|
echo "mirror=$OMARCHY_MIRROR"
|
|
echo "runtime_package=$OMARCHY_RUNTIME_PACKAGE"
|
|
echo "settings_package=$OMARCHY_SETTINGS_PACKAGE"
|
|
echo "nvim_package=$OMARCHY_NVIM_PACKAGE"
|
|
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).
|
|
# The selected omarchy-settings package 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_PACKAGE" 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 runtime
|
|
# package so we don't need a local checkout in the non-local-source path.
|
|
bootstrap_cache_dir=/tmp/omarchy-pkg-bootstrap
|
|
rm -rf "$bootstrap_cache_dir" /tmp/offlinedb-bootstrap /tmp/omarchy-pkglists
|
|
mkdir -p "$bootstrap_cache_dir" /tmp/offlinedb-bootstrap
|
|
pacman --config /configs/pacman-online-${OMARCHY_MIRROR}.conf --noconfirm -Syw "$OMARCHY_RUNTIME_PACKAGE" --cachedir "$bootstrap_cache_dir" --dbpath /tmp/offlinedb-bootstrap >/dev/null
|
|
omarchy_pkg=$(find "$bootstrap_cache_dir" -maxdepth 1 -type f -name "$OMARCHY_RUNTIME_PACKAGE-*.pkg.tar.zst" | sort | head -1)
|
|
if [[ -z $omarchy_pkg ]]; then
|
|
echo "ERROR: downloaded package for $OMARCHY_RUNTIME_PACKAGE not found in $bootstrap_cache_dir" >&2
|
|
exit 1
|
|
fi
|
|
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 selected Omarchy packages so the target install can
|
|
# find the runtime and companion packages in the offline mirror.
|
|
printf '%s\n' "$OMARCHY_RUNTIME_PACKAGE" "$OMARCHY_SETTINGS_PACKAGE" "$OMARCHY_NVIM_PACKAGE"
|
|
} | 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
|
|
mapfile -t all_packages < <(
|
|
printf '%s\n' "${all_packages[@]}" |
|
|
grep -Fxv \
|
|
-e "$OMARCHY_RUNTIME_PACKAGE" \
|
|
-e "$OMARCHY_SETTINGS_PACKAGE" \
|
|
-e "$OMARCHY_NVIM_PACKAGE" || true
|
|
)
|
|
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
|