Files
bootapi-templates/kickstart/_storage.ks.tmpl
T
unkinben c66eaedbd8
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 image-based provisioning (liveimg) + shared storage partial
Adds a fast, reproducible install path that unpacks a prebuilt AlmaLinux 9 node
rootfs onto the disk instead of resolving packages, with per-host networking
still templated after the unpack. Storage reuses the OptiPlex model vars so
image and package installs lay disks out identically.

- 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 clobbers /etc), sets hostname, the
  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 too (no behaviour
  change) so both installs share one storage layout.
- catalog/almalinux9-image.yaml (generic autopart) + optiplex-7080-image.yaml
  (auto-nvme + vg_grow) point liveimg at the artifactapi rootfs-images repo.
- .woodpecker/build-image.yaml: builds the rootfs via dnf --installroot,
  tars almalinux9-node-<ver>.tar.zst, uploads to the rootfs-images local repo
  on tag node-image-<ver>.

Validated with bootapi validate + shellcheck; no bootapi code change (DistroVars
+ existing interface data suffice).

Claude-Session: https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
2026-07-29 21:45:17 +10:00

91 lines
4.1 KiB
Cheetah

{{- /*
Shared model-aware storage partials, used by both almalinux9.ks.tmpl (package
install) and image.ks.tmpl (liveimg). One place for the storage layout so the
classic and image installs stay identical on disk.
Driven by the distro catalog vars:
storage_mode "" generic/VM -> autopart on sda
"fixed-nvme" OptiPlex 3050 -> static nvme0n1, BIOS/MBR, fixed VG
"auto-nvme" OptiPlex 3060/7080 -> %pre picks the NVMe, EFI-aware
vg_grow "true" grow the LVM PV to fill the disk (OptiPlex 7080)
liveimg works with this unchanged: Anaconda creates these filesystems, untars the
rootfs into them, writes fstab, installs grub and regenerates the initramfs.
*/ -}}
{{- define "storage-block" -}}
{{- $storage := index .DistroVars "storage_mode" -}}
{{- $grow := eq (index .DistroVars "vg_grow") "true" -}}
{{- if eq $storage "fixed-nvme" }}
# OptiPlex 3050: single known NVMe, legacy BIOS boot (no EFI, no boot-drive).
ignoredisk --only-use=nvme0n1
clearpart --all --initlabel --drives=nvme0n1
part /boot --fstype="xfs" --ondisk=nvme0n1 --size=1024
part pv.01 --fstype="lvmpv" --ondisk=nvme0n1 --size=31743
volgroup rootvg --pesize=4096 pv.01
logvol / --fstype="xfs" --size=10240 --name=root --vgname=rootvg
logvol swap --fstype="swap" --size=2048 --name=swap --vgname=rootvg
logvol /home --fstype="xfs" --size=9207 --name=home --vgname=rootvg
logvol /var/log --fstype="xfs" --size=10240 --name=varlog --vgname=rootvg
bootloader --location=mbr
{{- else if eq $storage "auto-nvme" }}
# OptiPlex 3060 / 7080: partition table generated in %pre (see storage-pre)
# into /tmp/bootapi-partitions, so the OS lands on whichever internal NVMe is
# present and an EFI partition is added only when booted UEFI.
%include /tmp/bootapi-partitions
{{- else }}
# Generic / VM default: single virtual disk, autopart.
ignoredisk --only-use=sda
clearpart --all --initlabel --drives=sda
bootloader --location=mbr --boot-drive=sda --append="crashkernel=auto"
autopart --type=lvm --nohome
{{- end }}
{{- end -}}
{{- define "storage-pre" -}}
{{- $storage := index .DistroVars "storage_mode" -}}
{{- $grow := eq (index .DistroVars "vg_grow") "true" -}}
{{- if eq $storage "auto-nvme" }}
# --- %pre: pick the internal NVMe and emit the partition table -----------------
# Ported from Cobbler almalinux9_dell3060 / almalinux9_dell7080. Anaconda reads
# every section before executing, so /tmp/bootapi-partitions (pulled in by the
# %include above) is populated in time. Picks the first NVMe under 512GB, wipes
# any prior rootvg so re-provisioning is idempotent, and adds an EFI System
# Partition only when the host actually booted UEFI.
%pre --interpreter=/usr/bin/bash --log=/root/bootapi-pre.log
set -x
lsblk -d -b -n -o NAME,SIZE
# First internal NVMe under 512GB (skips large data disks and USB installers).
OSDISK=$(lsblk -d -b -n -o NAME,SIZE | awk '$1 ~ /^nvme/ && $2 < 549755813888 { print $1; exit }')
# Tear down a pre-existing rootvg so a re-install starts from a clean disk.
if vgs rootvg >/dev/null 2>&1; then
lvchange -an rootvg || true
vgchange -an rootvg || true
vgremove -y rootvg || true
for pv in $(pvs --noheadings -o pv_name,vg_name | awk '$2 == "rootvg" { print $1 }'); do
pvremove "$pv" --force --force -y || true
done
fi
wipefs -a "/dev/${OSDISK}"
dd if=/dev/zero of="/dev/${OSDISK}" bs=512 count=100
{
echo "ignoredisk --only-use=${OSDISK}"
echo "clearpart --all --initlabel --drives=${OSDISK}"
if [ -d /sys/firmware/efi ]; then
echo "part /boot/efi --fstype=vfat --ondisk=${OSDISK} --size=200"
fi
echo "part /boot --fstype=xfs --ondisk=${OSDISK} --size=1024"
echo "part pv.01 --fstype=lvmpv --ondisk=${OSDISK} --size=31743{{ if $grow }} --grow{{ end }}"
echo "volgroup rootvg --pesize=4096 pv.01"
echo "logvol / --fstype=xfs --size=10240 --name=root --vgname=rootvg"
echo "logvol swap --fstype=swap --size=2048 --name=swap --vgname=rootvg"
echo "logvol /home --fstype=xfs --size=9207 --name=home --vgname=rootvg"
echo "logvol /var/log --fstype=xfs --size=10240 --name=varlog --vgname=rootvg"
echo "bootloader --location=mbr --boot-drive=${OSDISK}"
} > /tmp/bootapi-partitions
%end
{{- end }}
{{- end -}}