235 lines
5.7 KiB
Bash
Executable File
235 lines
5.7 KiB
Bash
Executable File
#!/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
|