- fabrics, VLANs, subnets, IP ranges (dynamic/reserved/static), IPAM with adoption of addresses machines already have; rollcall fabric|vlan|subnet|range|ip - interface layouts (physical/bond/vlan, NICs by selector: boot, name, mac, fastest:N, ib:N) per machine or per tag; deployment allocates addresses and writes cloud-init network-config plus udev name rules (RHEL cloud images boot with net.ifnames=0); release frees them; rollcall layout, rollcall net show|set - region/rack: rollcall rack long-polls its desired state (per-MAC PXE files kept in the database, dnsmasq configuration and host files) and a BMC command queue, caches boot and OS images (kernels/initrds prefetched for TFTP), proxies the node API and tags requests with its name; the region runs an embedded rack controller; install-rack.sh, rollcall-rack.service - dnsmasq configuration generated per rack from the VLANs it serves (split pool for two racks); reload script restarts only on change and restores the last working config if dnsmasq does not come back (drilled in the lab) - web: Network page, per-machine network tab, layout action, tag layout; console: Network page, network section in the machine view, layout action - tests for candidates, plans (default, bond+VLAN, pinned, DHCP fallback), network-config, udev rules and dnsmasq rendering - lab: pve-vbmc address script finds the interface per BMC address Verified in the lab: embedded rack (10.213.77.0/24) and a remote rack controller on a second SDN segment (10.213.78.0/24): enlistment, commissioning, BMC through the rack's queue, image cache, deployment and phone-home through the rack; Debian 13, Ubuntu 24.04 and Rocky 9 with a static boot NIC and with an active-backup bond carrying VLAN 200. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
65 lines
4.5 KiB
Bash
65 lines
4.5 KiB
Bash
#!/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
|
|
sed "s/@AGENT_TOKEN@/$(jq -r .agent_token /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)
|
|
if [ -d /etc/dnsmasq.d ] && [ ! -e /etc/dnsmasq.d/rollcall.conf ]; then
|
|
printf '# rollcall: generated from the network model (rollcall subnet / vlan)\nconf-dir=/var/lib/rollcall/dnsmasq/conf.d/,*.conf\n' > /etc/dnsmasq.d/rollcall.conf
|
|
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
|