Skip to content

Commit

Permalink
Add aarch64 support to Rocky Linux 8 (#282)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
alanbach authored Dec 9, 2024
1 parent ff3aee4 commit 158d3a8
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 54 deletions.
39 changes: 36 additions & 3 deletions rocky8/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
43 changes: 40 additions & 3 deletions rocky8/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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.
Expand All @@ -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:
Expand Down
14 changes: 7 additions & 7 deletions rocky8/http/rocky8.ks.pkrtpl.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -87,7 +86,7 @@ chmod 440 /etc/sudoers.d/rocky

%end

%packages
%packages --ignoremissing
@Core
bash-completion
cloud-init
Expand All @@ -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
Expand Down
105 changes: 64 additions & 41 deletions rocky8/rocky8.pkr.hcl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
packer {
required_version = ">= 1.7.0"
required_version = ">= 1.11.0"
required_plugins {
qemu = {
version = "~> 1.0"
Expand All @@ -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")}"
Expand All @@ -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 = ["<up><tab> ", "inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/rocky8.ks ", "console=ttyS0 inst.cmdline", "<enter>"]
boot_wait = "3s"
boot_command = ["<up><wait>", "e", "<down><down><down><left>", " console=ttyS0 inst.cmdline inst.text inst.ks=http://{{.HTTPIP}}:{{.HTTPPort}}/rocky8.ks <f10>"]
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",
Expand Down

0 comments on commit 158d3a8

Please sign in to comment.