Skip to content

gencloud: build aarch64 under QEMU TCG where there is no arm64 runner - #367

Merged
andrewlukoshko merged 1 commit into
AlmaLinux:mainfrom
yuravk:build-aarch64-using-tcg-emulation
Sep 24, 2026
Merged

andrewlukoshko merged 1 commit into
AlmaLinux:mainfrom
yuravk:build-aarch64-using-tcg-emulation

Conversation

@yuravk

@yuravk yuravk commented Sep 24, 2026

Copy link
Copy Markdown
Collaborator

In the AlmaLinux organisation the aarch64 GenericCloud images keep
building on the RunsOn a1.metal runner with KVM and the in-job boot
test, unchanged. Everywhere else (forks, CI mirrors) the leg needed a
self-hosted EC2 a1.metal runner started from AWS secrets, on an
AlmaLinux AMI where the apt-based boot test could not run anyway. There
the job now runs on a GitHub-hosted x86_64 runner and builds the image
under QEMU TCG full-system emulation, like the s390x and ppc64le legs.
The start-self-hosted-runner job and its EC2 secrets are removed.

How

The eight aarch64 GenericCloud sources keep their boot ISO, GRUB boot
command, kickstart, SSH and ansible provisioning. Their KVM-specific
settings become variables whose defaults keep the arm64 build unchanged:

aarch64_accelerator kvm -> tcg
aarch64_cpu_model host -> max,pauth-impdef=on
aarch64_grub_hold false -> true
aarch64_extra_kernel_args (empty) -> console=ttyAMA0
aarch64_console_log (unset) -> console teed into the job log

shared-steps switches to them by itself when arch=aarch64 runs on a
runner that is not arm64, with a 3 s boot wait and a 5 h SSH timeout.

  • pauth-impdef=on replaces the architected pointer-authentication
    algorithm, very slow to emulate, with QEMU's cheap one.
  • The GRUB hold presses a key GRUB ignores once a second for 90 s, so
    the emulated UEFI firmware's start-up time does not matter, then moves
    from the ISO's default "Test this media & install" entry to the plain
    "Install" entry.
  • On the virt machine the firmware and GRUB console is the serial port
    that Packer types the boot command into over VNC, so the console is
    teed into the log (-chardev vc,logfile=), not redirected.
  • The aarch64 kickstarts' %post removes the typed console=ttyAMA0 from
    /etc/default/grub and the boot entries, undoes the serial GRUB
    terminal anaconda sets because of it, and regenerates grub.cfg. On
    the arm64 host nothing is typed and these steps do nothing.

The Install KVM step now installs the runner's own emulator by its
architecture (qemu-system-x86, or qemu-system-arm with
qemu-efi-aarch64). Since #366 it installed qemu-system-x86
unconditionally, which is the wrong emulator on the arm64 runner. For an
emulated aarch64 build it adds qemu-system-arm and qemu-efi-aarch64. On
the hosted runner the job gets the 6 h maximum timeout and skips the
in-job boot test, which needs KVM for the image's architecture.
Documented in GENCLOUD_BUILD_TEST.md.

…runner

In the AlmaLinux organisation the aarch64 GenericCloud images keep
building on the RunsOn a1.metal runner with KVM and the in-job boot test,
unchanged. Elsewhere (forks, CI mirrors) the leg needed a self-hosted EC2
a1.metal runner started from secrets (EC2_AMI_ID_AL9_AARCH64, subnet,
security group), on an AlmaLinux AMI where the apt-based test could not
run anyway. Build there on a GitHub-hosted x86_64 runner under QEMU TCG
full-system emulation instead, like the s390x and ppc64le legs, and drop
the start-self-hosted-runner job.

The eight aarch64 GenericCloud sources keep their boot ISO, GRUB boot
command, kickstart, SSH and ansible provisioning; their KVM-specific
settings become variables whose defaults keep the arm64 build unchanged:

  aarch64_accelerator        kvm -> tcg
  aarch64_cpu_model          host -> max,pauth-impdef=on
  aarch64_grub_hold          false -> true
  aarch64_extra_kernel_args  (empty) -> console=ttyAMA0
  aarch64_console_log        (unset) -> file streamed into the job log

shared-steps switches to them by itself when arch=aarch64 runs on a
runner that is not arm64, with a 3 s boot wait and a 5 h SSH timeout.
pauth-impdef=on replaces the architected pointer-authentication
algorithm, very slow to emulate, with QEMU's cheap one. The GRUB hold
presses a key GRUB ignores once a second for 90 s, so the emulated UEFI
firmware's start-up time does not matter, then moves from the ISO's
default "Test this media & install" entry to the plain "Install" one.
console=ttyAMA0 puts anaconda's output on the captured serial console;
the aarch64 kickstarts' %post removes it again from the installed boot
loader configuration (a no-op on the arm64 host).

The Install KVM step now installs the runner's own system emulator by
its architecture (qemu-system-x86 or qemu-system-arm plus
qemu-efi-aarch64) instead of the unconditional qemu-system-x86, which
was the wrong emulator on the arm64 runner, and adds qemu-system-arm and
qemu-efi-aarch64 for an emulated aarch64 build. On the hosted runner the
job gets the 6 h maximum timeout and skips the in-job boot test, which
needs KVM for the image's architecture.
@andrewlukoshko
andrewlukoshko merged commit d4985c8 into AlmaLinux:main Sep 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants