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# Resolve Nix store symlinks for generated files
28GENERATED_MOUNTS=""
29if [ -L "$SCRIPT_DIR/generated/zones" ]; then
30 REAL_ZONES=$(readlink -f "$SCRIPT_DIR/generated/zones")
31 GENERATED_MOUNTS="$GENERATED_MOUNTS -v $REAL_ZONES:$REAL_ZONES:ro"
32fi
33if [ -L "$SCRIPT_DIR/generated/wireguard" ]; then
34 REAL_WG=$(readlink -f "$SCRIPT_DIR/generated/wireguard")
35 GENERATED_MOUNTS="$GENERATED_MOUNTS -v $REAL_WG:$REAL_WG:ro"
36fi
37
38# Build inside Alpine container for aarch64
39# shellcheck disable=SC2086 # GENERATED_MOUNTS needs word splitting
40$CONTAINER_ENGINE run --rm \
41 --platform linux/arm64 \
42 -v "$SCRIPT_DIR":/build:Z \
43 $GENERATED_MOUNTS \
44 -w /tmp \
45 docker.io/library/alpine:3.21 \
46 /build/build-inner.sh "$HOST"