Experimental Ubuntu 26.04 (resolute) build support#26
Merged
Conversation
3 tasks
7dc26ab to
befe594
Compare
fef6a8e to
b0a3226
Compare
c0e9db1 to
cfeb277
Compare
cfeb277 to
32c26bf
Compare
32c26bf to
24666f9
Compare
24666f9 to
8624c22
Compare
4f39b12 to
92226b9
Compare
92226b9 to
7562e1e
Compare
7562e1e to
282b2ab
Compare
4405c04 to
c36b485
Compare
282b2ab to
0842b6a
Compare
8280226 to
2eeb9b7
Compare
The dracut hostonly settings are not suite-specific.
Let 'just ubuntu_suite=resolute ubuntu_version=26.04 tailscale_suite=noble variant=cloud build' produce an experimental 26.04-based image without touching the 24.04 CI path. The Tailscale apt repo is keyed by Ubuntu codename and typically lags new Ubuntu releases during the RC window; TAILSCALE_SUITE defaults to UBUNTU_SUITE and can be overridden independently. The Tailscale packages are compatible across recent Ubuntu versions.
The hostonly=yes / sloppy config is a workaround for a dracut bug in noble's release of dracut where non-hostonly mode produces a non-functional initramfs. Newer Ubuntu suites run dracut in its default mode, which already includes the required hardware/cloud modules. The force-include directives in 03-hardware-drivers.conf and 04-cloud-drivers.conf only apply under the hostonly workaround.
Dracut's default is hostonly=yes per the resolute manpage, contrary to my earlier assumption. With no override on 26.04 the shipped initramfs ends up bound to the build environment, not the target hardware. Fix: on 26.04+ the image must explicitly set hostonly="no" to produce a portable initramfs. The installer is then responsible for stripping that override before its own dracut --force, so the target machine gets a hostonly=yes (default) initramfs specialised to its hardware. Updates r[image.boot.dracut], r[image.boot.hardware-drivers], r[image.boot.cloud-drivers], and adds a new install-time step to r[installer.boot.regen].
08d48cb to
4c1c5e3
Compare
Adds /etc/dracut.conf.d/01-portable-image.conf with hostonly="no" on non-noble suites, so the shipped image's initramfs includes modules for all kernel-supported hardware rather than just the build host's. Noble still uses the hostonly=yes + force-include workaround.
The 26.04+ images carry /etc/dracut.conf.d/01-portable-image.conf (hostonly="no") so the shipped initramfs is portable across hardware. For the target machine, we want dracut's default (hostonly=yes) so the rebuilt initramfs is specialised. Remove the override before running dracut in chroot.
Mirrors the impl change: assert /etc/dracut.conf.d/01-portable-image.conf exists and contains hostonly="no" on non-noble suites.
Adds a (arch × suite) matrix to images-cloud, images-metal, iso, container-test, and register-amis. Resolute (26.04) now runs the full pipeline: build → ISO → container-test → AMI registration on tagged releases.
upload-artifact v7 added 'archive: false' to skip the zip wrapper. For multi-GB uploads the local zip overhead is real, even with compression-level: 0 (it still streams every byte through the zip encoder). Switch every upload step to archive: false.
archive: false requires single-file uploads. The original 'Upload converted formats' step matched both *.vmdk and *.qcow2, which trips 'Found 2 files to upload'. Split into separate per-format uploads so each artifact is one file.
archive: false ignores the upload step's name: parameter — the artifact is named after the file's basename. Updates downstream jobs: - iso, register-ami: download cloud raw via pattern (the basename has a build-date suffix that varies between runs); merge-multiple flattens it into the expected directory structure. - container-test: ISO basenames are deterministic (no date), so an exact name lookup works. - release: switch from per-artifact-dir loops to pattern: '*' + merge-multiple, then glob by extension.
A long build crossing midnight UTC produces inconsistent filenames between parallel matrix entries, which breaks the pattern-matched downloads in iso/register-ami. Have a single top-level prep job emit the build date once; every matrix leg picks it up via $BUILD_DATE so all uploads share one stamp.
archive: false ignores the upload step's name: parameter — those fields are silently dead. The .raw.size sidecar globs in the raw uploads also match nothing (no producer in tree). Cleaning up both.
tracey's parser ignores the first of two consecutive '# r[...]' comment lines (no other location in the codebase uses that pattern, which is the clue). Joining them onto a single comment line makes both ci.output-arch and ci.output-suite annotations visible.
GitHub keeps at most ONE pending run per concurrency group, so a group keyed only on the ref evicts (cancels) older queued runs when new events fire — particularly noisy with stacked PRs, where pushing to one branch cascades synchronize events into the dependent PRs. Including the SHA gives each unique commit its own queue: same SHA retriggered still dedups, different SHAs run independently. Same treatment applied to both build.yml and checks.yml.
With the per-commit concurrency group, the only collision left is the same SHA being retriggered — and there 'cancel the older run, take the latest' is what we want. (checks.yml already had it true.)
.img is more widely recognised by image-flashing tools (rpi-imager, balena-etcher, gnome-disks, etc.). Rename the disk image file extension across the full pipeline: image build, iso source-image lookup, AMI registration, release artifacts, manual-testing docs.
4c1c5e3 to
9d1062b
Compare
The 26.04 cryptsetup package's systemd-cryptsetup binary moved to a separate package (systemd-cryptsetup), and is only a Recommends of cryptsetup — so --no-install-recommends drops it. Without that binary, dracut's 71systemd-cryptsetup module check() returns 1 and is dropped from the initramfs. The 70crypt module then installs only its crypt-generator.sh (which delegates to systemd-cryptsetup when systemd is present in the initramfs) and skips the cryptsetup binary. Result: nothing actually unlocks the LUKS root at boot. Pulling systemd-cryptsetup in explicitly fixes it.
9d1062b to
4e0ee5f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the plumbing to build images against arbitrary Ubuntu suites and validates it against Ubuntu 26.04 (resolute), now that 26.04 LTS has shipped.
What changed
UBUNTU_SUITEplumbed end-to-end through the justfile,image/build.sh,image/configure.sh, and the chroot scripts. NewTAILSCALE_SUITEenv/justfile var lets the Tailscale apt repo be set independently from the Ubuntu suite (defaults toubuntu_suite).hostonly=yes(per thedracut.conf(5)resolute manpage), so without an override the shipped image's initramfs would be bound to the build host. On noble,hostonly=nois broken, so we keep the existinghostonly=yes+ sloppy + force-include workaround. On 26.04+, we install/etc/dracut.conf.d/01-portable-image.confsettinghostonly="no", which auto-includes all kernel modules. Verified: resolute initramfs lands at ~82M (vs. typical hostonly=yes ~30-50M).01-portable-image.confbefore its post-installdracut --force, so dracut's default (hostonly=yes) takes effect and the rebuilt initramfs is specialised to the target machine. Existing fstab/UUID/LUKS workarounds in the installer remain valid.01-fix-hostonly-noble.conf→01-fix-hostonly.conf(filename is no longer suite-specific even though it's still gated to noble).bestool999 + wildcard 100 on 26.04+, so apt prefers Ubuntu's archive for everything except bestool.cloud-init.servicewrapper;cloud-init.targetis wired in dynamically bycloud-init-generatorat boot. Test now checks for the generator binary on non-noble suites.IMAGE_SIZEbumped to 8G. Resolute's package set pluslinux-firmwaredoesn't fit in 5G — metal builds hit btrfs ENOSPC mid-install. Cloud (which doesn't ship linux-firmware) stays at 5G.Status
End-to-end verified locally on every arch/variant combination (with the latest dracut hostonly fix):
Filed as a draft because:
docs/spec/ci-cd.mdare intentionally untouched.Test plan