Skip to content

Add support for AARCH64 builds via QEMU #457

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ Linux and Windows hosts, but feedback on other platforms is always welcome.

Due to difficulties with Packer packaging, this VM is frequently built with the
latest version of Packer available directly from Hashicorp. Check the
`main.pkr.hcl` file for the current minimum version required.
`main.pkr.hcl` file for the current minimum version required. To install the
required plugins, run `packer init .` within the `cs-vm-build/packer` directory.

Once the prerequisites are installed, change into the `cs-vm-build/packer`
directory and execute `packer build -only "*.mint" .`. This will take a
Expand Down
111 changes: 111 additions & 0 deletions packer/config.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ConfigurationVersion</key>
<integer>2</integer>
<key>Debug</key>
<dict>
<key>DebugLog</key>
<false/>
</dict>
<key>Display</key>
<dict>
<key>ConsoleFont</key>
<string>Menlo</string>
<key>ConsoleFontSize</key>
<integer>12</integer>
<key>ConsoleTheme</key>
<string>Default</string>
<key>DisplayCard</key>
<string>virtio-ramfb-gl</string>
<key>DisplayDownscaler</key>
<string>linear</string>
<key>DisplayFitScreen</key>
<true/>
<key>DisplayRetina</key>
<false/>
<key>DisplayUpscaler</key>
<string>linear</string>
</dict>
<key>Drives</key>
<array>
<dict>
<key>DriveName</key>
<string>drive0</string>
<key>ImagePath</key>
<string>image.qcow2</string>
<key>ImageType</key>
<string>disk</string>
<key>InterfaceType</key>
<string>virtio</string>
</dict>
</array>
<key>Info</key>
<dict>
<key>Icon</key>
<string>ubuntu</string>
<key>IconCustom</key>
<false/>
<key>Notes</key>
<string></string>
</dict>
<key>Input</key>
<dict>
<key>InputLegacy</key>
<false/>
</dict>
<key>Networking</key>
<dict>
<key>NetworkCard</key>
<string>virtio-net-pci</string>
<key>NetworkMode</key>
<string>emulated</string>
</dict>
<key>Printing</key>
<dict/>
<key>Sharing</key>
<dict>
<key>ClipboardSharing</key>
<true/>
<key>DirectoryName</key>
<string></string>
<key>DirectorySharing</key>
<true/>
<key>Usb3Support</key>
<true/>
<key>UsbRedirectMax</key>
<integer>3</integer>
</dict>
<key>Sound</key>
<dict>
<key>SoundCard</key>
<string>intel-hda</string>
<key>SoundEnabled</key>
<true/>
</dict>
<key>System</key>
<dict>
<key>Architecture</key>
<string>aarch64</string>
<key>BootDevice</key>
<string></string>
<key>CPU</key>
<string>cortex-a72</string>
<key>CPUCount</key>
<integer>0</integer>
<key>ForceMulticore</key>
<false/>
<key>JITCacheSize</key>
<integer>0</integer>
<key>MachineProperties</key>
<string>highmem=off</string>
<key>Memory</key>
<integer>4096</integer>
<key>SystemUUID</key>
<string>1A9B879C-CDA8-4728-AA9A-4717B646E9AC</string>
<key>Target</key>
<string>virt</string>
</dict>
</dict>
</plist>
1 change: 1 addition & 0 deletions packer/http/oem-preseed.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ ubiquity ubiquity/success_command string svcfile="/target/etc/systemd/system/ssh
echo "ExecStart=/usr/bin/apt-get -y install openssh-server" >> "$svcfile"; \
echo "ExecStartPost=/bin/systemctl disable ssh-install.service" >> "$svcfile"; \
echo "ExecStartPost=/bin/rm /etc/systemd/system/ssh-install.service" >> "$svcfile"; \
echo "TimeoutSec=300" >> "$svcfile"; \
echo "[Install]" >> "$svcfile"; \
echo "WantedBy=multi-user.target" >> "$svcfile"; \
in-target systemctl enable ssh-install.service
Expand Down
70 changes: 69 additions & 1 deletion packer/main.pkr.hcl
Original file line number Diff line number Diff line change
@@ -1,13 +1,73 @@
packer {
required_version = ">= 1.7.0"
required_version = ">= 1.9.0"
required_plugins {
qemu = {
source = "github.com/hashicorp/qemu"
version = "~> 1"
}
virtualbox = {
version = "~> 1"
source = "github.com/hashicorp/virtualbox"
}
}
}

source "qemu" "kvm" {
cpus = 2
memory = 4096
disk_size = 20480
machine_type = "virt"
accelerator = var.qemu_accelerator

format = "qcow2"
headless = "${var.headless}"
http_directory = "http"
qemu_binary = "qemu-system-aarch64"

efi_firmware_code = "${var.qemu_firmware_directory}/AAVMF_CODE.fd"
efi_firmware_vars = "${var.qemu_firmware_directory}/AAVMF_VARS.fd"
qemuargs = [
["-boot", "strict=off"],
["-cpu", "host"],
["-display", var.headless ? "none" : "gtk"],
["-device", "virtio-rng-pci"],
["-device", "virtio-gpu"],
["-device", "nec-usb-xhci,id=xhci"],
["-device", "usb-kbd,bus=xhci.0"],
["-device", "usb-tablet,bus=xhci.0"]
]
qemu_img_args {
create = ["-o", "preallocation=falloc"]
convert = ["-o", "compression_type=zstd"]
}
disk_cache = "unsafe"
disk_compression = "true"
disk_detect_zeroes = "unmap"
disk_discard = "unmap"
disk_interface = "virtio"
net_device = "virtio-net"
ssh_username = var.ssh_user
ssh_password = var.ssh_pass
ssh_timeout = "100m"

boot_wait = var.aarch64_boot_wait
boot_command = [
# Enter the command line
"c<wait><wait>",
# Configure the kernel
"linux /casper/vmlinuz",
" auto url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/oem-preseed.cfg",
" automatic-ubiquity only-ubiquity",
" debug-ubiquity oem-config/enable=true",
" keymap=us fsck.mode=skip",
" noprompt splash --<enter><wait><wait>",
# Configure initrd & boot
"initrd /casper/initrd ",
"<enter>boot<enter>"
]
shutdown_command = "echo -e \"${var.ssh_pass}\\n\" | sudo -S poweroff"
}

source "virtualbox-iso" "base-build" {
cpus = 2
memory = 4096
Expand Down Expand Up @@ -113,6 +173,14 @@ build {
]
}

source "source.qemu.kvm" {
name = "ubuntu-aarch64"
vm_name = "image.qcow2"
iso_url = "${local.ubuntu_aarch64_info.mirror_url}/${local.ubuntu_aarch64_info.iso_file}"
iso_checksum = "file:${local.ubuntu_aarch64_info.mirror_url}/SHA256SUMS"
output_directory = "${local.artifact_dir_prefix}ubuntu-aarch64"
}

provisioner "shell" {
execute_command = "echo 'oem' | sudo -S sh -c '{{ .Vars }} {{ .Path }}'"
environment_vars = [
Expand Down
34 changes: 34 additions & 0 deletions packer/variables.pkr.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,36 @@ variable "vm_name" {
default = "JMU CS"
}

variable "aarch64_boot_wait" {
type = string
default = "25s"
description = "The length of time to wait after boot before entering commands"

validation {
condition = can(regex("\\d+s", var.aarch64_boot_wait))
error_message = "The value should be a number of seconds followed by 's'."
}
}

variable "qemu_accelerator" {
type = string
default = "kvm"
description = <<EOF
The QEMU accelerator to use; keep this as 'kvm' unless building on macOS, in
which case it's probably best to use 'hvf'.
EOF
}

variable "qemu_firmware_directory" {
type = string
default = "/usr/share/AAVMF/"
description = <<EOF
The directory where the QEMU EFI code and variables are stored. On Fedora and
similar distributions, this is likely /usr/share/edk2/aarch64. On Debian
derivates, this is likely /usr/share/qemu-efi-aarch64.
EOF
}

locals {
build_id = formatdate("YYYY-MM-DD", timestamp())
ubuntu_info = {
Expand All @@ -81,5 +111,9 @@ locals {
mirror_url = "${var.mirror.base}/${var.mirror.mint_path}/${var.mint_version.build_type == "beta" ? "testing" : "stable/${var.mint_version.version}"}"
iso_file = "linuxmint-${var.mint_version.version}-cinnamon-64bit${var.mint_version.build_type != null ? "-${var.mint_version.build_type}" : ""}.iso"
}
ubuntu_aarch64_info = {
mirror_url = "http://cdimage.ubuntu.com/${var.ubuntu_version.version}/daily-live/current"
iso_file = "${var.ubuntu_version.version}-desktop-arm64.iso"
}
artifact_dir_prefix = "${path.cwd}/artifacts_"
}
6 changes: 4 additions & 2 deletions roles/oem/tasks/ubuntu_only.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
errors=0
changed=""
while read snapname revision; do
snap remove "$snapname" --revision="$revision"
if [[ -n "$snapname" ]] && [[ -n "$revision" ]]; then
snap remove "$snapname" --revision="$revision"
changed="Snap removed"
fi
errors=$((errors + $?))
changed="Snap removed"
done <<< "$(snap list --all | awk '/disabled/{print $1, $3}')"
echo $changed
exit $errors
Expand Down