Wire up arm64 without claiming it works
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>
This commit is contained in:
33
Makefile
33
Makefile
@@ -31,6 +31,9 @@ PVE_EXTRA_PACKAGES ?= ifupdown2 open-iscsi chrony postfix lvm2 thin-provisioning
|
|||||||
ethtool bridge-utils ipmitool nvme-cli lsscsi sudo
|
ethtool bridge-utils ipmitool nvme-cli lsscsi sudo
|
||||||
|
|
||||||
# ---------------------------------------------------------------- imaj ayarlari
|
# ---------------------------------------------------------------- imaj ayarlari
|
||||||
|
# amd64 | arm64. arm64 is wired up but has never been built or deployed -
|
||||||
|
# see "Verified status" in the README. Building arm64 on an x86_64 host means
|
||||||
|
# TCG emulation with no KVM, which is very slow; prefer a native arm64 builder.
|
||||||
ARCH ?= amd64
|
ARCH ?= amd64
|
||||||
SUBARCH ?= generic
|
SUBARCH ?= generic
|
||||||
BOOT ?= uefi
|
BOOT ?= uefi
|
||||||
@@ -85,8 +88,21 @@ MAAS_IMAGE_NAME ?= custom/$(IMAGE_NAME)
|
|||||||
# MAAS snap kurulumu icin: /var/snap/maas/current/preseeds
|
# MAAS snap kurulumu icin: /var/snap/maas/current/preseeds
|
||||||
MAAS_PRESEED_DIR ?= /var/snap/maas/current/preseeds
|
MAAS_PRESEED_DIR ?= /var/snap/maas/current/preseeds
|
||||||
|
|
||||||
OVMF_DIR ?= /usr/share/OVMF
|
# UEFI firmware, keyed on the TARGET architecture - an aarch64 guest needs
|
||||||
OVMF_SFX ?= $(shell test -f $(OVMF_DIR)/OVMF_CODE.fd && echo "" || echo "_4M")
|
# AAVMF whatever the build host is. (Upstream packer-maas keys this on the host
|
||||||
|
# architecture instead, which only works when host and target match.)
|
||||||
|
ifeq ($(strip $(ARCH)),arm64)
|
||||||
|
FW_DIR ?= /usr/share/AAVMF
|
||||||
|
FW ?= AAVMF
|
||||||
|
else
|
||||||
|
FW_DIR ?= /usr/share/OVMF
|
||||||
|
FW ?= OVMF
|
||||||
|
endif
|
||||||
|
FW_SFX ?= $(shell test -f $(FW_DIR)/$(FW)_CODE.fd && echo "" || echo "_4M")
|
||||||
|
|
||||||
|
# KVM is only usable when the host and the guest share an architecture.
|
||||||
|
# Otherwise QEMU falls back to TCG emulation, which is very slow.
|
||||||
|
HOST_IS_ARM := $(shell test "$$(uname -m)" = aarch64 && echo true || echo false)
|
||||||
|
|
||||||
# ---------------------------------------------------------------- hedefler
|
# ---------------------------------------------------------------- hedefler
|
||||||
.PHONY: help deps deps-cache check-upstream print-var checkout overlay customize image verify preseed install-preseed upload clean distclean lint
|
.PHONY: help deps deps-cache check-upstream print-var checkout overlay customize image verify preseed install-preseed upload clean distclean lint
|
||||||
@@ -165,8 +181,13 @@ ifeq ($(strip $(DEBIAN_IMAGE_CHANNEL)),stable)
|
|||||||
endif
|
endif
|
||||||
sed -i -E 's|--best --force|-$(GZIP_LEVEL) --force|' $(PM)/scripts/fuse-tar-root
|
sed -i -E 's|--best --force|-$(GZIP_LEVEL) --force|' $(PM)/scripts/fuse-tar-root
|
||||||
@grep -nE 'disk_size|^ cpus|^ memory' $(TPL)/debian-cloudimg.pkr.hcl
|
@grep -nE 'disk_size|^ cpus|^ memory' $(TPL)/debian-cloudimg.pkr.hcl
|
||||||
cp -v $(OVMF_DIR)/OVMF_CODE$(OVMF_SFX).fd $(TPL)/OVMF_CODE.fd
|
cp -v $(FW_DIR)/$(FW)_CODE$(FW_SFX).fd $(TPL)/OVMF_CODE.fd
|
||||||
cp -v $(OVMF_DIR)/OVMF_VARS$(OVMF_SFX).fd $(TPL)/OVMF_VARS.fd
|
cp -v $(FW_DIR)/$(FW)_VARS$(FW_SFX).fd $(TPL)/OVMF_VARS.fd
|
||||||
|
ifeq ($(strip $(ARCH)),arm64)
|
||||||
|
# AAVMF images must be padded to 64 MiB for QEMU's arm64 "virt" machine.
|
||||||
|
truncate -s 64m $(TPL)/OVMF_CODE.fd
|
||||||
|
truncate -s 64m $(TPL)/OVMF_VARS.fd
|
||||||
|
endif
|
||||||
rm -rf $(TPL)/output-cloudimg $(TPL)/seeds-cloudimg.iso
|
rm -rf $(TPL)/output-cloudimg $(TPL)/seeds-cloudimg.iso
|
||||||
cd $(TPL) && PACKER_LOG=$(PACKER_LOG) packer init .
|
cd $(TPL) && PACKER_LOG=$(PACKER_LOG) packer init .
|
||||||
cd $(TPL) && PACKER_LOG=$(PACKER_LOG) packer build \
|
cd $(TPL) && PACKER_LOG=$(PACKER_LOG) packer build \
|
||||||
@@ -174,8 +195,8 @@ endif
|
|||||||
-var debian_version=$(DEBIAN_VERSION) \
|
-var debian_version=$(DEBIAN_VERSION) \
|
||||||
-var architecture=$(ARCH) \
|
-var architecture=$(ARCH) \
|
||||||
-var boot_mode=$(BOOT) \
|
-var boot_mode=$(BOOT) \
|
||||||
-var ovmf_suffix=$(OVMF_SFX) \
|
-var ovmf_suffix=$(FW_SFX) \
|
||||||
-var host_is_arm=false \
|
-var host_is_arm=$(HOST_IS_ARM) \
|
||||||
-var timeout=$(TIMEOUT) \
|
-var timeout=$(TIMEOUT) \
|
||||||
-var customize_script=$(CUSTOMIZE) \
|
-var customize_script=$(CUSTOMIZE) \
|
||||||
-var filename=$(OUTPUT) \
|
-var filename=$(OUTPUT) \
|
||||||
|
|||||||
43
README.md
43
README.md
@@ -28,6 +28,7 @@ variable change away (see [Moving to a new Proxmox release](#moving-to-a-new-pro
|
|||||||
- [Four traps this image works around](#four-traps-this-image-works-around)
|
- [Four traps this image works around](#four-traps-this-image-works-around)
|
||||||
- [Moving to a new Proxmox release](#moving-to-a-new-proxmox-release)
|
- [Moving to a new Proxmox release](#moving-to-a-new-proxmox-release)
|
||||||
- [Build performance](#build-performance)
|
- [Build performance](#build-performance)
|
||||||
|
- [arm64](#arm64)
|
||||||
- [Release automation](#release-automation)
|
- [Release automation](#release-automation)
|
||||||
- [Repository layout](#repository-layout)
|
- [Repository layout](#repository-layout)
|
||||||
- [Troubleshooting](#troubleshooting)
|
- [Troubleshooting](#troubleshooting)
|
||||||
@@ -262,7 +263,7 @@ All of these are `make` variables — `sudo make image DISK_SIZE=24G`, and so on
|
|||||||
| Variable | Default | Meaning |
|
| Variable | Default | Meaning |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `IMAGE_NAME` | `proxmox-ve-9` | MAAS name (`custom/<name>`) and preseed filename |
|
| `IMAGE_NAME` | `proxmox-ve-9` | MAAS name (`custom/<name>`) and preseed filename |
|
||||||
| `ARCH` / `SUBARCH` | `amd64` / `generic` | Target architecture. *Only amd64 was tested.* |
|
| `ARCH` / `SUBARCH` | `amd64` / `generic` | Target architecture. `arm64` is wired up but **never built or deployed** — see [arm64](#arm64). |
|
||||||
| `BOOT` | `uefi` | Boot mode baked into the image. *Only UEFI was tested.* |
|
| `BOOT` | `uefi` | Boot mode baked into the image. *Only UEFI was tested.* |
|
||||||
| `DISK_SIZE` | `16G` | Build VM disk. Upstream's 4G cannot fit Debian + Proxmox |
|
| `DISK_SIZE` | `16G` | Build VM disk. Upstream's 4G cannot fit Debian + Proxmox |
|
||||||
| `BUILD_CPUS` / `BUILD_MEM` | `4` / `4096` | Build VM resources |
|
| `BUILD_CPUS` / `BUILD_MEM` | `4` / `4096` | Build VM resources |
|
||||||
@@ -751,6 +752,42 @@ serve them; package signatures are still verified.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## arm64
|
||||||
|
|
||||||
|
Proxmox VE 9.2 added **official** arm64 support — same code base, same
|
||||||
|
repositories, same release lifecycle as x86-64, with full support on NVIDIA Grace
|
||||||
|
and Vera platforms and best-effort on other UEFI Armv8-A/Armv9-A hardware. The
|
||||||
|
`pve-no-subscription` repository carries `proxmox-ve`, `pve-manager`,
|
||||||
|
`proxmox-default-kernel` and `pve-qemu-kvm` for arm64.
|
||||||
|
|
||||||
|
This repository is wired for it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo WITH_ARM64=1 ./scripts/install-deps.sh # adds qemu-system-arm, AAVMF
|
||||||
|
sudo make image ARCH=arm64
|
||||||
|
make preseed ARCH=arm64 # -> ..._arm64_generic_proxmox-ve-9
|
||||||
|
make upload ARCH=arm64
|
||||||
|
```
|
||||||
|
|
||||||
|
The firmware is selected from the **target** architecture (`AAVMF` for arm64,
|
||||||
|
`OVMF` for amd64) and padded to 64 MiB as QEMU's arm64 `virt` machine requires;
|
||||||
|
KVM is used only when the host and target architectures match.
|
||||||
|
|
||||||
|
**This has never been run.** Nothing here has been built for arm64, let alone
|
||||||
|
deployed, and it is listed under [Not verified](#not-verified) for that reason.
|
||||||
|
Two things stand between the code and a usable image:
|
||||||
|
|
||||||
|
- **Build speed.** On an x86_64 builder an arm64 build runs under TCG emulation
|
||||||
|
with no KVM. Expect it to be several times slower than the ~11 minutes an amd64
|
||||||
|
build takes; how much slower has not been measured. The I/O optimisations
|
||||||
|
(`eatmydata`, deferred initramfs) help less when the bottleneck is CPU.
|
||||||
|
- **Somewhere to deploy it.** An arm64 image needs arm64 machines behind MAAS to
|
||||||
|
be worth anything, and none were available to test against.
|
||||||
|
|
||||||
|
If you want arm64 seriously, put a native arm64 builder behind a second runner
|
||||||
|
rather than emulating. That removes the speed problem entirely and lets the same
|
||||||
|
pipeline build both architectures.
|
||||||
|
|
||||||
## Release automation
|
## Release automation
|
||||||
|
|
||||||
[`.gitea/workflows/build-image.yml`](.gitea/workflows/build-image.yml) builds the image
|
[`.gitea/workflows/build-image.yml`](.gitea/workflows/build-image.yml) builds the image
|
||||||
@@ -931,7 +968,9 @@ plaintext `PVE_ROOT_PASSWORD`, `PVE_ENABLED=false`, `PVE_FQDN`, and every
|
|||||||
**Build variants**
|
**Build variants**
|
||||||
|
|
||||||
- `pve-enterprise` and `pve-test` repositories
|
- `pve-enterprise` and `pve-test` repositories
|
||||||
- arm64
|
- **arm64** — the Makefile and scripts handle it (firmware selection, MAAS
|
||||||
|
architecture, the Debian-kernel check), but no arm64 image has been built and
|
||||||
|
none deployed. See [arm64](#arm64).
|
||||||
- BIOS boot (`BOOT=bios`)
|
- BIOS boot (`BOOT=bios`)
|
||||||
- `DEBIAN_IMAGE_CHANNEL=daily`
|
- `DEBIAN_IMAGE_CHANNEL=daily`
|
||||||
- `APT_PROXY` and `make deps-cache`. The ~700 MB figure quoted under
|
- `APT_PROXY` and `make deps-cache`. The ~700 MB figure quoted under
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ REPO_URL="${GITHUB_SERVER_URL:-}/${GITHUB_REPOSITORY:-}"
|
|||||||
RUN="${GITHUB_RUN_NUMBER:-manual}"
|
RUN="${GITHUB_RUN_NUMBER:-manual}"
|
||||||
SHA="${GITHUB_SHA:-}"
|
SHA="${GITHUB_SHA:-}"
|
||||||
IMAGE=$(basename "$(ls "$DIST"/maas-image-*.tar.gz)")
|
IMAGE=$(basename "$(ls "$DIST"/maas-image-*.tar.gz)")
|
||||||
|
MAAS_ARCH=$(make -s print-var VAR=MAAS_ARCH)
|
||||||
|
PVE_MAJOR=$(make -s print-var VAR=PVE_VERSION)
|
||||||
|
IMAGE_NAME=$(make -s print-var VAR=IMAGE_NAME)
|
||||||
|
|
||||||
BODY=$(cat <<BODYEOF
|
BODY=$(cat <<BODYEOF
|
||||||
Unofficial build of a MAAS-deployable Proxmox VE image.
|
Unofficial build of a MAAS-deployable Proxmox VE image.
|
||||||
@@ -32,8 +35,8 @@ Unofficial build of a MAAS-deployable Proxmox VE image.
|
|||||||
Upload to MAAS:
|
Upload to MAAS:
|
||||||
|
|
||||||
\`\`\`bash
|
\`\`\`bash
|
||||||
maas \$PROFILE boot-resources create name='custom/proxmox-ve-9' \\
|
maas \$PROFILE boot-resources create name='custom/${IMAGE_NAME}' \\
|
||||||
title='Proxmox VE 9' architecture='amd64/generic' \\
|
title='Proxmox VE ${PVE_MAJOR}' architecture='${MAAS_ARCH}' \\
|
||||||
filetype='tgz' content@=${IMAGE}
|
filetype='tgz' content@=${IMAGE}
|
||||||
\`\`\`
|
\`\`\`
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,14 @@ apt-get install -y --no-install-recommends \
|
|||||||
qemu-system-x86 qemu-utils ovmf cloud-image-utils \
|
qemu-system-x86 qemu-utils ovmf cloud-image-utils \
|
||||||
libnbd-bin nbdkit fuse2fs cpu-checker
|
libnbd-bin nbdkit fuse2fs cpu-checker
|
||||||
|
|
||||||
|
# arm64 hedefi icin ek paketler. Varsayilan olarak kurulmaz: x86_64 host'ta
|
||||||
|
# arm64 derlemek TCG emulasyonu demektir (KVM yok) ve cok yavastir. Bu yol
|
||||||
|
# hic denenmedi - README'deki "Verified status" bolumune bakin.
|
||||||
|
if [ "${WITH_ARM64:-0}" = "1" ]; then
|
||||||
|
echo "==> arm64 hedefi icin ek paketler (WITH_ARM64=1)"
|
||||||
|
apt-get install -y --no-install-recommends qemu-system-arm qemu-efi-aarch64
|
||||||
|
fi
|
||||||
|
|
||||||
echo "==> HashiCorp APT deposu ekleniyor (packer)"
|
echo "==> HashiCorp APT deposu ekleniyor (packer)"
|
||||||
install -d -m 0755 /etc/apt/keyrings
|
install -d -m 0755 /etc/apt/keyrings
|
||||||
curl -fsSL https://apt.releases.hashicorp.com/gpg \
|
curl -fsSL https://apt.releases.hashicorp.com/gpg \
|
||||||
|
|||||||
@@ -55,7 +55,11 @@ check "iSCSI initiator adi yok (dugumde uretilir)" '! present "etc/iscsi/initia
|
|||||||
check "SSH host anahtarlari yok" '! grep -qE "^\./etc/ssh/ssh_host_.*_key$" "$TMP/list"'
|
check "SSH host anahtarlari yok" '! grep -qE "^\./etc/ssh/ssh_host_.*_key$" "$TMP/list"'
|
||||||
check "networking.service etkin DEGIL" '! present "etc/systemd/system/multi-user.target.wants/networking.service"'
|
check "networking.service etkin DEGIL" '! present "etc/systemd/system/multi-user.target.wants/networking.service"'
|
||||||
check "interfaces.new yok (pvenetcommit ezmesin)" '! present "etc/network/interfaces.new"'
|
check "interfaces.new yok (pvenetcommit ezmesin)" '! present "etc/network/interfaces.new"'
|
||||||
check "Debian cekirdegi yok" '! grep -qE "^\./boot/vmlinuz-.*[^e]-(cloud-)?amd64$" "$TMP/list"'
|
# Mimariden bagimsiz: /boot altinda -pve ile bitmeyen hicbir cekirdek olmamali.
|
||||||
|
# Debian'inki amd64'te *-amd64, arm64'te *-arm64 diye adlandirilir; Proxmox'unki
|
||||||
|
# her zaman -pve ile biter. Hic cekirdek yoksa da gecer - PVE cekirdeginin
|
||||||
|
# varligini asagidaki ayri kontrol dogruluyor.
|
||||||
|
check "Debian cekirdegi yok" '! grep -E "^\./boot/vmlinuz-" "$TMP/list" | grep -qv -- "-pve$"'
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "==> Proxmox cekirdegi"
|
echo "==> Proxmox cekirdegi"
|
||||||
|
|||||||
Reference in New Issue
Block a user