mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
28ca689130
* feat: add GPU discovery package (mulga-992) Adds spinifex/gpu package with sysfs-based GPU enumeration, IOMMU group member lookup, and a PCI device ID model table. Vendor-specific enrichment via nvidia-smi is attempted opportunistically and falls back to the built-in table when unavailable. All discovery and IOMMU logic is covered by unit tests using mock sysfs trees. * feat: add VFIO bind/unbind and GPU pool manager (mulga-993) Adds gpu.BindVFIO/UnbindVFIO using sysfs driver_override for per-device driver switching, and gpu.Manager which owns the claim/release lifecycle for the GPU pool including full IOMMU group binding, rollback on partial failure, and marking entries unavailable when rebind fails after VM termination. * feat: add G5 instance type generator with GPU model support (mulga-994) - Add GPUModel type, NVIDIAa10g constant, and GPUModelForVendorDevice lookup - Add generateGPUTypes to emit g5.* types with GpuInfo populated - Add IsGPUType helper for consumers filtering GPU-capable types - Update DetectAndGenerate to accept gpuModels []GPUModel parameter * feat: integrate GPU passthrough into daemon lifecycle (mulga-995) - Add gpu_passthrough config flag; discover GPUs and build manager at startup - Gate g5 instance types on GPU pool availability via canAllocateCount - Claim GPU (VFIO bind) in LaunchInstance; inject vfio-pci QEMU device - Release GPU (VFIO unbind, rebind to host driver) in stopInstance - Re-claim GPU on daemon restart when QEMU process is still alive - Add UseUEFI / OVMF support for x86_64 VMs (optional, falls back to SeaBIOS) - Fix Claim to use stored OriginalDriver when device is already vfio-pci bound * feat: add GPU fields to NodeStatus and spx top nodes (mulga-996) - Add TotalGPUs/AllocGPUs to NodeStatusResponse (zero on non-GPU nodes) - Populate from gpuManager in handleNodeStatus - Show GPU (used/total) column in spx top nodes; "-" when no GPUs present * feat: Ubuntu 24.04 GPU AMI build pipeline (mulga-997) Extends build-system-image.sh to support Ubuntu alongside Alpine. Key differences handled: partition table (parted resizepart p1), bind mounts for DKMS (/proc /sys /dev), apt vs apk, systemctl vs rc-update. DISTRO defaults to "alpine" for backward compatibility. Adds ubuntu-gpu.conf manifest and ubuntu-gpu-setup.sh chroot script that installs nvidia-headless-550-server with DKMS pre-built against a pinned linux-image-generic kernel, blacklists nouveau, and prevents unattended-upgrades from invalidating the pre-built module. * Fixed GPU passthrough and added test script * feat: always-probe GPU at startup, surface capability in NodeStatusResponse - Add gpuProbeResult struct and probeGPU() which runs at daemon startup regardless of gpu_passthrough config. Checks sysfs for GPUs, IOMMU groups, and vfio_pci module presence. - Store gpuProbe on Daemon struct; split NewDaemon into probe (always) and activate (opt-in) phases. - Populate GPUCapable, GPUPassthrough, GPUModels on NodeStatusResponse so operators can see hardware state before enabling passthrough. - Update 'spx top' GPU column: '-' = no hardware, '0/N*' = capable but passthrough not active, 'used/total' = passthrough active. * feat: SIGHUP hot-reload for GPU passthrough config (mulga-1001) - Export GenerateGPUTypes for use by the reload path - Add ResourceManager.reloadGPUTypes: mutates instanceTypes map in-place (preserves references held by instanceService) and updates NATS subscriptions without full daemon restart - Separate SIGHUP from SIGTERM/SIGINT: setupReload() listens for SIGHUP in a context-aware loop; setupShutdown no longer intercepts SIGHUP - Add reloadConfig() + applyGPUConfig(): re-reads spinifex.toml on signal, handles false→true (re-probe + activate) and true→false (refuse if instances running, otherwise deactivate) transitions * feat: spx admin gpu status/enable/disable commands (mulga-1000) - admin.SetGPUPassthrough: Go implementation of the idempotent TOML write (replaces the inline Python heredoc in spx-test-gpu.sh) - spx admin gpu status: shows GPU hardware, IOMMU/vfio state, passthrough activation, and advertised g5 instance types via NATS NodeStatusResponse - spx admin gpu enable: checks prerequisites, writes TOML, sends SIGHUP, polls until daemon confirms GPUPassthrough=true - spx admin gpu disable: refuses while GPU instances are running, otherwise writes TOML, sends SIGHUP, polls until confirmed - spx-test-gpu.sh: replace Python TOML heredoc with spx admin gpu enable * fixed admin * fix: filter Intel iGPU from passthrough pool, use lspci for consumer GPU names Discover() now skips non-NVIDIA/AMD vendors so Intel iGPUs never enter the passthrough pool. enrichFromLspci() uses the system PCI ID database via lspci -vmm to populate the model name for any card not in the hardcoded table, without needing nvidia-smi or driver tools. * fix: grant CAP_SYS_ADMIN and vfio device access to spinifex-daemon GPU passthrough requires writing to /sys/bus/pci/drivers/vfio-pci/unbind on instance stop. The kernel gates this on CAP_SYS_ADMIN regardless of file permissions. QEMU subprocesses also need char-vfio rw access to open /dev/vfio/N for the passed-through device. * fixing gpu bining permissions * working state of gpu passthrough on phyiscal box * installer grub image fixes * made gpu-passthrough more user facing * fixed banner * fixed banner * banner fix * gpu passthrough docs * preflight tweak * vpcd fixes to set br-wan to promisc for public IP DHCP processes * fixed vpcd br-wan promisc and veth pair * ssh keygen fix * fixes after running /review-branch * feat: re-wire GPU claim and device injection after vm.Manager refactor GPU passthrough claim (VFIO bind) and QEMU device injection were lost when dev's vm.Manager refactor (#185/#186) moved StartInstance/ CreateQMPClient into vm/lifecycle.go. Re-add both in their correct new homes: - daemon_handlers_instance.go: claim GPU before vmMgr.Run() in both RunInstances and StartStoppedInstance handlers; release on failure - vm/lifecycle.go startQEMU(): inject vfio-pci device with x-vga flag derived from instance.GPUXVGAEnabled when GPUPCIAddress is set * fix: Create spinifex user ~/.ssh and keys in firstboot --------- Co-authored-by: Ben Duncan <5178243+benduncan@users.noreply.github.com> Co-authored-by: Julian Sommer <115516918+juliansommer@users.noreply.github.com>
83 lines
3.0 KiB
Bash
Executable File
83 lines
3.0 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# ubuntu-gpu-setup.sh — Chroot setup for Ubuntu 24.04 GPU AMI
|
|
#
|
|
# Installs NVIDIA headless server driver with DKMS module pre-built against
|
|
# a pinned kernel. Blacklists nouveau. Prevents unattended-upgrades from
|
|
# invalidating the pre-built module.
|
|
#
|
|
# Must run inside an Ubuntu 24.04 chroot with /proc /sys /dev bind-mounted
|
|
# (required by DKMS during the nvidia package post-install hook).
|
|
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
|
|
apt-get update
|
|
|
|
# Install a pinned kernel and its headers so DKMS has a stable build target.
|
|
# linux-image-generic and linux-headers-generic pull in the current HWE stack.
|
|
apt-get install -y --no-install-recommends \
|
|
linux-image-generic \
|
|
linux-headers-generic
|
|
|
|
# Capture the installed kernel version before adding the driver.
|
|
KVER=$(ls /boot/vmlinuz-* 2>/dev/null | sort -V | tail -1 | sed 's|/boot/vmlinuz-||')
|
|
if [[ -z "${KVER}" ]]; then
|
|
echo "ERROR: No kernel found under /boot after linux-image-generic install"
|
|
exit 1
|
|
fi
|
|
echo "Target kernel: ${KVER}"
|
|
|
|
# Install the NVIDIA headless server driver.
|
|
# The nvidia-dkms-550-server post-install hook runs `dkms autoinstall`, which
|
|
# builds the module against every kernel found under /lib/modules/ — including
|
|
# ${KVER} whose headers we just installed above.
|
|
apt-get install -y --no-install-recommends \
|
|
nvidia-headless-550-server \
|
|
nvidia-utils-550-server
|
|
|
|
# Verify the DKMS module was registered and built.
|
|
if dkms status 2>/dev/null | grep -q "nvidia"; then
|
|
echo "NVIDIA DKMS module status: $(dkms status 2>/dev/null | grep nvidia | head -1)"
|
|
else
|
|
echo "WARNING: nvidia DKMS module not found in dkms status — manual verification required"
|
|
fi
|
|
|
|
# Pin the kernel so unattended-upgrades cannot replace it and invalidate
|
|
# the pre-built DKMS module.
|
|
apt-mark hold \
|
|
linux-image-generic \
|
|
linux-headers-generic \
|
|
"linux-image-${KVER}" \
|
|
"linux-headers-${KVER}"
|
|
|
|
# Pin all installed NVIDIA packages for the same reason.
|
|
NVIDIA_PKGS=$(dpkg --get-selections 'nvidia-*' 2>/dev/null | awk '/install$/{print $1}' || true)
|
|
LIBNVIDIA_PKGS=$(dpkg --get-selections 'libnvidia-*' 2>/dev/null | awk '/install$/{print $1}' || true)
|
|
# shellcheck disable=SC2086
|
|
[[ -n "${NVIDIA_PKGS}" ]] && apt-mark hold ${NVIDIA_PKGS}
|
|
# shellcheck disable=SC2086
|
|
[[ -n "${LIBNVIDIA_PKGS}" ]] && apt-mark hold ${LIBNVIDIA_PKGS}
|
|
|
|
# Blacklist nouveau so it does not conflict with the NVIDIA driver on boot.
|
|
cat > /etc/modprobe.d/blacklist-nouveau.conf << 'EOF'
|
|
blacklist nouveau
|
|
options nouveau modeset=0
|
|
EOF
|
|
|
|
# Prevent unattended-upgrades from updating kernel or NVIDIA packages,
|
|
# which would break the pre-built DKMS module.
|
|
mkdir -p /etc/apt/apt.conf.d
|
|
cat > /etc/apt/apt.conf.d/99-gpu-ami << 'EOF'
|
|
Unattended-Upgrade::Package-Blacklist {
|
|
"linux-";
|
|
"nvidia-";
|
|
"libnvidia-";
|
|
};
|
|
EOF
|
|
|
|
# Rebuild initramfs with nouveau blacklisted and NVIDIA module included.
|
|
update-initramfs -u -k "${KVER}"
|
|
|
|
echo "GPU AMI setup complete: kernel=${KVER}, NVIDIA 550 driver installed, DKMS module pre-built"
|