Skip to content

Commit

Permalink
Add aarch64 support to Rocky9 template.
Browse files Browse the repository at this point in the history
  • Loading branch information
alanbach committed Dec 20, 2024
1 parent b8ed17a commit 0dd5525
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 67 deletions.
39 changes: 36 additions & 3 deletions rocky9/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: 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
66 changes: 56 additions & 10 deletions rocky9/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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 .
```

Expand All @@ -50,19 +64,51 @@ 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.

## 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:
Expand Down
120 changes: 66 additions & 54 deletions rocky9/rocky9.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,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")}"
Expand All @@ -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 = ["<up><tab> ", "inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/rocky.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}}/rocky9.ks <f10>"]
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
}
Expand Down

0 comments on commit 0dd5525

Please sign in to comment.