Proxmox VE 9.2 made arm64 official — same code base, repositories and release
lifecycle as x86-64 — and the pve-no-subscription repository carries proxmox-ve,
pve-manager, proxmox-default-kernel and pve-qemu-kvm for it. The build was still
hard-wired to amd64 in four places, which is now fixed:
* firmware is chosen from the target architecture (AAVMF for arm64, OVMF for
amd64) and padded to 64 MiB as QEMU's arm64 virt machine requires. Upstream
packer-maas keys this on the host architecture, which only works when host
and target match.
* host_is_arm is derived from uname rather than hard-coded false, so KVM is
used exactly when host and target architectures agree
* the release body builds its MAAS upload command from MAAS_ARCH, PVE_VERSION
and IMAGE_NAME instead of repeating amd64
* install-deps.sh installs qemu-system-arm and AAVMF under WITH_ARM64=1,
off by default since they are useless on an amd64-only builder
verify-image.sh asserted no kernel matching *-amd64, which would have passed
silently on an arm64 image carrying a Debian arm64 kernel. It now rejects any
/boot/vmlinuz-* not ending in -pve, which holds for both architectures. Checking
that with synthetic file lists caught a first attempt that returned "pass" for an
image containing both a PVE and a Debian kernel, so the expression is now a single
pipeline verified against GNU grep on the build host — the macOS grep this was
first tried on disagrees, and only the Linux behaviour matters here.
No arm64 image has been built and none deployed. The README gains an arm64
section saying so plainly, listing the two real obstacles — TCG emulation on an
x86_64 builder, and having no arm64 hardware to deploy to — and the entry stays
under "Not verified".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Parts of this repository are derived from canonical/packer-maas, which Canonical
distributes under the AGPLv3, so its copyleft carries over and a permissive or
plain-GPL licence is not available:
* maas/curtin_userdata_custom.in is adapted from upstream's
debian/curtin_userdata_custom_amd64, with several late_commands copied
verbatim (the PXE-disable call, the target bind mount, the cloud.cfg rewrite
and the zz-update-grub fix)
* overlay/curtin/curtin-hooks follows upstream's debian/scripts/curtin-hooks:
same imports, same load_command_environment -> load_command_config ->
builtin_curthooks -> cleanup structure, near-identical cleanup(). The
kernel-disabling and interface-pinning functions are original.
The upstream template itself is not vendored; it is cloned at build time and
pinned by PM_REF.
Adds the full AGPL-3.0 text as LICENSE and SPDX-License-Identifier headers to
every source file, placed after the shebang or the #cloud-config marker so both
keep working. deploy-cluster.sh's --help filters the new header lines out of the
usage text it extracts from its own comment block.
GitHub Pages serves index.md, which includes README.md, so the site cannot drift
from the repository documentation. Nothing but build/ is excluded, which keeps
the README's relative links to LICENSE, scripts/ and maas/examples/ resolving on
the published site.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>