Files
bootapi-templates/catalog
unkinben 80dbcdd108
ci/woodpecker/push/pre-commit Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/push/validate Pipeline was successful
ci/woodpecker/pr/validate Pipeline was successful
Add per-model OptiPlex kickstart variants from live Cobbler
The seed almalinux9 kickstart reconstructed the Cobbler contract from memory
and guessed storage: it installed to sda with autopart and keyboard us. The
real Cobbler server (cobbler.main.unkin.net) provisions the OptiPlex fleet from
three model-specific profiles (almalinux9-dell_3050 / _3060 / _7080) that all
install to NVMe with an explicit LVM layout and differ in disk selection, EFI
handling and whether the VG grows. This folds that real content in, keeping one
shared template driven by per-model catalog data.

Changes:
- Make almalinux9.ks.tmpl storage model-aware via .DistroVars.storage_mode:
  fixed-nvme (static nvme0n1, BIOS/MBR), auto-nvme (%pre picks the internal
  NVMe, UEFI-aware, --boot-drive), with vg_grow to grow the PV; generic/VM
  hosts keep the autopart-on-sda path.
- Port the explicit LVM layout (/boot, root, swap, /home, /var/log) and the
  %pre NVMe picker + rootvg wipe from the real Cobbler dell templates.
- Add catalog entries optiplex-3050 (fixed-nvme), optiplex-3060 (auto-nvme) and
  optiplex-7080 (auto-nvme + vg_grow), selected by a device's provision_template
  custom field set to the OptiPlex device_type slug.
- Correct keyboard us -> au and add the kdump addon + kexec-tools/bind-utils to
  match the Cobbler profiles.
- Document the per-model variants and selection in catalog/README.md.

Claude-Session: https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
2026-07-29 00:48:15 +10:00
..

Distro catalog

One YAML file per bootable OS. bootapi selects an entry for a NetBox host (platform slug / OS family / provision_template override) and uses it to build the iPXE kernel/initrd URLs and pick the kickstart template. Adding an OS is a YAML + template change here — no bootapi code change.

Fields

Field Required Meaning
name yes catalog key; also what a provision_template override matches
match.platforms one of platforms/family exact NetBox platform slugs
match.family one of platforms/family NetBox platform family (matches any version)
kickstart yes kickstart template name (kickstart/<name>.ks.tmpl)
kernel_url yes Go-template for the installer kernel URL
initrd_url yes Go-template for the installer initrd URL
version_default no version used when the platform slug carries none
kernel_args no extra iPXE kernel args
vars no named Go-template strings exposed to templates as .DistroVars.<key>

kernel_url, initrd_url and vars values are rendered with: {{.ArtifactBase}} (bootapi's BOOTAPI_ARTIFACT_BASE_URL), {{.Version}}, {{.Arch}}, {{.Hostname}}, {{.Platform}}, {{.OSFamily}}.

Shipped entries

  • almalinux9 — artifactapi almalinux remote, tree almalinux/<ver>/BaseOS/<arch>/os/. Generic / VM default (autopart on sda).
  • fedora — artifactapi fedora remote, tree fedora/releases/<ver>/Everything/<arch>/os/.
  • optiplex-3050 / optiplex-3060 / optiplex-7080 — AlmaLinux 9 on the Dell OptiPlex fleet. Same install tree and almalinux9 kickstart template, but each passes a storage_mode (and, for the 7080, vg_grow) var so the one template lays disks out per model. Ported from the Cobbler profiles almalinux9-dell_3050 / _3060 / _7080. See "Per-model variants" below.

Per-model variants (Dell OptiPlex)

Different OptiPlex models need slightly different storage handling, so each is its own catalog entry selecting the shared almalinux9 kickstart with a model-specific storage_mode var:

Entry storage_mode Disk selection Firmware LVM PV
optiplex-3050 fixed-nvme static nvme0n1 legacy BIOS/MBR fixed ~31G
optiplex-3060 auto-nvme %pre picks first NVMe <512G UEFI-aware (EFI part if booted UEFI) fixed ~31G
optiplex-7080 auto-nvme + vg_grow: "true" %pre picks first NVMe <512G UEFI-aware grows to fill disk

The kickstart (kickstart/almalinux9.ks.tmpl) reads .DistroVars.storage_mode / .DistroVars.vg_grow and renders the matching storage stanza; any entry without those vars (e.g. plain almalinux9, fedora) gets the generic autopart-on-sda path.

Model selection (NetBox-driven, no code change): the entry name is the OptiPlex device_type slug. Set the device's provision_template custom field to that slug (optiplex-3050 / -3060 / -7080) and bootapi's catalog Select picks the matching entry (override precedence beats platform/family). The match.platforms slug on each entry is the device_type slug too — not a real NetBox platform slug — so these entries are only reachable via the override and never hijack a plain almalinux9 host. To add another model, copy one of these files, change the name/slug and storage_mode.

Adding another distro (the intended path)

Add catalog/<name>.yaml + kickstart/<name>.ks.tmpl. If the OS lives on a mirror bootapi can't already reach, add an artifactapi remote first (terraform-artifactapi config/remote_rpm/<name>.yaml). CI (bootapi validate) will render the new distro against a fixture host and fail the PR if anything is unresolved.

Debian / Talos — not implemented, different artifact shapes

These need their own catalog fields/template because their PXE artifacts differ from the RHEL-family images/pxeboot/{vmlinuz,initrd.img} layout:

  • Debian: netboot installer under dists/<release>/main/installer-<arch>/current/images/netboot/ with linux + initrd.gz, and preseed (not kickstart). A debian entry would set kernel_url/initrd_url to those paths and reference a debian.preseed.tmpl template (and bootapi would serve it from /ks unchanged — it's just text).
  • Talos: immutable OS booted from factory images (vmlinuz + initramfs.xz from the Talos image factory / a mirrored remote), configured by a machine config, not a kickstart. A talos entry would point kernel_url/initrd_url at the factory artifacts and carry the config URL via kernel_args/vars.

Both are deferred; this note records the shape so the follow-up is mechanical.