From 0dd5525ab6d671d05196a9897def63d014e48d3c Mon Sep 17 00:00:00 2001 From: Alan Baghumian Date: Fri, 20 Dec 2024 12:41:56 -0800 Subject: [PATCH] Add aarch64 support to Rocky9 template. --- rocky9/Makefile | 39 ++++++++++++-- rocky9/README.md | 66 +++++++++++++++++++---- rocky9/rocky9.pkr.hcl | 120 +++++++++++++++++++++++------------------- 3 files changed, 158 insertions(+), 67 deletions(-) diff --git a/rocky9/Makefile b/rocky9/Makefile index dbc5452..65640e4 100644 --- a/rocky9/Makefile +++ b/rocky9/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: rocky9.tar.gz $(eval $(call check_packages_deps)) -rocky9.tar.gz: check-deps clean - ${PACKER} init rocky9.pkr.hcl && ${PACKER} build -var timeout=${TIMEOUT} rocky9.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 + +rocky9.tar.gz: check-deps clean OVMF_VARS.fd SIZE_VARS.fd + ${PACKER} init rocky9.pkr.hcl && ${PACKER} build \ + -var architecture=${ARCH} \ + -var timeout=${TIMEOUT} \ + -var ovmf_suffix=${OVMF_SFX} \ + rocky9.pkr.hcl clean: - ${RM} -rf output-rocky9 rocky9.tar.gz + ${RM} -rf *.fd output-rocky9 rocky9.tar.gz diff --git a/rocky9/README.md b/rocky9/README.md index 29761d5..7343377 100644 --- a/rocky9/README.md +++ b/rocky9/README.md @@ -2,33 +2,46 @@ ## Introduction -The Packer template in this directory creates a Rocky 9 AMD64 image for use with MAAS. +The Packer template in this directory creates a Rocky 9 AMD64/ARM64 image for use with MAAS. ## Prerequisites to create the image -* A machine running Ubuntu 22.04+ with the ability to run KVM virtual machines and with a CPU that supports x86-64-v2 extensions +* 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) +* 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 * [MAAS](https://maas.io) 3.3 or later, as that version introduces support for Rocky -* [Curtin](https://launchpad.net/curtin) >22.1 +* [Curtin](https://launchpad.net/curtin) 22.1. If you have a MAAS with an earlier Curtin version, you can [patch](https://code.launchpad.net/~xnox/curtin/+git/curtin/+merge/415604) distro.py to deploy Rocky. ## Customizing the image -You can customize the deployment image by modifying http/rocky.ks. See the [RHEL kickstart documentation](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/performing_an_advanced_rhel_installation/kickstart-commands-and-options-reference_installing-rhel-as-an-experienced-user#part-or-partition_kickstart-commands-for-handling-storage) for more information. +You can customize the deployment image by modifying http/rocky.ks. See the [RHEL kickstart documentation](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/performing_an_advanced_rhel_installation/kickstart-commands-and-options-reference_installing-rhel-as-an-experienced-user#part-or-partition_kickstart-commands-for-handling-storage) for more information. ## Building the image using a proxy -The Packer template downloads the Rocky ISO image from the Internet. You can tell Packer to use a proxy by setting the HTTP_PROXY environment variable to point to your proxy server. You can also redefine rocky_iso_url to a local file. If you want to skip the base image integrity check, set iso_checksum_type to none and remove iso_checksum. +The Packer template downloads the Rocky ISO image from the Internet. You can tell Packer to use a proxy by setting the HTTP_PROXY environment variable to point to your proxy server. You can also redefine rocky_iso_url to a local file. If you want to skip the base image integrity check, set iso_checksum_type to none and remove iso_checksum. To use a proxy during the installation define the `KS_PROXY` variable in the environment, as bellow: ```shell -export KS_PROXY=$HTTP_PROXY +export KS_PROXY="\"${HTTP_PROXY}\"" ``` +# Building the image using a kickstart mirror + +To tell Packer to use a specific mirror set the `KS_MIRROR` environment variable +poiniting to the mirror URL. + +```shell +export KS_MIRROR="https://dl.rockylinux.org/pub/rocky/9" +``` ## Building an image @@ -41,6 +54,7 @@ make You can also manually run packer. Set your current working directory to packer-maas/rocky9, where this file resides, and generate an image with: ```shell +packer init PACKER_LOG=1 packer build . ``` @@ -50,6 +64,10 @@ Note: rocky9.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. @@ -57,12 +75,40 @@ The timeout to apply when building the image. The default value is set to 1h. ## Uploading an image to MAAS ```shell -maas $PROFILE boot-resources create \ - name='custom/rocky9' title='Rocky 9 Custom' \ - architecture='amd64/generic' base_image='rhel/9' filetype='tgz' \ +maas $PROFILE boot-resources create name='custom/rocky9' \ + title='Rocky 9 Custom' architecture='amd64/generic' \ + base_image='rhel/9' filetype='tgz' \ + content@=rocky9.tar.gz +``` + +For ARM64, use: + +```shell +maas $PROFILE boot-resources create name='custom/rocky9' \ + title='Rocky 9 Custom' architecture='arm64/generic' \ + base_image='rhel/9' filetype='tgz' \ content@=rocky9.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_rocky9 or /etc/maas/preseeds/curtin_userdata_custom_arm64_generic_rocky9. 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/rocky9/rocky9.pkr.hcl b/rocky9/rocky9.pkr.hcl index c625b21..05b6934 100644 --- a/rocky9/rocky9.pkr.hcl +++ b/rocky9/rocky9.pkr.hcl @@ -1,5 +1,5 @@ packer { - required_version = ">= 1.7.0" + required_version = ">= 1.11.0" required_plugins { qemu = { version = "~> 1.0" @@ -14,46 +14,6 @@ variable "filename" { description = "The filename of the tarball to produce" } -variable "headless" { - type = bool - default = true - description = "Whether VNC viewer should not be launched." -} - -variable "rocky_iso_url" { - type = string - default = "https://download.rockylinux.org/pub/rocky/9/isos/x86_64/Rocky-x86_64-boot.iso" -} - -variable "rocky_sha256sum_url" { - type = string - default = "https://download.rockylinux.org/pub/rocky/9/isos/x86_64/CHECKSUM" -} - -# use can use "--url" to specify the exact url for os repo -variable "ks_os_repos" { - type = string - default = "--url='https://download.rockylinux.org/pub/rocky/9/BaseOS/x86_64/os/'" -} - -# Use --baseurl to specify the exact url for base_os repo -variable "ks_base_os_repos" { - type = string - default = "--mirrorlist='http://mirrors.rockylinux.org/mirrorlist?arch=x86_64&repo=BaseOS-9'" -} - -# Use --baseurl to specify the exact url for appstream repo -variable "ks_appstream_repos" { - type = string - default = "--mirrorlist='https://mirrors.rockylinux.org/mirrorlist?arch=x86_64&release=9&repo=AppStream-9'" -} - -# Use --baseurl to specify the exact url for extras repo -variable "ks_extras_repos" { - type = string - default = "--mirrorlist='https://mirrors.rockylinux.org/mirrorlist?arch=x86_64&repo=extras-9'" -} - variable ks_proxy { type = string default = "${env("KS_PROXY")}" @@ -70,31 +30,83 @@ 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_base_os_repos = var.ks_mirror != "" ? "--url=${var.ks_mirror}/BaseOS/x86_64/os" : var.ks_base_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-9'" + ks_appstream_repos = var.ks_mirror != "" ? "--baseurl=${var.ks_mirror}/AppStream/${var.architecture}/os" : "--mirrorlist='https://mirrors.rockylinux.org/mirrorlist?release=9&arch=${var.architecture}&repo=AppStream-9'" + 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-9'" } source "qemu" "rocky9" { - boot_command = [" ", "inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/rocky.ks ", "console=ttyS0 inst.cmdline", ""] - boot_wait = "3s" + boot_command = ["", "e", "", " console=ttyS0 inst.cmdline inst.text inst.ks=http://{{.HTTPIP}}:{{.HTTPPort}}/rocky9.ks "] + boot_wait = "5s" communicator = "none" - disk_size = "4G" - headless = var.headless - iso_checksum = "file:${var.rocky_sha256sum_url}" - iso_url = "${var.rocky_iso_url}" + disk_size = "45G" + format = "qcow2" + headless = true + iso_checksum = "file:http://download.rockylinux.org/pub/rocky/9/isos/${var.architecture}/CHECKSUM" + iso_url = "http://download.rockylinux.org/pub/rocky/9/isos/${var.architecture}/Rocky-${var.architecture}-boot.iso" + iso_target_path = "packer_cache/Rocky-${var.architecture}-boot.iso" memory = 2048 - qemuargs = [["-serial", "stdio"], ["-cpu", "host"]] + 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-rocky9/packer-rocky9,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 = { - "/rocky.ks" = templatefile("${path.root}/http/rocky.ks.pkrtpl.hcl", + "/rocky9.ks" = templatefile("${path.root}/http/rocky9.ks.pkrtpl.hcl", { KS_PROXY = local.ks_proxy, KS_OS_REPOS = local.ks_os_repos, - KS_BASE_OS_REPOS = local.ks_base_os_repos, KS_APPSTREAM_REPOS = local.ks_appstream_repos, KS_EXTRAS_REPOS = local.ks_extras_repos }