Files
infra/ansible/bootstrap/generate-aegis-ign.sh
Fabio Scotto di Santolo ae1ca44aa7 Feature/aegis coreos (#7)
* feat(aegis): add ARM image bootstrap workflow

* feat(aegis): manage firewall and SSH hardening

* feat(aegis): harden Fedora IoT services

* chore(aegis): remove local TLS configuration

* fix(aegis): restore supported Fedora IoT bootstrap
2026-09-05 16:58:53 +02:00

148 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env sh
set -eu
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
BUTANE_IMAGE=${BUTANE_IMAGE:-quay.io/coreos/butane:release}
BUTANE_SOURCE=${BUTANE_SOURCE:-"$SCRIPT_DIR/aegis.bu"}
IGNITION_OUTPUT=${IGNITION_OUTPUT:-"$SCRIPT_DIR/config.ign"}
SSH_PUBLIC_KEY=${SSH_PUBLIC_KEY:-"$HOME/.ssh/id_ed25519.pub"}
WIFI_SECURITY=${WIFI_SECURITY:-wpa-psk}
usage() {
cat <<'USAGE'
Usage:
generate-aegis-ign.sh
generate-aegis-ign.sh --write IMAGE DEVICE
Environment overrides:
BUTANE_IMAGE Butane container image (default: quay.io/coreos/butane:release)
BUTANE_SOURCE Butane source path (default: aegis.bu beside this script)
IGNITION_OUTPUT Ignition output path (default: config.ign beside this script)
SSH_PUBLIC_KEY SSH public key passed to arm-image-installer
WIFI_SSID Wi-Fi SSID; prompted if unset in --write mode
WIFI_PASS Wi-Fi password; prompted if unset in --write mode
WIFI_SECURITY Wi-Fi security type (default: wpa-psk)
USAGE
}
require_command() {
if ! command -v "$1" >/dev/null 2>&1; then
printf 'Error: required command not found: %s\n' "$1" >&2
exit 1
fi
}
read_required() {
prompt=$1
value=$2
if [ -z "$value" ]; then
printf '%s' "$prompt" >&2
IFS= read -r value
fi
if [ -z "$value" ]; then
printf '%s\n' 'Error: a value is required.' >&2
exit 1
fi
printf '%s' "$value"
}
read_secret() {
value=$1
if [ -z "$value" ]; then
printf '%s' 'Wi-Fi password: ' >&2
stty -echo
IFS= read -r value
stty echo
printf '\n' >&2
fi
if [ -z "$value" ]; then
printf '%s\n' 'Error: a value is required.' >&2
exit 1
fi
printf '%s' "$value"
}
write_image=false
case $# in
0)
;;
3)
if [ "$1" != '--write' ]; then
usage >&2
exit 2
fi
write_image=true
IMAGE=$2
DEVICE=$3
;;
*)
usage >&2
exit 2
;;
esac
require_command podman
if [ ! -f "$BUTANE_SOURCE" ]; then
printf 'Error: Butane source not found: %s\n' "$BUTANE_SOURCE" >&2
exit 1
fi
OUTPUT_DIR=$(dirname "$IGNITION_OUTPUT")
if [ ! -d "$OUTPUT_DIR" ]; then
printf 'Error: output directory not found: %s\n' "$OUTPUT_DIR" >&2
exit 1
fi
umask 077
TEMP_OUTPUT=$(mktemp "$OUTPUT_DIR/.config.ign.XXXXXX")
trap 'rm -f "$TEMP_OUTPUT"' EXIT HUP INT TERM
podman run --rm -i "$BUTANE_IMAGE" --strict < "$BUTANE_SOURCE" > "$TEMP_OUTPUT"
mv "$TEMP_OUTPUT" "$IGNITION_OUTPUT"
trap - EXIT HUP INT TERM
printf 'Generated Ignition config: %s\n' "$IGNITION_OUTPUT"
if [ "$write_image" = false ]; then
exit 0
fi
if [ ! -f "$IMAGE" ]; then
printf 'Error: image not found: %s\n' "$IMAGE" >&2
exit 1
fi
if [ ! -b "$DEVICE" ]; then
printf 'Error: target is not a block device: %s\n' "$DEVICE" >&2
exit 1
fi
if [ ! -f "$SSH_PUBLIC_KEY" ]; then
printf 'Error: SSH public key not found: %s\n' "$SSH_PUBLIC_KEY" >&2
exit 1
fi
require_command arm-image-installer
WIFI_SSID=$(read_required 'Wi-Fi SSID: ' "${WIFI_SSID:-}")
WIFI_PASS=$(read_secret "${WIFI_PASS:-}")
printf 'Writing %s to %s.\n' "$IMAGE" "$DEVICE" >&2
sudo arm-image-installer \
--image="$IMAGE" \
--target=rpi4 \
--media="$DEVICE" \
--ignition="$IGNITION_OUTPUT" \
--addkey="$SSH_PUBLIC_KEY" \
--resizefs \
--wifi-ssid="$WIFI_SSID" \
--wifi-pass="$WIFI_PASS" \
--wifi-security="$WIFI_SECURITY"