Files
OpenPXE/scripts/fetch-ipxe.sh
T
2026-05-06 14:13:38 -04:00

84 lines
3.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Fetch prebuilt iPXE binaries from the official distribution at
# https://boot.ipxe.org/ and place them under assets/ipxe/ with the filenames
# OpenPXE's arch mapping expects.
#
# Why not build from source?
# - Building iPXE requires the toolchain + several megabytes of source, and
# the official binaries are rebuilt nightly from upstream master with the
# standard driver set. For Phase 1 we use those. A later iteration can
# add an optional Dockerfile build stage that compiles iPXE with custom
# driver or scripting patches if needed.
#
# Safety:
# - Upstream (boot.ipxe.org) serves over HTTPS.
# - We do NOT pin by sha256 because upstream is a nightly rolling build;
# pinning would mean stale binaries with known CVEs. If you need
# deterministic builds, mirror these to your own artifact store and
# point the Dockerfile there instead.
# - Each binary is boot firmware the client executes. Only fetch from
# upstream or a mirror you trust; never from random sources.
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
DEST="$ROOT/assets/ipxe"
mkdir -p "$DEST"
# Map: local filename <- upstream path on boot.ipxe.org
# Upstream uses arch-scoped subdirectories; we flatten to the names our
# ClientArch::ipxe_bootfile() expects.
declare -a MAP=(
"undionly.kpxe=undionly.kpxe"
"snponly.efi=x86_64-efi/snponly.efi"
"snponly-i386.efi=i386-efi/snponly.efi"
"snponly-arm64.efi=arm64-efi/snponly.efi"
"ipxe.efi=x86_64-efi/ipxe.efi" # fallback with bundled drivers
)
BASE="https://boot.ipxe.org"
# wimboot lives in its own GitHub release. Fetching it enables the Windows
# toggle in the WebUI. Safe to leave disabled — the binary is vendor-signed
# for iPXE's own use; we never modify it and it only runs inside iPXE's
# memory space, never the target OS.
WIMBOOT_URL="https://github.com/ipxe/wimboot/releases/latest/download/wimboot"
fetched=0
for entry in "${MAP[@]}"; do
local_name="${entry%%=*}"
upstream_name="${entry#*=}"
url="$BASE/$upstream_name"
out="$DEST/$local_name"
echo ">> fetching $url -> $out"
if ! curl --fail --silent --show-error --location --output "$out.tmp" "$url"; then
echo " skip: upstream not available ($url)"
rm -f "$out.tmp"
continue
fi
mv "$out.tmp" "$out"
fetched=$((fetched+1))
done
if [ "$fetched" -eq 0 ]; then
echo
echo "ERROR: zero iPXE binaries were downloaded. The container would build"
echo " but no PXE client could boot. Check your network egress to"
echo " $BASE and re-run this script. Aborting."
exit 2
fi
echo
echo ">> fetching wimboot (optional, enables Windows ISO support)"
if curl --fail --silent --show-error --location --output "$DEST/wimboot.tmp" "$WIMBOOT_URL"; then
mv "$DEST/wimboot.tmp" "$DEST/wimboot"
echo " wimboot installed"
else
echo " skip: wimboot unreachable — Windows toggle will stay disabled in the WebUI"
rm -f "$DEST/wimboot.tmp"
fi
echo
echo "iPXE assets now in $DEST:"
ls -lh "$DEST" | tail -n +2