From 158d3a8e174a9bc9969a2f9403319c36a293932b Mon Sep 17 00:00:00 2001 From: Alan Baghumian Date: Mon, 9 Dec 2024 19:29:40 +0100 Subject: [PATCH] Add aarch64 support to Rocky Linux 8 (#282) This PR is an initial attempt to add ```aarch64``` support to the whole entire RHEL family. This currently also need a change in curtin [LP# 2090874](https://bugs.launchpad.net/curtin/+bug/2090874) which I am preparing a PR for as well. --- rocky8/Makefile | 39 +++++++++++- rocky8/README.md | 43 ++++++++++++- rocky8/http/rocky8.ks.pkrtpl.hcl | 14 ++--- rocky8/rocky8.pkr.hcl | 105 +++++++++++++++++++------------ 4 files changed, 147 insertions(+), 54 deletions(-) diff --git a/rocky8/Makefile b/rocky8/Makefile index 40bc066..aba2367 100644 --- a/rocky8/Makefile +++ b/rocky8/Makefile @@ -5,17 +5,50 @@ include ../scripts/check.mk PACKER ?= packer PACKER_LOG ?= 0 TIMEOUT ?= 1h +ARCH ?= x86_64 + +ifeq ($(wildcard /usr/share/OVMF/OVMF_CODE.fd),) + OVMF_SFX ?= _4M +else + OVMF_SFX ?= +endif export PACKER_LOG +# Fallback +ifeq ($(strip $(ARCH)),amd64) + ARCH = x86_64 +endif + .PHONY: all clean all: rocky8.tar.gz $(eval $(call check_packages_deps)) -rocky8.tar.gz: check-deps clean - ${PACKER} init rocky8.pkr.hcl && ${PACKER} build -var timeout=${TIMEOUT} rocky8.pkr.hcl +lint: + packer validate . + packer fmt -check -diff . + +format: + packer fmt . + +OVMF_VARS.fd: /usr/share/OVMF/OVMF_VARS${OVMF_SFX}.fd + cp -v $< ${ARCH}_VARS.fd + +SIZE_VARS.fd: +ifeq ($(strip $(ARCH)),aarch64) + truncate -s 64m ${ARCH}_VARS.fd +else + truncate -s 2m ${ARCH}_VARS.fd +endif + +rocky8.tar.gz: check-deps clean OVMF_VARS.fd SIZE_VARS.fd + ${PACKER} init rocky8.pkr.hcl && ${PACKER} build \ + -var architecture=${ARCH} \ + -var timeout=${TIMEOUT} \ + -var ovmf_suffix=${OVMF_SFX} \ + rocky8.pkr.hcl clean: - ${RM} -rf output-rocky8 rocky8.tar.gz + ${RM} -rf *.fd output-rocky8 rocky8.tar.gz diff --git a/rocky8/README.md b/rocky8/README.md index 180669d..58fffa9 100644 --- a/rocky8/README.md +++ b/rocky8/README.md @@ -2,13 +2,18 @@ ## Introduction -The Packer template in this directory creates a Rocky 8 AMD64 image for use with MAAS. +The Packer template in this directory creates a Rocky 8 AMD64/ARM64 image for use with MAAS. ## Prerequisites to create the image -* A machine running Ubuntu 18.04+ with the ability to run KVM virtual machines. +* A machine running Ubuntu 22.04+ with the ability to run KVM virtual machines. * qemu-utils, libnbd-bin, nbdkit and fuse2fs -* [Packer.](https://www.packer.io/intro/getting-started/install.html), v1.7.0 or newer +* qemu-system +* qemu-system-modules-spice (If building on Ubuntu 24.04 LTS "Noble") +* ovmf +* cloud-image-utils +* parted +* [Packer.](https://www.packer.io/intro/getting-started/install.html), v1.11.0 or newer ## Requirements to deploy the image @@ -59,6 +64,10 @@ Note: rocky8.pkr.hcl runs Packer in headless mode, with the serial port output f ### Makefile Parameters +#### ARCH + +Defaults to x86_64 to build AMD64 compatible images. In order to build ARM64 images, use ARCH=aarch64 + #### TIMEOUT The timeout to apply when building the image. The default value is set to 1h. @@ -72,6 +81,34 @@ maas $PROFILE boot-resources create name='custom/rocky8' \ content@=rocky8.tar.gz ``` +For ARM64, use: + +```shell +maas $PROFILE boot-resources create name='custom/rocky8' \ + title='Rocky 8 Custom' architecture='arm64/generic' \ + base_image='rhel/8' filetype='tgz' \ + content@=rocky8.tar.gz +``` + +Please note that, currently due to lack of support in curtin, deploying ARM64 images needs a preseed file. This is due to [LP# 2090874](https://bugs.launchpad.net/curtin/+bug/2090874) and currently is in the process of getting fixed. + +``` +#cloud-config +debconf_selections: + maas: | + {{for line in str(curtin_preseed).splitlines()}} + {{line}} + {{endfor}} + +extract_commands: + grub_install: curtin in-target -- cp -v /boot/efi/EFI/rocky/shimaa64.efi /boot/efi/EFI/rocky/shimx64.efi + +late_commands: + maas: [wget, '--no-proxy', '{{node_disable_pxe_url}}', '--post-data', '{{node_disable_pxe_data}}', '-O', '/dev/null'] +``` + +This file needs to be saved on Region Controllers under /var/snap/maas/current/preseeds/curtin_userdata_custom_arm64_generic_rocky8 or /etc/maas/preseeds/curtin_userdata_custom_arm64_generic_rocky8. The last portion of this file must match the image name uploaded in MAAS. + ## Default username MAAS uses cloud-init to create ```cloud-user``` account using the ssh keys configured for the MAAS admin user (e.g. imported from Launchpad). Log in to the machine: diff --git a/rocky8/http/rocky8.ks.pkrtpl.hcl b/rocky8/http/rocky8.ks.pkrtpl.hcl index efea180..e1daf8d 100644 --- a/rocky8/http/rocky8.ks.pkrtpl.hcl +++ b/rocky8/http/rocky8.ks.pkrtpl.hcl @@ -28,9 +28,8 @@ skipx # Initial disk setup # Use the first paravirtualized disk ignoredisk --only-use=vda -# Place the bootloader on the Master Boot Record -bootloader --location=mbr --driveorder="vda" --timeout=1 -# Wipe invalid partition tables + +bootloader --disabled zerombr # Erase all partitions and assign default labels clearpart --all --initlabel @@ -87,7 +86,7 @@ chmod 440 /etc/sudoers.d/rocky %end -%packages +%packages --ignoremissing @Core bash-completion cloud-init @@ -96,9 +95,10 @@ rsync tar patch yum-utils -grub2-efi-x64 -shim-x64 -grub2-efi-x64-modules +grub2-pc +grub2-efi-* +shim-* +grub2-efi-*-modules efibootmgr dosfstools lvm2 diff --git a/rocky8/rocky8.pkr.hcl b/rocky8/rocky8.pkr.hcl index ebb7cd2..54fc88b 100644 --- a/rocky8/rocky8.pkr.hcl +++ b/rocky8/rocky8.pkr.hcl @@ -1,5 +1,5 @@ packer { - required_version = ">= 1.7.0" + required_version = ">= 1.11.0" required_plugins { qemu = { version = "~> 1.0" @@ -14,37 +14,6 @@ variable "filename" { description = "The filename of the tarball to produce" } -variable "rocky_iso_url" { - type = string - default = "http://download.rockylinux.org/pub/rocky/8/isos/x86_64/Rocky-x86_64-boot.iso" -} - -variable "rocky_sha256sum_url" { - type = string - default = "http://download.rockylinux.org/pub/rocky/8/isos/x86_64/CHECKSUM" -} - -# use can use "--url" to specify the exact url for os repo -# for ex. "--url='https://dl.rockylinux.org/pub/rocky/8/BaseOS/x86_64/os'" -variable "ks_os_repos" { - type = string - default = "--mirrorlist='http://mirrors.rockylinux.org/mirrorlist?arch=x86_64&repo=BaseOS-8'" -} - -# Use --baseurl to specify the exact url for appstream repo -# for ex. "--baseurl='https://dl.rockylinux.org/pub/rocky/8/AppStream/x86_64/os'" -variable "ks_appstream_repos" { - type = string - default = "--mirrorlist='https://mirrors.rockylinux.org/mirrorlist?release=8&arch=x86_64&repo=AppStream-8'" -} - -# Use --baseurl to specify the exact url for extras repo -# for ex. "--baseurl='https://dl.rockylinux.org/pub/rocky/8/extras/x86_64/os'" -variable "ks_extras_repos" { - type = string - default = "--mirrorlist='https://mirrors.rockylinux.org/mirrorlist?arch=x86_64&repo=extras-8'" -} - variable ks_proxy { type = string default = "${env("KS_PROXY")}" @@ -61,23 +30,77 @@ variable "timeout" { description = "Timeout for building the image" } +variable "architecture" { + type = string + default = "amd64" + description = "The architecture to build the image for (amd64 or arm64)" +} + +variable "ovmf_suffix" { + type = string + default = "" + description = "Suffix for OVMF CODE and VARS files. Newer systems such as Noble use _4M." +} + locals { + qemu_arch = { + "x86_64" = "x86_64" + "aarch64" = "aarch64" + } + uefi_imp = { + "x86_64" = "OVMF" + "aarch64" = "AAVMF" + } + uefi_sfx = { + "x86_64" = "${var.ovmf_suffix}" + "aarch64" = "" + } + qemu_machine = { + "x86_64" = "accel=kvm" + "aarch64" = "virt" + } + qemu_cpu = { + "x86_64" = "host" + "aarch64" = "max" + } + ks_proxy = var.ks_proxy != "" ? "--proxy=${var.ks_proxy}" : "" - ks_os_repos = var.ks_mirror != "" ? "--url=${var.ks_mirror}/BaseOS/x86_64/os" : var.ks_os_repos - ks_appstream_repos = var.ks_mirror != "" ? "--baseurl=${var.ks_mirror}/AppStream/x86_64/os" : var.ks_appstream_repos - ks_extras_repos = var.ks_mirror != "" ? "--baseurl=${var.ks_mirror}/extras/x86_64/os" : var.ks_extras_repos + ks_os_repos = var.ks_mirror != "" ? "--url=${var.ks_mirror}/BaseOS/${var.architecture}/os" : "--mirrorlist='http://mirrors.rockylinux.org/mirrorlist?arch=${var.architecture}&repo=BaseOS-8'" + ks_appstream_repos = var.ks_mirror != "" ? "--baseurl=${var.ks_mirror}/AppStream/${var.architecture}/os" : "--mirrorlist='https://mirrors.rockylinux.org/mirrorlist?release=8&arch=${var.architecture}&repo=AppStream-8'" + ks_extras_repos = var.ks_mirror != "" ? "--baseurl=${var.ks_mirror}/extras/${var.architecture}/os" : "--mirrorlist='https://mirrors.rockylinux.org/mirrorlist?arch=${var.architecture}&repo=extras-8'" } source "qemu" "rocky8" { - boot_command = [" ", "inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/rocky8.ks ", "console=ttyS0 inst.cmdline", ""] - boot_wait = "3s" + boot_command = ["", "e", "", " console=ttyS0 inst.cmdline inst.text inst.ks=http://{{.HTTPIP}}:{{.HTTPPort}}/rocky8.ks "] + boot_wait = "5s" communicator = "none" - disk_size = "4G" + disk_size = "45G" + format = "qcow2" headless = true - iso_checksum = "file:${var.rocky_sha256sum_url}" - iso_url = var.rocky_iso_url + iso_checksum = "file:http://download.rockylinux.org/pub/rocky/8/isos/${var.architecture}/CHECKSUM" + iso_url = "http://download.rockylinux.org/pub/rocky/8/isos/${var.architecture}/Rocky-${var.architecture}-boot.iso" + iso_target_path = "packer_cache/Rocky-${var.architecture}-boot.iso" memory = 2048 - qemuargs = [["-serial", "stdio"]] + cores = 4 + qemu_binary = "qemu-system-${lookup(local.qemu_arch, var.architecture, "")}" + qemuargs = [ + ["-serial", "stdio"], + ["-boot", "strict=off"], + ["-device", "qemu-xhci"], + ["-device", "usb-kbd"], + ["-device", "virtio-net-pci,netdev=net0"], + ["-netdev", "user,id=net0"], + ["-device", "virtio-blk-pci,drive=drive0,bootindex=0"], + ["-device", "virtio-blk-pci,drive=cdrom0,bootindex=1"], + ["-machine", "${lookup(local.qemu_machine, var.architecture, "")}"], + ["-cpu", "${lookup(local.qemu_cpu, var.architecture, "")}"], + ["-device", "virtio-gpu-pci"], + ["-global", "driver=cfi.pflash01,property=secure,value=off"], + ["-drive", "if=pflash,format=raw,unit=0,id=ovmf_code,readonly=on,file=/usr/share/${lookup(local.uefi_imp, var.architecture, "")}/${lookup(local.uefi_imp, var.architecture, "")}_CODE${lookup(local.uefi_sfx, var.architecture, "")}.fd"], + ["-drive", "if=pflash,format=raw,unit=1,id=ovmf_vars,file=${var.architecture}_VARS.fd"], + ["-drive", "file=output-rocky8/packer-rocky8,if=none,id=drive0,cache=writeback,discard=ignore,format=qcow2"], + ["-drive", "file=packer_cache/Rocky-${var.architecture}-boot.iso,if=none,id=cdrom0,media=cdrom"] + ] shutdown_timeout = var.timeout http_content = { "/rocky8.ks" = templatefile("${path.root}/http/rocky8.ks.pkrtpl.hcl",