diff --git a/bin/build b/bin/build index 7aba76a..de93333 100755 --- a/bin/build +++ b/bin/build @@ -110,12 +110,7 @@ fi # Run the builder with assembled args IMAGE_TAG="omarchy-pkg-builder:latest-$ARCH" -PLATFORM_ARG="" -if [[ "$ARCH" == "aarch64" ]]; then - PLATFORM_ARG="--platform linux/arm64" -elif [[ "$ARCH" == "x86_64" ]]; then - PLATFORM_ARG="--platform linux/amd64" -fi +PLATFORM_ARG=$(get_platform_arg "$ARCH") docker run $PLATFORM_ARG "${DOCKER_ARGS[@]}" "$IMAGE_TAG" /build/build.sh diff --git a/build/Dockerfile b/build/Dockerfile new file mode 100644 index 0000000..4121ce4 --- /dev/null +++ b/build/Dockerfile @@ -0,0 +1,143 @@ +# ============================================================================== +# Omarchy Package Builder - Multi-Architecture +# Supports: x86_64 (Arch Linux) and aarch64 (Arch Linux ARM) +# ============================================================================== + +# ------------------------------------------------------------------------------ +# Stage 1: Bootstrap - Create base Arch/ALARM system from scratch +# ------------------------------------------------------------------------------ +FROM docker.io/alpine:3.21 AS bootstrapper + +ARG TARGETARCH +ARG BUILDPLATFORM + +COPY pacstrap-docker /usr/local/bin/ + +RUN apk add --no-cache \ + pacman-makepkg \ + curl \ + bash \ + zstd \ + gnupg + +# Map Docker TARGETARCH (amd64/arm64) to Arch naming (x86_64/aarch64) +RUN case "${TARGETARCH}" in \ + amd64) \ + echo "x86_64" > /tmp/arch && \ + printf '[core]\nInclude = /etc/pacman.d/mirrorlist\n\n[extra]\nInclude = /etc/pacman.d/mirrorlist\n' > /tmp/repos.conf ;; \ + arm64) \ + echo "aarch64" > /tmp/arch && \ + printf '[core]\nInclude = /etc/pacman.d/mirrorlist\n\n[extra]\nInclude = /etc/pacman.d/mirrorlist\n\n[alarm]\nInclude = /etc/pacman.d/mirrorlist\n\n[aur]\nInclude = /etc/pacman.d/mirrorlist\n' > /tmp/repos.conf ;; \ + *) \ + echo "Unsupported architecture: ${TARGETARCH}" && exit 1 ;; \ + esac + +RUN mkdir -p /etc/pacman.d && \ + cat /tmp/repos.conf >> /etc/pacman.conf + +RUN if [ "${TARGETARCH}" = "amd64" ]; then \ + printf 'Server = https://mirror.omarchy.org/$repo/os/$arch\nServer = https://mirror.rackspace.com/archlinux/$repo/os/$arch\nServer = https://geo.mirror.pkgbuild.com/$repo/os/$arch\n' > /etc/pacman.d/mirrorlist; \ + else \ + curl -L "https://raw.githubusercontent.com/archlinuxarm/PKGBUILDs/master/core/pacman-mirrorlist/mirrorlist" 2>/dev/null | \ + sed -E 's/^\s*#\s*Server\s*=/Server =/g' > /etc/pacman.d/mirrorlist && \ + sed -i 's/\$arch/aarch64/g' /etc/pacman.d/mirrorlist; \ + fi + +# Bootstrap keyrings (required before pacstrap can verify packages) +RUN mkdir -p /usr/share/pacman/keyrings && \ + if [ "${TARGETARCH}" = "arm64" ]; then \ + KEYRING_URL="https://raw.githubusercontent.com/archlinuxarm/PKGBUILDs/master/core/archlinuxarm-keyring/" && \ + for file in archlinuxarm-revoked archlinuxarm-trusted archlinuxarm.gpg; do \ + curl -fsSL "${KEYRING_URL}${file}" -o /usr/share/pacman/keyrings/${file} || exit 1; \ + done && \ + BOOTSTRAP_EXTRA="archlinuxarm-keyring"; \ + else \ + mkdir /tmp/archlinux-keyring && \ + curl -fsSL https://archlinux.org/packages/core/any/archlinux-keyring/download | \ + unzstd | tar -C /tmp/archlinux-keyring -xv && \ + mv /tmp/archlinux-keyring/usr/share/pacman/keyrings/* /usr/share/pacman/keyrings/ && \ + BOOTSTRAP_EXTRA=""; \ + fi && \ + pacman-key --init && \ + pacman-key --populate + +RUN mkdir /rootfs && \ + if [ "${TARGETARCH}" = "arm64" ]; then \ + BOOTSTRAP_EXTRA="archlinuxarm-keyring"; \ + else \ + BOOTSTRAP_EXTRA=""; \ + fi && \ + pacstrap-docker /rootfs base ${BOOTSTRAP_EXTRA} && \ + cp /etc/pacman.conf /rootfs/etc/pacman.conf && \ + cp /etc/pacman.d/mirrorlist /rootfs/etc/pacman.d/mirrorlist && \ + echo "en_US.UTF-8 UTF-8" > /rootfs/etc/locale.gen && \ + echo "LANG=en_US.UTF-8" > /rootfs/etc/locale.conf && \ + rm -rf /rootfs/var/lib/pacman/sync/* \ + /rootfs/var/cache/pacman/pkg/* \ + /rootfs/tmp/* + +# ------------------------------------------------------------------------------ +# Stage 2: Build Environment +# ------------------------------------------------------------------------------ +FROM scratch AS builder + +ARG TARGETARCH + +COPY --from=bootstrapper /rootfs/ / + +ENV LANG=en_US.UTF-8 +ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +RUN ln -sf /usr/lib/os-release /etc/os-release && \ + locale-gen && \ + pacman-key --init && \ + if pacman -Q archlinuxarm-keyring >/dev/null 2>&1; then \ + pacman-key --populate archlinux archlinuxarm && \ + pacman-key --lsign-key 77193F152BDBE6A6; \ + else \ + pacman-key --populate archlinux; \ + fi + +# Setup Omarchy keyring manually before adding repo (avoids keyserver trust issues) +# Note: Repository is removed at the end since build scripts add it dynamically +RUN pacman-key --recv-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571 --keyserver keys.openpgp.org && \ + pacman-key --lsign-key 40DFB630FF42BCFFB047046CF0134EE680CAC571 && \ + printf '\n[omarchy]\nSigLevel = Optional\nServer = https://pkgs.omarchy.org/$arch\n' >> /etc/pacman.conf && \ + pacman -Sy --noconfirm && \ + pacman -S --noconfirm omarchy-keyring && \ + pacman-key --populate omarchy && \ + sed -i '/^\[omarchy\]/,/^$/d' /etc/pacman.conf + +RUN pacman -Syu --noconfirm && \ + pacman -S --noconfirm \ + base-devel \ + git \ + sudo \ + wget \ + curl \ + jq \ + gnupg && \ + pacman -Scc --noconfirm && \ + rm -rf /var/cache/pacman/pkg/* + +# makepkg cannot run as root +RUN useradd -m -G wheel -s /bin/bash builder && \ + echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \ + mkdir -p /home/builder/.gnupg && \ + chmod 700 /home/builder/.gnupg && \ + chown -R builder:builder /home/builder + +RUN sed -i 's/^#MAKEFLAGS=.*/MAKEFLAGS="-j$(nproc)"/' /etc/makepkg.conf && \ + sed -i 's/^COMPRESSZST=.*/COMPRESSZST=(zstd -c -z -q --threads=0 -)/' /etc/makepkg.conf + +RUN rm -rf /etc/pacman.d/gnupg/{openpgp-revocs.d/,private-keys-v1.d/,pubring.gpg~,gnupg.S.}* + +USER builder +WORKDIR /src + +CMD ["/bin/bash"] + +LABEL maintainer="Omarchy " +LABEL description="Multi-architecture Arch Linux package build environment" +LABEL version="2.0" +LABEL architectures="x86_64,aarch64" diff --git a/build/Dockerfile.x86_64 b/build/Dockerfile.x86_64 deleted file mode 100644 index bd6af10..0000000 --- a/build/Dockerfile.x86_64 +++ /dev/null @@ -1,23 +0,0 @@ -FROM archlinux:latest - -# Update system and install build tools -RUN pacman -Syu --noconfirm && \ - pacman -S --noconfirm base-devel git sudo wget jq gnupg - -# Import Omarchy signing key into pacman keyring -RUN pacman-key --init && \ - pacman-key --recv-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571 --keyserver keys.openpgp.org && \ - pacman-key --lsign-key 40DFB630FF42BCFFB047046CF0134EE680CAC571 - -# Create build user (required for makepkg - cannot run as root) -RUN useradd -m -G wheel builder && \ - echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers - -USER builder -WORKDIR /src - -# Setup GPG directory -RUN mkdir -p ~/.gnupg && chmod 700 ~/.gnupg - -# Default command -CMD ["/build/build.sh"] diff --git a/build/pacstrap-docker b/build/pacstrap-docker new file mode 100755 index 0000000..0e3051f --- /dev/null +++ b/build/pacstrap-docker @@ -0,0 +1,23 @@ +#!/bin/bash +# Simplified pacstrap for Docker (doesn't require mounts) + +set -e + +newroot=$1 +shift +pacman_args=("${@:-base}") + +[[ -d "$newroot" ]] || { echo "ERROR: $newroot is not a directory"; exit 1; } + +echo "==> Creating install root at $newroot" +mkdir -m 0755 -p "$newroot"/var/{cache/pacman/pkg,lib/pacman,log} "$newroot"/{dev,run,etc} +mkdir -m 1777 -p "$newroot"/tmp +mkdir -m 0555 -p "$newroot"/{sys,proc} + +echo "==> Installing packages to $newroot" +if ! pacman -r "$newroot" -Sy --noconfirm "${pacman_args[@]}"; then + echo "ERROR: Failed to install packages" + exit 1 +fi + +echo "==> Installation complete" diff --git a/helpers/docker-helpers.sh b/helpers/docker-helpers.sh index 0b05386..ac88873 100644 --- a/helpers/docker-helpers.sh +++ b/helpers/docker-helpers.sh @@ -1,6 +1,5 @@ # Docker helper functions for Omarchy package build system -# Check Docker is available and running check_docker() { if ! command -v docker &>/dev/null; then print_error "Docker is not installed" @@ -14,26 +13,31 @@ check_docker() { fi } -# Build the Docker image if needed build_docker_image() { local build_dir="$1" local arch="${2:-x86_64}" - local dockerfile="$build_dir/Dockerfile.$arch" local platform="" local image_tag="omarchy-pkg-builder:latest-$arch" - # Set platform for Docker build - if [[ "$arch" == "aarch64" ]]; then - platform="--platform linux/arm64" - elif [[ "$arch" == "x86_64" ]]; then - platform="--platform linux/amd64" - fi + case "$arch" in + x86_64) platform="linux/amd64" ;; + aarch64) platform="linux/arm64" ;; + *) + print_error "Unsupported architecture: $arch" + exit 1 + ;; + esac - print_info "Building Docker image for $arch..." - docker build $platform -t "$image_tag" -f "$dockerfile" "$build_dir" + print_info "Building Docker image for $arch ($platform)..." + + docker buildx build \ + --platform "$platform" \ + --load \ + -t "$image_tag" \ + -f "$build_dir/Dockerfile" \ + "$build_dir" } -# Make directory writable by Docker container user make_dir_writable() { local dir="$1" if [ "$(id -u)" -eq 0 ]; then @@ -42,22 +46,3 @@ make_dir_writable() { sudo chown -R $(id -u):$(id -g) "$dir" 2>/dev/null || chmod -R 777 "$dir" fi } - -# Run a Docker container with standard setup -run_docker() { - local script="$1" - local arch="${2:-x86_64}" - shift 2 - local -a args=("$@") - local image_tag="omarchy-pkg-builder:latest-$arch" - local platform="" - - # Set platform for Docker run - if [[ "$arch" == "aarch64" ]]; then - platform="--platform linux/arm64" - elif [[ "$arch" == "x86_64" ]]; then - platform="--platform linux/amd64" - fi - - docker run --rm $platform "${args[@]}" "$image_tag" "$script" -}