Adds a fast, reproducible install path that unpacks a prebuilt AlmaLinux 9 node
rootfs onto the device (Anaconda liveimg) instead of resolving packages, with
per-host networking still templated after the unpack. Reuses the OptiPlex storage
vars so image and package installs lay disks out identically. Templates-only per
review; the rootfs build lives in the bootapi-images repo.
- kickstart/image.ks.tmpl: liveimg --url={{ .DistroVars.rootfs_tarball }};
%post renders per-host NetworkManager keyfiles from NetBox interface data
(the image is generic and liveimg overwrites /etc), hostname, puppet-initial
PUPPETCA_URL env, and the provisioned callback.
- kickstart/_storage.ks.tmpl: shared storage-block/storage-pre partials
(storage_mode / vg_grow); almalinux9.ks.tmpl now uses them (no behaviour
change).
- catalog/almalinux9-image.yaml (VM autopart) + optiplex-7080-image.yaml
(auto-nvme + vg_grow), rootfs_tarball -> artifactapi rootfs-images repo.
Rootfs tarball built+published by https://git.unkin.net/unkin/bootapi-images
(v* tag). Validated with bootapi validate + shellcheck; no bootapi code change.
Claude-Session: https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
6.4 KiB
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
almalinuxremote, treealmalinux/<ver>/BaseOS/<arch>/os/. Generic / VM default (autopart onsda). - fedora — artifactapi
fedoraremote, treefedora/releases/<ver>/Everything/<arch>/os/. - optiplex-3050 / optiplex-3060 / optiplex-7080 — AlmaLinux 9 on the Dell
OptiPlex fleet. Same install tree and
almalinux9kickstart template, but each passes astorage_mode(and, for the 7080,vg_grow) var so the one template lays disks out per model. Ported from the Cobbler profilesalmalinux9-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.
Image (liveimg) installs
image.ks.tmpl unpacks a prebuilt rootfs tarball with Anaconda liveimg instead
of resolving packages — faster and reproducible. An image catalog entry looks
like a normal one but sets kickstart: image and a rootfs_tarball var:
name: almalinux9-image
match: {platforms: [almalinux9-image]}
kickstart: image
kernel_url: "{{.ArtifactBase}}/almalinux/{{.Version}}/BaseOS/{{.Arch}}/os/images/pxeboot/vmlinuz" # the Anaconda installer kernel, unchanged
initrd_url: "...initrd.img"
vars:
rootfs_tarball: "https://artifactapi.k8s.syd1.au.unkin.net/api/v2/remotes/rootfs-images/files/almalinux9-node-<ver>.tar.zst"
# storage_mode / vg_grow work exactly as for package installs (omit for VM autopart).
- Boot is still the AlmaLinux installer kernel/initrd;
liveimgonly changes the payload. Storage reuses the sharedkickstart/_storage.ks.tmplpartials (storage_mode/vg_grow), so image and package installs lay disks out identically — including the OptiPlex NVMe modes (optiplex-7080-imageshows an image +auto-nvme+vg_growcombination). - Networking is templated per-host in
%post(NetworkManager keyfiles from the same NetBox interface data), because the generic image has no per-host identity and theliveimgunpack overwrites/etc. - The tarball is built by the separate
bootapi-images repo (a
v*tag builds and uploadsalmalinux9-node-<ver>.tar.zstto the artifactapirootfs-imageslocal repo). Baked into the image = everything the%postassumes present (kernel/grub/dracut, NetworkManager, openssh, chrony, kexec-tools, curl, puppet-agent). Bump an image = new bootapi-images release + a one-linerootfs_tarballedit here.
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/withlinux+initrd.gz, and preseed (not kickstart). Adebianentry would setkernel_url/initrd_urlto those paths and reference adebian.preseed.tmpltemplate (and bootapi would serve it from/ksunchanged — it's just text). - Talos: immutable OS booted from factory images (
vmlinuz+initramfs.xzfrom the Talos image factory / a mirrored remote), configured by a machine config, not a kickstart. Atalosentry would pointkernel_url/initrd_urlat the factory artifacts and carry the config URL viakernel_args/vars.
Both are deferred; this note records the shape so the follow-up is mechanical.