Harden emulated ARM builds

This commit is contained in:
Ryan Hughes committed 2026-09-04 23:40:49 -04:00
1 parent 9e9acb071a
commit 0b67dbab8e
4 files changed
+71 -23

No files matched your search

+5 -3
View File
@@ -32,12 +32,14 @@ The filesystem no longer encodes release policy. Instead:
The repository host builds every architecture it publishes on the same
machine. A foreign architecture runs under QEMU user emulation, which
`bin/build` sets up on first use (and re-checks after each reboot by
actually running a container for the target platform):
`bin/build` checks by actually running a container for the target platform.
Rootful Docker registers QEMU on first use. Rootless Podman uses the host's
registration and prints the one-time Arch setup commands when it is missing or
lacks the credential flag required by `sudo` inside the builder:
```bash
# Verify
docker run --rm --platform linux/arm64 alpine:latest uname -m
podman run --rm --platform linux/arm64 docker.io/library/alpine:latest uname -m
# Should output: aarch64
```
+16 -2
View File
@@ -174,10 +174,24 @@ HOST_ARCH=$(uname -m)
if [[ "$HOST_ARCH" != "$ARCH" ]]; then
PROBE_IMAGE="alpine:3.21"
[[ "$CONTAINER_ENGINE" == "podman" ]] && PROBE_IMAGE="docker.io/library/alpine:3.21"
if ! "$CONTAINER_ENGINE" run "${CONTAINER_RUN_ARGS[@]}" --rm "$(get_platform_arg "$ARCH")" "$PROBE_IMAGE" /bin/true >/dev/null 2>&1; then
print_info "Setting up QEMU for $ARCH emulation on this $HOST_ARCH host..."
# Rootless Podman cannot repair host binfmt state itself. Validate the flags
# before the basic probe, because an F-only registration can start an ARM
# container but silently breaks sudo inside it.
if [[ "$CONTAINER_ENGINE" == "podman" ]]; then
setup_qemu "$ARCH"
fi
if ! "$CONTAINER_ENGINE" run "${CONTAINER_RUN_ARGS[@]}" --rm "$(get_platform_arg "$ARCH")" "$PROBE_IMAGE" /bin/true >/dev/null 2>&1; then
if [[ "$CONTAINER_ENGINE" == "podman" ]]; then
print_error "QEMU $ARCH is registered, but the container probe failed"
print_info "Refresh the registration with: sudo systemctl restart systemd-binfmt"
exit 1
else
print_info "Setting up QEMU for $ARCH emulation on this $HOST_ARCH host..."
setup_qemu "$ARCH"
fi
fi
fi
# Clean build-output directory to start fresh, unless the caller seeded it
+35 -15
View File
@@ -5,6 +5,10 @@
# Setup directories
ARCH=${ARCH:-x86_64}
# ARCH selects the repository target for this script, but make and Kbuild also
# interpret an exported ARCH themselves (Linux calls this target "arm64").
# Keep the shell variable local to the orchestrator so PKGBUILDs see CARCH only.
export -n ARCH
MIRROR=${MIRROR:-edge}
DRY_RUN=${DRY_RUN:-false}
PKGBUILDS_DIR=${PKGBUILDS_DIR:-/pkgbuilds}
@@ -60,14 +64,11 @@ if [[ "$DRY_RUN" != true ]]; then
# Configure Omarchy repositories for dependency resolution
echo "==> Configuring Omarchy repositories for dependency resolution..."
# Always add omarchy-build repo (for incremental builds)
# Packages in build-output are unsigned, so use SigLevel = Never
sudo tee -a /etc/pacman.conf > /dev/null <<EOF
[omarchy-build]
SigLevel = Never
Server = file://$BUILD_OUTPUT_DIR
EOF
# Always add omarchy-build repo first (for incremental builds). Repository
# order is pacman's priority order, so this must precede the official repos;
# otherwise pacman can select an older official package with the same name.
# Packages in build-output are unsigned, so use SigLevel = Never.
sudo sed -i "/^\[core\]$/i [omarchy-build]\nSigLevel = Never\nServer = file://$BUILD_OUTPUT_DIR\n" /etc/pacman.conf
echo " -> omarchy-build (priority 1): $BUILD_OUTPUT_DIR"
# Initialize empty build database if it doesn't exist
@@ -90,12 +91,7 @@ EOF
# Add omarchy repo if it has a database (stable packages)
if [[ -f "$FINAL_OUTPUT_DIR/omarchy.db.tar.zst" ]] || [[ -f "$FINAL_OUTPUT_DIR/omarchy.db" ]]; then
sudo tee -a /etc/pacman.conf > /dev/null <<EOF
[omarchy]
SigLevel = Optional TrustAll
Server = file://$FINAL_OUTPUT_DIR
EOF
sudo sed -i "/^\[core\]$/i [omarchy]\nSigLevel = Optional TrustAll\nServer = file://$FINAL_OUTPUT_DIR\n" /etc/pacman.conf
echo " -> omarchy (priority 2): $FINAL_OUTPUT_DIR"
fi
@@ -336,8 +332,14 @@ build_package() {
# Ensure output directory exists
mkdir -p "$BUILD_OUTPUT_DIR"
local dependency_pkg_file=""
for pkg_file in *.pkg.tar.*; do
[[ -f "$pkg_file" ]] && cp "$pkg_file" "$BUILD_OUTPUT_DIR/"
[[ -f "$pkg_file" && "$pkg_file" != *.sig ]] || continue
cp "$pkg_file" "$BUILD_OUTPUT_DIR/"
if [[ "$(bsdtar -xOf "$pkg_file" .PKGINFO 2>/dev/null | sed -n 's/^pkgname = //p')" == "$pkg" ]]; then
dependency_pkg_file="$BUILD_OUTPUT_DIR/$pkg_file"
fi
done
cd "$BUILD_OUTPUT_DIR"
@@ -353,6 +355,24 @@ build_package() {
cd /src/$pkg
# A lower-priority official repository may contain an older package with
# the same name. Install the exact artifact we just built before building
# its consumers, so pacman cannot select that older provider instead.
if [[ "${INSTALL_PACKAGES[$pkg]:-}" == "1" ]]; then
if [[ -z "$dependency_pkg_file" ]]; then
echo " Could not find the built $pkg package to install as a dependency"
FAILED_PACKAGES="$FAILED_PACKAGES $pkg"
return 1
fi
echo " Installing freshly built $pkg for dependent packages..."
if ! sudo /usr/local/bin/pacman-for-makepkg -U --needed --noconfirm "$dependency_pkg_file"; then
echo " Failed to install freshly built dependency $pkg"
FAILED_PACKAGES="$FAILED_PACKAGES $pkg"
return 1
fi
fi
echo " Successfully built $pkg"
SUCCESSFUL_PACKAGES="$SUCCESSFUL_PACKAGES $pkg"
return 0
+15 -3
View File
@@ -69,13 +69,25 @@ setup_qemu() {
if [[ "$CONTAINER_ENGINE" == "podman" ]]; then
local registration="/proc/sys/fs/binfmt_misc/qemu-$target_arch"
if [[ -r "$registration" ]] && grep -q '^flags:.*F' "$registration"; then
local packaged_registration="/usr/lib/binfmt.d/qemu-$target_arch-static.conf"
local flags=""
if [[ -r "$registration" ]]; then
flags=$(sed -n 's/^flags: //p' "$registration")
fi
if [[ "$flags" == *F* && "$flags" == *C* ]]; then
print_success "QEMU $target_arch emulation is registered"
return 0
fi
print_error "Rootless Podman requires host QEMU binfmt registration with the F flag"
print_info "Install it with: sudo pacman -S qemu-user-static qemu-user-static-binfmt"
print_error "Rootless Podman requires QEMU binfmt registration with the F and C flags"
print_info "F keeps the emulator available inside containers; C lets container sudo preserve credentials."
print_info "Configure it once with:"
echo " sudo pacman -S --needed qemu-user-static qemu-user-static-binfmt"
echo " sudo mkdir -p /etc/binfmt.d"
echo " sed 's/:FP$/:FPC/' $packaged_registration | sudo tee /etc/binfmt.d/qemu-$target_arch-static.conf >/dev/null"
echo " sudo systemctl restart systemd-binfmt"
exit 1
fi