iPXE Server

This commit is contained in:
2026-02-02 21:50:03 +01:00
commit 96249d0c06
6 changed files with 743 additions and 0 deletions

234
setup.sh Executable file
View File

@@ -0,0 +1,234 @@
#!/bin/bash
# Setup script for iPXE boot server
# Creates directory structure and deploys Quadlet
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[0;33m'
NC='\033[0m'
log_info() { printf "${BLUE}[INFO]${NC} %s\n" "$1"; }
log_ok() { printf "${GREEN}[OK]${NC} %s\n" "$1"; }
log_warn() { printf "${YELLOW}[WARN]${NC} %s\n" "$1"; }
log_err() { printf "${RED}[ERROR]${NC} %s\n" "$1"; }
# Configuration
IPXE_BASE="${IPXE_BASE:-$HOME/ipxe}"
QUADLET_DIR="${QUADLET_DIR:-$HOME/.config/containers/systemd}"
CADDY_SNIPPETS="${CADDY_SNIPPETS:-$HOME/Caddy/snippets}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
usage() {
cat << EOF
iPXE Boot Server Setup
Usage: $0 [command]
Commands:
install Install Quadlet and create directories
build Build the container image
start Start the iPXE server
stop Stop the iPXE server
status Show server status
logs Show server logs
uninstall Remove Quadlet unit
Options:
--rootless Install for rootless Podman (default)
--root Install system-wide (requires sudo)
EOF
}
create_directories() {
log_info "Creating directory structure..."
mkdir -p "$IPXE_BASE"/{boot,menus,images,config}
mkdir -p "$QUADLET_DIR"
mkdir -p "$CADDY_SNIPPETS"
log_ok "Directories created at $IPXE_BASE"
}
install_quadlet() {
log_info "Installing Quadlet unit..."
# Copy Quadlet file
cp "$SCRIPT_DIR/ipxe-server.container" "$QUADLET_DIR/"
# Update paths in Quadlet to use actual home directory
sed -i "s|%h/ipxe|$IPXE_BASE|g" "$QUADLET_DIR/ipxe-server.container"
log_ok "Quadlet installed to $QUADLET_DIR/ipxe-server.container"
}
install_caddy_snippet() {
log_info "Installing Caddy snippet..."
cp "$SCRIPT_DIR/snippets/ipxe" "$CADDY_SNIPPETS/"
log_ok "Caddy snippet installed to $CADDY_SNIPPETS/ipxe"
log_warn "Don't forget to:"
log_warn " 1. Add 'import snippets/ipxe' to your Caddyfile"
log_warn " 2. Add the ipxe.nuc.lan site block from caddy/ipxe.caddyfile"
log_warn " 3. Reload Caddy: podman exec caddy caddy reload --config /etc/caddy/Caddyfile"
}
copy_default_menu() {
log_info "Copying default boot menu..."
if [[ ! -f "$IPXE_BASE/menus/boot.ipxe" ]]; then
# Extract default menu from Containerfile or use embedded one
cat > "$IPXE_BASE/menus/boot.ipxe" << 'EOF'
#!ipxe
# iPXE Boot Menu - NUC Home Server
set menu-timeout 30000
set menu-default local
:start
menu iPXE Boot Menu - nuc.lan
item --gap -- -------- Boot Options --------
item local Boot from local disk
item --gap -- -------- Network Boot --------
item fedora-live Fedora 42 Live (Minimal)
item fedora-kiosk Fedora 42 Kiosk/PoS
item --gap -- -------- Utilities --------
item shell iPXE Shell
item reboot Reboot
choose --timeout ${menu-timeout} --default ${menu-default} selected || goto cancel
goto ${selected}
:cancel
echo Boot cancelled
goto start
:local
sanboot --no-describe --drive 0x80 || goto start
:fedora-live
echo Booting Fedora 42 Live...
set base-url http://ipxe.nuc.lan/images/fedora-42
kernel ${base-url}/vmlinuz initrd=initrd.img root=live:${base-url}/squashfs.img rd.live.image quiet
initrd ${base-url}/initrd.img
boot || goto start
:fedora-kiosk
echo Booting Fedora 42 Kiosk...
set base-url http://ipxe.nuc.lan/images/fedora-42-kiosk
kernel ${base-url}/vmlinuz initrd=initrd.img root=live:${base-url}/squashfs.img rd.live.image quiet
initrd ${base-url}/initrd.img
boot || goto start
:shell
shell
:reboot
reboot
EOF
log_ok "Default boot menu created"
else
log_warn "Boot menu already exists, skipping"
fi
}
build_image() {
log_info "Building iPXE server container image..."
podman build -t localhost/ipxe-server:latest -f "$SCRIPT_DIR/Containerfile" "$SCRIPT_DIR"
log_ok "Image built: localhost/ipxe-server:latest"
}
reload_systemd() {
log_info "Reloading systemd user units..."
systemctl --user daemon-reload
log_ok "Systemd reloaded"
}
start_server() {
log_info "Starting iPXE server..."
systemctl --user start ipxe-server
log_ok "iPXE server started"
}
stop_server() {
log_info "Stopping iPXE server..."
systemctl --user stop ipxe-server
log_ok "iPXE server stopped"
}
show_status() {
systemctl --user status ipxe-server
}
show_logs() {
journalctl --user -u ipxe-server -f
}
uninstall() {
log_info "Uninstalling iPXE server..."
systemctl --user stop ipxe-server 2>/dev/null || true
rm -f "$QUADLET_DIR/ipxe-server.container"
systemctl --user daemon-reload
log_ok "Quadlet removed"
log_warn "Data in $IPXE_BASE preserved. Remove manually if needed."
}
do_install() {
create_directories
install_quadlet
install_caddy_snippet
copy_default_menu
build_image
reload_systemd
echo ""
log_ok "Installation complete!"
echo ""
echo "Next steps:"
echo " 1. Add boot files to: $IPXE_BASE/boot/"
echo " 2. Add images to: $IPXE_BASE/images/"
echo " 3. Edit boot menu: $IPXE_BASE/menus/boot.ipxe"
echo " 4. Update Caddy config (see caddy/ipxe.caddyfile)"
echo " 5. Start server: $0 start"
echo ""
}
# Main
case "${1:-}" in
install)
do_install
;;
build)
build_image
;;
start)
start_server
;;
stop)
stop_server
;;
status)
show_status
;;
logs)
show_logs
;;
uninstall)
uninstall
;;
-h|--help|help|"")
usage
;;
*)
log_err "Unknown command: $1"
usage
exit 1
;;
esac