Initial commit: MAAS-deployable Proxmox VE images with cluster automation

Builds a Proxmox VE image that MAAS can deploy to bare metal, plus first-boot
automation that configures the node and joins it to a Proxmox cluster with no
manual steps.

The image starts from the official Debian cloud image and installs proxmox-ve
on top of it, rather than capturing a raw disk from the Proxmox ISO. That keeps
MAAS in control of partitioning, networking, SSH keys and cloud-init, and makes
moving between Proxmox releases a variable change instead of a rewrite.

Contents:

  * Makefile driving the whole flow: build, verify, preseed, upload
  * customize-proxmox.sh, run inside the Packer build VM, which layers Proxmox
    onto the Debian cloud image and resets the pmxcfs node identity so one image
    can produce many nodes
  * pve-maas-init, a first-boot state machine covering /etc/hosts, node-unique
    identifiers, the root password, vmbr0 conversion, cluster create/join and
    the local-lvm thin pool; each stage is resumable across reboots
  * curtin-hooks, which stops curtin installing a kernel over APT and pins
    interface names by MAC so they match what MAAS recorded at commissioning
  * a MAAS curtin preseed template and cloud-init examples
  * deploy-cluster.sh, which builds a whole cluster through the MAAS API
  * verify-image.sh, 22 static checks on the produced tarball

Cluster identity lives entirely in deploy-time cloud-init user-data, so a single
image and preseed can build any number of independent clusters.

Verified end to end against MAAS 3.7.2: proxmox-ve 9.2.0 / pve-manager 9.2.11 /
kernel 7.0.14-15-pve, deployed to two machines that formed a quorate cluster with
local-lvm on both, with no manual intervention.

The README documents four failure modes found along the way that all fail
silently: curtin rejecting "kernel: null", pvenetcommit overwriting the network
configuration at boot, interface renaming leaving the link down, and a systemd
ordering cycle that made systemd delete the service's start job.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-04 21:50:17 +02:00
commit 3d4841f31c
18 changed files with 3395 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
#cloud-config
#
# MAAS curtin preseed - Proxmox VE ozel imaji icin
#
# Dosya adi: curtin_userdata_custom_@@ARCH@@_generic_@@IMAGE_NAME@@
# Kopyalanacak yer (MAAS snap): /var/snap/maas/current/preseeds/
# (MAAS deb paketi): /etc/maas/preseeds/
#
# Bu ad yalnizca 'custom/@@IMAGE_NAME@@' adiyla, '@@ARCH@@/generic' mimarisiyle
# yuklenen imaja uygulanir; diger ozel imajlariniz etkilenmez.
# Cekirdek kurulumu imajdaki /curtin/curtin-hooks tarafindan devre disi
# birakilir (Proxmox cekirdegi imajda hazir gelir). Asagidaki blok yalnizca
# kanca herhangi bir nedenle calismazsa devreye giren yedek yoldur.
#
# DIKKAT: burada 'kernel: null' KULLANMAYIN. MAAS ile gelen curtin
# surumlerinin bir kismi bunu desteklemiyor ve kurulum su hatayla basarisiz
# oluyor: install_kernel -> AttributeError: 'NoneType' object has no
# attribute 'get'
kernel:
package: proxmox-default-kernel
fallback-package: proxmox-default-kernel
mapping: {}
apt:
preserve_sources_list: true
debconf_selections:
maas: |
{{for line in str(curtin_preseed).splitlines()}}
{{line}}
{{endfor}}
late_commands:
maas: [wget, '--no-proxy', '{{node_disable_pxe_url}}', '--post-data', '{{node_disable_pxe_data}}', '-O', '/dev/null']
# Hedef sistemi /mnt altina bagla
late_01: mount --bind $TARGET_MOUNT_POINT /mnt
# MAAS datasource tanimini hedef sisteme tasi
late_02: grep -A2 datasource /etc/cloud/cloud.cfg.d/91_kernel_cmdline_url.cfg | sed 's/curtin//' | tee /mnt/etc/cloud/cloud.cfg.d/91_maas_datasource.cfg
# Debian cloud-init sablonundaki Ubuntu referanslarini duzelt
late_03: sed -i 's@ubuntu.com/ubuntu@debian.org/debian@g;s@archive@deb@g;s@ubuntu@debian@g;s@Ubuntu@Debian@g;s@security.debian.org/debian@security.debian.org@g' /mnt/etc/cloud/cloud.cfg
# zz-update-grub kancasindaki 'set -e' tuzagini kaldir
late_04: sed -i '/^set -e/{n;N;d}' /mnt/etc/kernel/postinst.d/zz-update-grub
# packer-maas'in netplan.io kontrolunu atlatmak icin koydugu sarmalayicilari sil
late_05: rm -f /usr/local/bin/dpkg-query /usr/local/bin/netplan
late_06: rm -f /mnt/usr/local/bin/dpkg-query /mnt/usr/local/bin/netplan
# Guvenlik agi: ilk acilis servisi kesin etkin olsun
late_07: chroot /mnt systemctl enable pve-maas-init.service || true
# Onceki calistirmadan kalan durum dosyalari varsa temizle
late_08: rm -f /mnt/var/lib/pve-maas/*.done /mnt/var/lib/pve-maas/complete