main
 1#!/usr/bin/env bash
 2# Build an Alpine initramfs appliance for a given host.
 3# Usage: ./alpine/build.sh <hostname>
 4#
 5# Runs inside a container (podman/docker). Merges common/ and hosts/<hostname>/
 6# into a rootfs, installs packages, runs setup scripts, and produces
 7# kernel + initramfs for RPi 4 boot.
 8set -euo pipefail
 9
10SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
11HOST="${1:?Usage: $0 <hostname>}"
12HOST_DIR="$SCRIPT_DIR/hosts/$HOST"
13OUTPUT_DIR="$SCRIPT_DIR/images/$HOST"
14CONTAINER_ENGINE="${CONTAINER_ENGINE:-podman}"
15
16if [ ! -d "$HOST_DIR" ]; then
17    echo "Error: host directory '$HOST_DIR' not found"
18    echo "Available hosts:"
19    ls "$SCRIPT_DIR/hosts/"
20    exit 1
21fi
22
23echo "==> Building Alpine appliance for $HOST (using $CONTAINER_ENGINE)"
24
25mkdir -p "$OUTPUT_DIR"
26
27# Dereference Nix store symlinks into a temp dir so the container can
28# read them without needing /nix/store mounts (SELinux can't relabel the
29# read-only Nix store).
30GENERATED_TMP=$(mktemp -d)
31# ponytail: force-remove because :Z relabels files, making them owned by container sub-UIDs
32trap 'rm -rf "$GENERATED_TMP" 2>/dev/null || true' EXIT
33if [ -d "$SCRIPT_DIR/generated/zones" ]; then
34    cp -rL "$SCRIPT_DIR/generated/zones" "$GENERATED_TMP/zones"
35fi
36if [ -d "$SCRIPT_DIR/generated/wireguard" ]; then
37    cp -rL "$SCRIPT_DIR/generated/wireguard" "$GENERATED_TMP/wireguard"
38fi
39
40# Build inside Alpine container for aarch64
41$CONTAINER_ENGINE run --rm \
42    --platform linux/arm64 \
43    -v "$SCRIPT_DIR":/build:Z \
44    -v "$GENERATED_TMP":/build/generated:Z \
45    -w /tmp \
46    docker.io/library/alpine:3.23 \
47    /build/build-inner.sh "$HOST"