Files
Ilker ManapandClaude Opus 5.5 a0df7295ea
CI / agent (push) Successful in 3s
CI / site (push) Successful in 2s
CI / go (push) Successful in 40s
UEFI PXE through signed shim and GRUB (Secure Boot)
UEFI machines were given syslinux.efi, which is unsigned: with Secure
Boot on (the default on much server hardware) the firmware refuses it
("Access Denied", seen on an OVMF lab VM), so such a machine could not
PXE-boot at all. They now get Debian's signed shim (bootx64.efi), which
loads the signed network GRUB (grubx64.efi); GRUB reads
grub/grub.cfg-<mac>, else grub/grub.cfg-default, and loads kernels
only as shim verifies them. Rack controllers write the GRUB menus from
the pxelinux menus they already get (same entries: kernel and initrd,
local disk via exit, power off via halt), so both always agree; BIOS
machines keep pxelinux. install.sh, install-rack.sh and bootstrap.sh
install shim-signed and grub-efi-amd64-signed and lay out the files.

Secure Boot covers the kernel; the initrd and the squashfs it fetches
are not covered by it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:25:54 +01:00

76 lines
5.3 KiB
Bash
Executable File

#!/bin/sh
# Install the rollcall binary on pxe-server. Run as root from this directory.
# Prereqs: PostgreSQL running locally with role+db "rollcall";
# /etc/rollcall/config.json present (see config.example.json).
set -eu
cd "$(dirname "$0")"
getent passwd rollcall >/dev/null || useradd --system --no-create-home --shell /usr/sbin/nologin --user-group rollcall
install -d -m 0750 -o root -g rollcall /etc/rollcall
install -d /srv/rollcall/image
[ -x ./rollcall ] && install -m 0755 rollcall /usr/local/bin/rollcall
install -m 0644 rollcall.service /etc/systemd/system/
[ -e /etc/rollcall/config.json ] || { echo "write /etc/rollcall/config.json first (see config.example.json)" >&2; exit 1; }
chown root:rollcall /etc/rollcall/config.json && chmod 0640 /etc/rollcall/config.json
# master key is created by the service on first start; the dir must be writable for that
chown rollcall:rollcall /etc/rollcall
# rollcall writes per-MAC pxelinux configs
chgrp rollcall /srv/tftp/pxelinux.cfg && chmod 2775 /srv/tftp/pxelinux.cfg
install -m 0644 /usr/lib/syslinux/modules/bios/poweroff.c32 /srv/tftp/poweroff.c32
# UEFI, Secure Boot included: signed shim and GRUB; rollcall writes the GRUB menus next to pxelinux's
if [ -f /usr/lib/shim/shimx64.efi.signed ] && [ -f /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed ]; then
install -m 0644 /usr/lib/shim/shimx64.efi.signed /srv/tftp/bootx64.efi
install -m 0644 /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed /srv/tftp/grubx64.efi
install -d -o root -g rollcall -m 2775 /srv/tftp/grub
else
echo "WARNING: shim-signed or grub-efi-amd64-signed missing: UEFI machines cannot PXE-boot (apt install shim-signed grub-efi-amd64-signed)" >&2
fi
sed -e "s/@AGENT_TOKEN@/$(jq -r .agent_token /etc/rollcall/config.json)/g" -e "s#@SERVER@#$(jq -r .server_url /etc/rollcall/config.json)#g" pxelinux-default > /srv/tftp/pxelinux.cfg/default && chmod 0644 /srv/tftp/pxelinux.cfg/default
[ -e /srv/tftp/rollcall ] || ln -s /srv/rollcall/image /srv/tftp/rollcall
[ -d /srv/tftp/efi64 ] && ln -sfn ../rollcall /srv/tftp/efi64/rollcall
# stateless images: <images_dir>/<name>/..., reachable by pxelinux as images/<name>/
install -d /srv/rollcall/images
[ -e /srv/tftp/images ] || ln -s /srv/rollcall/images /srv/tftp/images
[ -d /srv/tftp/efi64 ] && ln -sfn ../images /srv/tftp/efi64/images
# overlay templates (server-only secrets such as munge.key live next to them and are kept)
install -d -m 0750 -o root -g rollcall /etc/rollcall/overlays
cp -a overlays/. /etc/rollcall/overlays/
chgrp -R rollcall /etc/rollcall/overlays
# OS deployment images: <os_dir>/<name>/<version>/disk.raw.zst, written by `rollcall os sync` (user rollcall)
install -d -m 0755 -o rollcall -g rollcall /srv/rollcall/os
[ -e /etc/rollcall/os-sources.json ] || install -m 0644 os-sources.json /etc/rollcall/os-sources.json
install -m 0644 rollcall-os-sync.service rollcall-os-sync.timer /etc/systemd/system/
command -v qemu-img >/dev/null || echo "WARNING: qemu-img missing (apt install qemu-utils) - rollcall os sync/import will fail" >&2
# dnsmasq host export + reload trigger
install -d -m 0755 /var/lib/rollcall
install -d -m 0755 -o rollcall -g rollcall /var/lib/rollcall/dnsmasq /var/lib/rollcall/dnsmasq/conf.d
for f in hosts hosts.dhcp; do [ -e /var/lib/rollcall/dnsmasq/$f ] || install -m 0644 -o rollcall -g rollcall /dev/null /var/lib/rollcall/dnsmasq/$f; done
install -m 0755 rollcall-dnsmasq-reload.sh /usr/local/bin/rollcall-dnsmasq-reload.sh
install -m 0644 rollcall-dnsmasq.path rollcall-dnsmasq.service /etc/systemd/system/
# the embedded rack controller writes conf.d/rollcall.conf once a VLAN with dhcp is assigned to it;
# a hand-written dnsmasq configuration for the same interface has to go then (see README, Network).
# dnsmasq (root) reads the checked copy rollcall-dnsmasq-reload.sh keeps in a directory of root's.
install -d -m 0755 /var/lib/rollcall-dnsmasq
if [ -d /etc/dnsmasq.d ]; then
printf '# rollcall: generated from the network model (rollcall subnet / vlan), checked by rollcall-dnsmasq-reload.sh\nconf-dir=/var/lib/rollcall-dnsmasq/,*.conf\n' > /etc/dnsmasq.d/rollcall.conf
/usr/local/bin/rollcall-dnsmasq-reload.sh >/dev/null 2>&1 || true
fi
legacy=$(grep -lE '^(dhcp-range|bind-interfaces|enable-tftp)' /etc/dnsmasq.conf /etc/dnsmasq.d/*.conf 2>/dev/null | grep -v '/rollcall.conf$' || true)
if [ -n "$legacy" ]; then
echo "NOTE: hand-written dnsmasq DHCP/TFTP configuration in: $legacy" >&2
echo " Once a VLAN with dhcp is assigned to this host (rollcall vlan add … -dhcp), rollcall generates" >&2
echo " that configuration; move these files away then, or the generated one is rejected." >&2
fi
# optional: this host is also the Slurm controller -> keep its slurm.conf rendered from the profile
install -m 0644 rollcall-controller-sync.service rollcall-controller-sync.timer /etc/systemd/system/
install -m 0755 rollcall-controller-sync.sh /usr/local/bin/rollcall-controller-sync.sh
systemctl daemon-reload
systemctl enable --now rollcall-dnsmasq.path >/dev/null 2>&1 || true
systemctl enable --now rollcall-os-sync.timer >/dev/null 2>&1 || true
if systemctl list-unit-files slurmctld.service >/dev/null 2>&1 && [ -d /etc/slurm ]; then
systemctl enable --now rollcall-controller-sync.timer >/dev/null 2>&1 || true
fi
systemctl enable --now rollcall.service
systemctl restart rollcall.service
sleep 1
systemctl --no-pager status rollcall.service | head -5