diff --git a/bin/omarchy-iso-make b/bin/omarchy-iso-make index 5dbbeff..500de4b 100755 --- a/bin/omarchy-iso-make +++ b/bin/omarchy-iso-make @@ -6,8 +6,17 @@ NO_CACHE="" KEEP_PKG_CACHE="" LOCAL_OMARCHY_PATH="" LOCAL_PKGS_PATH="" +OMARCHY_REGION="${OMARCHY_REGION:-global}" while [[ $# -gt 0 ]]; do case $1 in + --region) + OMARCHY_REGION="${2:-}" + if [[ $OMARCHY_REGION != "global" && $OMARCHY_REGION != "cn" ]]; then + echo "Error: --region requires global or cn (ISO 3166-1 alpha-2)." >&2 + exit 1 + fi + shift 2 + ;; --no-cache) NO_CACHE=1 shift @@ -57,12 +66,17 @@ while [[ $# -gt 0 ]]; do ;; *) echo "Unknown option: $1" - echo "Usage: $0 [--no-cache] [--keep-pkg-cache] [--no-boot-offer] [--debug] [--edge] [--dev|--rc] [--local-source ]" + echo "Usage: $0 [--no-cache] [--keep-pkg-cache] [--no-boot-offer] [--debug] [--edge] [--dev|--rc] [--region global|cn] [--local-source ]" exit 1 ;; esac done +if [[ $OMARCHY_REGION != "global" && $OMARCHY_REGION != "cn" ]]; then + echo "Error: unsupported region '$OMARCHY_REGION'. Expected global or cn." >&2 + exit 1 +fi + if [[ -n $LOCAL_OMARCHY_PATH ]]; then [[ -d $LOCAL_OMARCHY_PATH ]] || { echo "Error: Omarchy checkout not found at $LOCAL_OMARCHY_PATH" >&2; exit 1; } [[ -d $LOCAL_PKGS_PATH ]] || { echo "Error: pkgs checkout not found at $LOCAL_PKGS_PATH" >&2; exit 1; } @@ -125,6 +139,7 @@ DOCKER_ARGS=( --privileged -e "OMARCHY_ISO_REF=$OMARCHY_ISO_REF" -e "OMARCHY_MIRROR=$OMARCHY_MIRROR" + -e "OMARCHY_REGION=$OMARCHY_REGION" -e "OMARCHY_INSTALL_DEBUG=${OMARCHY_INSTALL_DEBUG:-}" -e "HOST_UID=$(id -u)" -e "HOST_GID=$(id -g)" @@ -146,10 +161,14 @@ if [[ -d /var/cache/pacman/pkg ]]; then DOCKER_ARGS+=(-v "/var/cache/pacman/pkg:/var/cache/pacman/pkg") fi -# Mount the build cache directory where packages are downloaded. Channels use -# different package snapshots and must never share an offline mirror cache. +# Channels and regions must not share an offline mirror cache. Keep the +# existing global cache path and artifact suffix unchanged. +region_suffix="" +if [[ $OMARCHY_REGION != "global" ]]; then + region_suffix="-$OMARCHY_REGION" +fi if [[ -z "$NO_CACHE" ]]; then - OFFLINE_REPO_BUILD_CACHE_DIR="$HOME/.cache/omarchy/iso_${OMARCHY_MIRROR}/airootfs/var/cache/omarchy" + OFFLINE_REPO_BUILD_CACHE_DIR="$HOME/.cache/omarchy/iso_${OMARCHY_MIRROR}${region_suffix}/airootfs/var/cache/omarchy" mkdir -p "$OFFLINE_REPO_BUILD_CACHE_DIR" DOCKER_ARGS+=(-v "$OFFLINE_REPO_BUILD_CACHE_DIR:/var/cache/airootfs/var/cache/omarchy") else @@ -169,7 +188,7 @@ fi "${DOCKER[@]}" run "${DOCKER_ARGS[@]}" archlinux/archlinux:latest /$BUILD_SCRIPT latest_iso=$(\ls -t "$BUILD_RELEASE_PATH"/*.iso | head -n1) -iso_ref="${latest_iso%.*}-$OMARCHY_ISO_REF.iso" +iso_ref="${latest_iso%.*}-${OMARCHY_ISO_REF}${region_suffix}.iso" mv -f "$latest_iso" "$iso_ref" if [[ -z "${NO_BOOT_OFFER:-}" ]]; then diff --git a/builder/build-iso.sh b/builder/build-iso.sh index 0c917d6..5224eef 100755 --- a/builder/build-iso.sh +++ b/builder/build-iso.sh @@ -4,6 +4,11 @@ set -e OMARCHY_ISO_REF="${OMARCHY_ISO_REF:-quattro}" OMARCHY_MIRROR="${OMARCHY_MIRROR:-stable}" +OMARCHY_REGION="${OMARCHY_REGION:-global}" +case "$OMARCHY_REGION" in + global|cn) ;; + *) echo "Unsupported region: $OMARCHY_REGION" >&2; exit 1 ;; +esac # Edge, dev, and local-source ISOs install the dev packages explicitly. Those # package recipes track the quattro branch. This avoids relying on pacman's @@ -67,6 +72,7 @@ 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" +echo "$OMARCHY_REGION" > "$build_cache_dir/airootfs/root/omarchy_region" cat > "$build_cache_dir/airootfs/usr/share/omarchy-iso/package-targets" <&2 + exit 1 + fi + fi base_pkg_lists=(/tmp/omarchy-pkglists/usr/share/omarchy/install/omarchy-base.packages /tmp/omarchy-pkglists/usr/share/omarchy/install/omarchy-other.packages) # Extracted on its own, tolerating a miss: bsdtar exits non-zero for a member # it can't find, so asking for this alongside the package lists would abort the @@ -168,6 +184,15 @@ 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" +# Work on writable copies, leaving the mounted runtime and ISO configs intact. +online_config=/tmp/omarchy-pacman-online.conf +cp "/configs/pacman-online-${OMARCHY_MIRROR}.conf" "$online_config" +bash /builder/prepare-region.sh "$OMARCHY_REGION" "$runtime_root" "$build_cache_dir/airootfs" "$online_config" +base_pkg_lists=( + "$build_cache_dir/airootfs/usr/share/omarchy-iso/omarchy-base.packages" + "$build_cache_dir/airootfs/usr/share/omarchy-iso/omarchy-other.packages" +) + # The configurator's setup form comes from the runtime this ISO bundles, so the # installer and the first-boot setup that finishes a deferred install can never # disagree. A runtime predating the split ships no such file, which would leave @@ -232,7 +257,7 @@ fi mkdir -p /tmp/offlinedb download_offline_packages() { - pacman --config /configs/pacman-online-${OMARCHY_MIRROR}.conf --noconfirm -Syw \ + pacman --config "$online_config" --noconfirm -Syw \ "${all_packages[@]}" --cachedir "$offline_mirror_dir/" --dbpath /tmp/offlinedb --needed } @@ -250,7 +275,7 @@ fi # newest version of every cached package name) removes packages that have left # the lists or dependency closure, such as an old Electron major version. if ! resolved_package_files="$( - pacman --config "/configs/pacman-online-${OMARCHY_MIRROR}.conf" --noconfirm \ + pacman --config "$online_config" --noconfirm \ --dbpath /tmp/offlinedb -S --print --print-format '%f' "${all_packages[@]}" )"; then echo "ERROR: could not resolve the package files required by the offline mirror" >&2 diff --git a/builder/prepare-region.sh b/builder/prepare-region.sh new file mode 100644 index 0000000..2707fba --- /dev/null +++ b/builder/prepare-region.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Add the selected runtime's regional payload to the ISO. Repository defaults +# stay in the runtime package, not in a second set of ISO-specific templates. +set -euo pipefail + +region="$1" +runtime="$2" +iso_root="$3" +online_config="$4" + +case "$region" in + global) exit 0 ;; + cn) ;; + *) echo "Unsupported region: $region" >&2; exit 1 ;; +esac + +profile="$runtime/default/regions/$region" +if [[ ! -f $runtime/bin/omarchy-apply-pacman || ! -f $profile/packages || + ! -f $profile/pacman/pacman.conf.append || ! -f $profile/pacman/mirrorlist.append ]]; then + echo "Runtime does not support region '$region'; publish a matching runtime or use --local-source." >&2 + exit 1 +fi + +# This is the target package list used both for download resolution and by the +# installer. Merely putting extra packages in the cache would not install them. +payload="$iso_root/usr/share/omarchy-iso" +cp -a "$profile" "$payload/region" +printf '\n' >> "$payload/omarchy-base.packages" +cat "$profile/packages" >> "$payload/omarchy-base.packages" + +# Only the community repository is needed for regional package downloads. +# Keep the channel's build mirrors intact; target mirrors are restored later. +printf '\n' >> "$online_config" +cat "$profile/pacman/pacman.conf.append" >> "$online_config" + +# The keyring package must be signed by a key already trusted by Arch. Do not +# bootstrap trust from an unchecked keyserver response or disable signatures. +# https://github.com/archlinuxcn/repo#usage +pacman --config "$online_config" --noconfirm -Sy --needed archlinuxcn-keyring +pacman-key --populate archlinuxcn