Prepare to support UKIs - #1007
Conversation
7871ec2 to
96f69ca
Compare
|
(Force push to fix commit messages) |
96f69ca to
43887e4
Compare
|
(Forced push to fix commit messages, for real) |
43887e4 to
337e9c8
Compare
|
(Forced push includes missing systemd service) |
| # Note that this file is measured into TPM PCR 5 before parsing: editing | ||
| # it changes PCR 5 and invalidates anything sealed against it. |
There was a problem hiding this comment.
I'd suggest this being the first line of the file, seems like a significant callout. Maybe a "DO NOT EDIT" line, or "WARNING" line too?
| # shim EFI binaries, so image builds find all ESP loaders in one place. | ||
| %global efidir /boot/efi/EFI/BOOT | ||
|
|
||
| # systemd-boot reads its own configuration from \loader\loader.conf on the |
There was a problem hiding this comment.
did you mean /loader/loader.conf?
https://www.freedesktop.org/software/systemd/man/latest/loader.conf.html
| # systemd-boot reads its own configuration from \loader\loader.conf on the | |
| # systemd-boot reads its own configuration from /loader/loader.conf on the |
| # No PC-speaker beeping during the countdown. | ||
| beep no | ||
|
|
||
| # Never scan \loader\keys or enroll Secure Boot keys from the ESP. |
There was a problem hiding this comment.
| # Never scan \loader\keys or enroll Secure Boot keys from the ESP. | |
| # Never scan /loader/keys or enroll Secure Boot keys from the ESP. |
https://www.freedesktop.org/software/systemd/man/latest/loader.conf.html
| %{buildroot}%{efidir}/systemd-boot%{_cross_efi_arch}.efi | ||
|
|
||
| # Ship sensible systemd-boot defaults. This has to land on the ESP rather than | ||
| # the boot partition, since systemd-boot only reads \loader\loader.conf from |
There was a problem hiding this comment.
| # the boot partition, since systemd-boot only reads \loader\loader.conf from | |
| # the boot partition, since systemd-boot only reads /loader/loader.conf from |
| // A UKI image boots from the XBOOTLDR partition and has no A/B partition sets to fall back | ||
| // on, so a missing partition means /boot can never be populated. Fail loudly instead of | ||
| // leaving it unmounted, which would silently break everything that reads /boot. | ||
| None if uki_image() => BootAction::MissingXbootldr, |
There was a problem hiding this comment.
can't we just
| None if uki_image() => BootAction::MissingXbootldr, | |
| None if uki_image_from_env() => BootAction::MissingXbootldr, |
and bring this function's signature to just
fn boot_action(xbootldr: Option<PathBuf>) -> BootAction
? The callsite in prepare_boot is the only instance of using uki_image_from_env(), which is just wired through to this method.
| match boot_action(xbootldr, uki_image_from_env) { | ||
| BootAction::MountXbootldr(boot_partition_path) => { | ||
| info!( | ||
| "Found XBOOTLDR partition {} on the OS disk, so this is a UKI image", |
There was a problem hiding this comment.
| "Found XBOOTLDR partition {} on the OS disk, so this is a UKI image", | |
| "UKI image detected (XBOOTLDR partition '{}')", |
| pub fn xbootldr_partition() -> Result<Option<PathBuf>, Error> { | ||
| // The root filesystem is a dm-verity device. We want to determine what disk and partition | ||
| // the backing data is part of. Look up the device major and minor via stat(2): | ||
| let root_fs = BlockDevice::from_device_path("/") | ||
| .context(error::BlockDeviceFromPathSnafu { device: "/" })?; | ||
| // Get the first lower device from this one, and determine what disk it belongs to. | ||
| let active_partition = root_fs | ||
| .lower_devices() | ||
| .and_then(|mut iter| iter.next().transpose()) | ||
| .context(error::RootLowerDevicesSnafu { | ||
| root: root_fs.path(), | ||
| })? | ||
| .context(error::RootHasNoLowerDevicesSnafu { | ||
| root: root_fs.path(), | ||
| })?; | ||
| let os_disk = active_partition | ||
| .disk() | ||
| .context(error::DiskFromPartitionSnafu { | ||
| device: root_fs.path(), | ||
| })? | ||
| .context(error::RootNotPartitionSnafu { | ||
| device: root_fs.path(), | ||
| })?; | ||
|
|
||
| // Parse the partition table on the disk. | ||
| let table = GPT::find_from(&mut File::open(os_disk.path()).context(error::OpenSnafu { | ||
| path: os_disk.path(), | ||
| what: "reading", | ||
| })?) | ||
| .map_err(error::GPTError) | ||
| .context(error::GPTFindSnafu { | ||
| device: os_disk.path(), | ||
| })?; | ||
|
|
||
| // Loads the path to partition number `num` on the OS disk. | ||
| let device_from_part_num = |num| -> Result<PathBuf, Error> { | ||
| Ok(os_disk | ||
| .partition(num) | ||
| .context(error::PartitionFromDiskSnafu { | ||
| device: os_disk.path(), | ||
| })? | ||
| .context(error::PartitionNotFoundOnDeviceSnafu { | ||
| num, | ||
| device: os_disk.path(), | ||
| })? | ||
| .path()) | ||
| }; | ||
|
|
||
| let mut partitions = table | ||
| .iter() | ||
| .filter(|(_, p)| p.is_used() && p.partition_type_guid == XBOOTLDR) | ||
| .map(|(num, _)| device_from_part_num(num)) | ||
| .collect::<Result<Vec<_>, Error>>()?; | ||
|
|
||
| ensure!( | ||
| partitions.len() <= 1, | ||
| error::MultiplePartitionsOfTypeSnafu { | ||
| partition_type: { | ||
| let g = XBOOTLDR; | ||
| format!( | ||
| "{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-\ | ||
| {:02x}{:02x}{:02x}{:02x}{:02x}{:02x}", | ||
| g[3], | ||
| g[2], | ||
| g[1], | ||
| g[0], | ||
| g[5], | ||
| g[4], | ||
| g[7], | ||
| g[6], | ||
| g[8], | ||
| g[9], | ||
| g[10], | ||
| g[11], | ||
| g[12], | ||
| g[13], | ||
| g[14], | ||
| g[15], | ||
| ) | ||
| }, | ||
| partitions, | ||
| } | ||
| ); | ||
|
|
||
| Ok(partitions.pop()) | ||
| } |
There was a problem hiding this comment.
[P2] Deduplicate disk/GPT lookup shared by xbootldr_partition and State::load
xbootldr_partition() (lines ~418–461) is a near line-for-line copy of the first ~60 lines of State::load() (lines 71–131): the BlockDevice::from_device_path("/") walk, the lower_devices() selection, the disk() unwrap, the GPT::find_from open, and the device_from_part_num closure are all repeated verbatim.
Why it matters. prepare_boot in prairiedog calls both signpost::xbootldr_partition() and signpost::State::load() back-to-back in the GRUB path (main.rs:243 and main.rs:274), so the same disk is stat-walked and its GPT parsed twice on every boot. More importantly, any future change to how the OS disk is discovered has to be applied in two places, and drift here is silent.
Failure scenario. A follow-up change that teaches State::load to unwrap an extra dm layer (say, "boot from LUKS") applied only to State::load leaves xbootldr_partition looking at the wrong disk. It returns None, prairiedog silently takes the MountActiveSet branch on what is really a UKI image, and boot tries to mount an ext4 boot partition on a disk that no longer has one.
Fix. Extract a private helper like fn parse_os_disk_table() -> Result<(Disk, GPT), Error> and have both entry points call it. Alternatively, expose the XBOOTLDR lookup as a method on State so a single scan feeds both.
|
|
||
| let mut partitions = table | ||
| .iter() | ||
| .filter(|(_, p)| p.is_used() && p.partition_type_guid == XBOOTLDR) |
There was a problem hiding this comment.
[P2] xbootldr_partition filters on is_used() but State::load does not
xbootldr_partition filters entries with p.is_used() && p.partition_type_guid == XBOOTLDR (this line). State::load's nth_guid closure (lines 104–110) filters only on p.partition_type_guid == guid — no is_used() check.
In the current schema this cannot matter, because unused entries have an all-zero type GUID. But the asymmetry is exactly the kind of subtle drift the "read the GPT once" comment in main.rs:239–242 is trying to avoid: if a future change ever ties partition identity to something other than the type GUID (a partition-name convention, an "in transition" tombstone), the two functions will disagree.
Also: the test ignores_unused_and_other_types (line 583) exercises partition_nums_with_type — a test helper — not State::load's actual nth_guid filter.
Fix. Add p.is_used() to State::load's nth_guid filter for consistency, or extract a shared helper.
| ensure!( | ||
| partitions.len() <= 1, | ||
| error::MultiplePartitionsOfTypeSnafu { | ||
| partition_type: { | ||
| let g = XBOOTLDR; | ||
| format!( | ||
| "{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-\ | ||
| {:02x}{:02x}{:02x}{:02x}{:02x}{:02x}", | ||
| g[3], | ||
| g[2], | ||
| g[1], | ||
| g[0], | ||
| g[5], | ||
| g[4], | ||
| g[7], | ||
| g[6], | ||
| g[8], | ||
| g[9], | ||
| g[10], | ||
| g[11], | ||
| g[12], | ||
| g[13], | ||
| g[14], | ||
| g[15], | ||
| ) | ||
| }, | ||
| partitions, | ||
| } | ||
| ); |
There was a problem hiding this comment.
[P2] MultiplePartitionsOfType builds the GUID string at runtime with a 16-arg format!
The XBOOTLDR type GUID is a compile-time constant — its canonical form is already in a comment three lines above the array literal (line 23) and in the MissingXbootldrPartition / ScanForXbootldrPartition display messages in prairiedog (error.rs:29, error.rs:47).
Three separate places now hand-serialize the same 128-bit constant, and one of them does it with a 16-argument positional format! that will silently produce the wrong string if the byte-swap indices are ever transcribed incorrectly. There is a byte-order test (xbootldr_guid_byte_order, line 597), but no test for the formatting.
Fix. Since XBOOTLDR is the only type GUID this call currently reports, just pass the canonical string literal: partition_type: "bc13c2ff-59e6-4262-a352-b275fd6f7172".to_string(). If more type GUIDs need reporting later, introduce a fn guid_to_string(g: [u8; 16]) -> String helper with its own test.
| let (xbootldr, scan_error) = match signpost::xbootldr_partition() { | ||
| Ok(partition) => (partition, None), | ||
| Err(e) => { | ||
| // Not fatal by itself: a GRUB image still has the boot partition of its active | ||
| // partition set to mount. Log it here so the cause reaches the journal on every | ||
| // path, and hold on to it so a UKI image can report it as the underlying cause | ||
| // rather than claiming the partition is absent. | ||
| warn!("Unable to scan the OS disk for an XBOOTLDR partition: {e}"); | ||
| (None, Some(e)) | ||
| } | ||
| }; | ||
|
|
||
| match boot_action(xbootldr, uki_image_from_env) { | ||
| BootAction::MountXbootldr(boot_partition_path) => { | ||
| info!( | ||
| "Found XBOOTLDR partition {} on the OS disk, so this is a UKI image", | ||
| boot_partition_path.display() | ||
| ); | ||
| mount_boot_partition(&boot_partition_path, BOOT_FS_VFAT, Some(VFAT_MOUNT_DATA)) | ||
| } | ||
|
|
||
| BootAction::MissingXbootldr => match scan_error { | ||
| // The disk may well have an XBOOTLDR partition that we were unable to see, so report | ||
| // why the scan failed instead of reporting the partition as absent. | ||
| Some(source) => Err(source).context(error::ScanForXbootldrPartitionSnafu), | ||
| None => error::MissingXbootldrPartitionSnafu.fail(), | ||
| }, | ||
|
|
||
| BootAction::MountActiveSet => { | ||
| info!("No XBOOTLDR partition found on the OS disk; using the boot partition of the active partition set"); | ||
| // Get the current partitions state | ||
| let state = signpost::State::load().context(error::LoadStateSnafu)?; | ||
|
|
||
| mount_boot_partition(&state.active_set().boot, BOOT_FS_EXT4, None) | ||
| } | ||
| } |
There was a problem hiding this comment.
[P2] Multiple XBOOTLDR partitions on a "GRUB" image silently fall back to mounting the A-set ext4 boot partition
xbootldr_partition() returns Err(MultiplePartitionsOfType) when more than one XBOOTLDR partition is on the OS disk (state.rs:469–497). Here in prepare_boot, that error is stashed as scan_error and downgraded to a warn! log (lines 250–252). Then boot_action(None, uki_image_from_env) is called: if UKI_IMAGE is unset or "false", control flows to BootAction::MountActiveSet and prairiedog mounts the A-set ext4 boot partition (lines 271–277).
Why it matters. "Two XBOOTLDR partitions on disk" is a structural corruption of the partition table, not a legitimate GRUB layout — a plain GRUB image has zero of them. Suppressing this to a warning on the GRUB path lets a broken disk boot as if nothing is wrong; if that disk was meant to be a UKI image but image-format.env got lost, the operator sees a successful /boot mount that contains none of the UKI's kernels. The failure only surfaces later, when systemd-boot or a kernel update tool trips over it.
Fix. In the Err arm at line 245, distinguish "no XBOOTLDR to report" (log and continue) from "the scan found a real problem" (return the error unconditionally). Only demote truly ambiguous scan errors (I/O failures on the raw disk) and propagate MultiplePartitionsOfType as a hard failure. Alternatively, keep the scan-error stash but check its variant when choosing the fallback.
| fn uki_image_from_env() -> bool { | ||
| match env::var(UKI_IMAGE_ENV) { | ||
| Ok(value) => { | ||
| info!("{UKI_IMAGE_ENV} is set to '{value}' in the environment"); | ||
| value.trim() == "true" | ||
| } | ||
| Err(_) => { | ||
| info!( | ||
| "{UKI_IMAGE_ENV} is not set in the environment; assuming this is not a UKI image" | ||
| ); | ||
| false | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
[P2] uki_image_from_env treats non-UTF-8 and misspelled values as "not a UKI image" without warning
uki_image_from_env uses env::var(UKI_IMAGE_ENV):
Ok(value)wherevalue.trim() != "true"(including"TRUE","1","yes", or an accidental leading#) silently returnsfalseafter logging the value atinfo.Err(NotUnicode(_))(garbage bytes in the env var) is collapsed into the same "not set" branch asErr(NotPresent), so the operator sees"UKI_IMAGE is not set in the environment"even though it was set — just unreadably.
Why it matters. This env variable is the sole fallback used to decide whether missing partitions are fatal (line 232). A UKI image whose image-format.env was corrupted or transcoded (e.g. an editor added a BOM, or a build emitted UKI_IMAGE=True) will be misclassified as a GRUB image. On a UKI image with a transient GPT read error at boot, the operator loses the useful ScanForXbootldrPartition error message and gets a misleading State::load failure instead.
Fix. Either
- Case-insensitive parse (
value.trim().eq_ignore_ascii_case("true")) and explicitly reject unrecognized values with a warning, or - Return
Result<bool, Error>and propagate parse/NotUnicodeerrors soprepare_bootcan decide.
At minimum, log warn! (not info!) when the value is set but not exactly "true" — right now that case is indistinguishable from a legitimate UKI_IMAGE=false in the journal.
| Conflicts: %{_cross_os}image-feature(standalone-image) | ||
| Conflicts: %{_cross_os}image-feature(in-place-updates) |
There was a problem hiding this comment.
[P1] Conflicts: image-feature(in-place-updates) / image-feature(standalone-image) reference feature names that do not exist
The image-feature naming convention throughout the repository is the negative form. A grep for image-feature( across the tree shows:
image-feature(no-in-place-updates)— used acrossos.specas the "off" flag.image-feature(in-place-updates)— not defined or used anywhere else.image-feature(standalone-image)— not defined or used anywhere else.
Why it matters. These are dead conflict clauses. The intended safety guard — "the systemd-boot bootloader package must never be installed alongside the signpost/GRUB update flow" — is silently inert. If a future variant is misconfigured to include both signpost/GRUB and the UKI bootloader package, rpm/dnf won't catch it.
Fix. Either invert the polarity to match the codebase convention, or drop these lines since Requires: image-feature(uki-image) on line 192 combined with Conflicts: image-feature(no-uki-image) on line 194 already prevents installation on any non-UKI image. If two new positive feature names are being introduced by this PR series, they need to actually be defined on the image side and referenced consistently.
There was a problem hiding this comment.
Not accurate again, the image features exist in Twoliter.
| +# Bottlerocket SDK fix: the cross sysroot reports cpu_family 'x86' even for | ||
| +# x86_64 targets, which makes efi_arch resolve to 'ia32'. Force x64 when the | ||
| +# real target cpu is x86_64. | ||
| +if efi_arch == 'ia32' and host_machine.cpu() == 'x86_64' | ||
| + efi_arch = 'x64' | ||
| +endif | ||
| + | ||
| +# The same SDK quirk applies on 64-bit ARM: cpu_family is reported as 'arm', | ||
| +# so efi_arch resolves to the 32-bit 'arm' EFI target and sd-boot is emitted as | ||
| +# systemd-bootarm.efi with EFI_MACHINE_TYPE_NAME=arm. Force aa64 when the real | ||
| +# target cpu is aarch64, so the binary is named and typed per the EFI spec and | ||
| +# matches the bootaa64.efi/grubaa64.efi convention used by shim and GRUB. | ||
| +# Note: efi_cpu_family is deliberately left resolving to 'arm' below, since the | ||
| +# 'arm' and 'aarch64' entries of efi_arch_c_args are identical | ||
| +# (-mgeneral-regs-only) and the extra 'arm' link arg | ||
| +# (-Wl,--no-wchar-size-warning) is harmless here. | ||
| +if efi_arch == 'arm' and host_machine.cpu() == 'aarch64' | ||
| + efi_arch = 'aa64' | ||
| +endif | ||
| + | ||
| +# Single corrected arch key for all EFI flag lookups, so no flag site can | ||
| +# silently regress to the -m32 (ia32) path on this SDK. | ||
| +if efi_arch == 'x64' | ||
| + efi_cpu_family = 'x86_64' | ||
| +elif efi_arch == 'ia32' | ||
| + efi_cpu_family = 'x86' | ||
| +else | ||
| + efi_cpu_family = host_machine.cpu_family() | ||
| +endif |
There was a problem hiding this comment.
[P2] Overriding efi_arch in systemd's meson.build masks a real SDK bug and is fragile against upstream refactors
The patch works around a Bottlerocket-SDK quirk where host_machine.cpu_family() returns 'x86' on x86_64 and 'arm' on aarch64, and post-processes the value here.
-
Root cause is elsewhere.
host_machine.cpu_family()being wrong is a meson cross-file / SDK configuration bug ([host_machine] cpu_family = 'x86_64'/'aarch64'are the correct settings). Patching every consumer ofcpu_familyin systemd is whack-a-mole — the SDK cross-file should be fixed so every build sees the right value. If the SDK fix ever lands, this patch becomes actively misleading. -
Incomplete coverage. The patch only replaces
host_machine.cpu_family()at two call sites insrc/boot/meson.build. Other consumers inside systemd 257 (e.g., arch-specific seccomp lists, syscall filter tables, ukify machinery) will still see the wrong value. The commit message says "no flag site can silently regress" but only sd-boot'sefi_archspecswas fixed. -
efi_arch_altsentinel semantics. The patch removes theif have and efi_arch == 'x64' and cc.links(…)block but leaves theefi_arch_alt = ''initializer. Please confirm thatefi_archspecsguards the_altentries withif efi_arch_alt != ''— otherwise meson may still try to build a nameless alt binary. -
Aarch64 asserts an unenforced invariant. The comment says "efi_cpu_family is deliberately left resolving to 'arm'" for aarch64, relying on
efi_arch_c_args.get('arm', []) == efi_arch_c_args.get('aarch64', []). Any future systemd change that diverges the two entries will silently be lost.
Fix.
- Preferred: fix the SDK meson cross-file and drop this patch.
- If the patch must stay: set
efi_cpu_family = 'aarch64'explicitly whenefi_arch == 'aa64', and add amessage()/error()guard that assertsefi_arch_c_args.get('arm') == efi_arch_c_args.get('aarch64')at configure time.
There was a problem hiding this comment.
The SDK fix, we can do in a subsequent release. The patch must stay so I'll fix the suggestion.
Enable systemd-boot and systemd-stub in the systemd-257 spec to provide the bootloader and EFI stub required for Unified Kernel Images (UKI). Add a patch to skip building 32-bit (ia32) EFI binaries on architectures that do not need them, and ship a loader.conf with sensible default settings. Signed-off-by: Arnaldo Garcia Rincon <agarrcia@amazon.com>
Add EnvironmentFile=-/usr/share/bottlerocket/image-format.env to prepare-boot.service so prairiedog can read image-format variables at boot preparation time. Signed-off-by: Arnaldo Garcia Rincon <agarrcia@amazon.com>
On UKI-based images, the kernel command line is measured into PCR9 as part of the UKI PE binary at boot, so the separate user-space measurement in measure-cmdline.service is redundant. Gate the service with an ExecCondition on UKI_IMAGE so it only runs on non-UKI images. Signed-off-by: Arnaldo Garcia Rincon <agarrcia@amazon.com>
Prior to the introduction of systemd-boot, GRUB was the only supported bootloader and was always explicitly required. With systemd-boot now available, the bootloader must be selected based on the format of the built image. Require the (bootloader-efi) capability, which is satisfied by either grub or systemd-boot, whichever is installed based on the variant's enabled feature flags. Default to grub when the (uki-image) bconds are absent, preserving backwards compatibility with older twoliter versions. Signed-off-by: Arnaldo Garcia Rincon <agarrcia@amazon.com>
UKIs do not yet support in-place upgrades. Skip installing signpost on UKI-based variants, since marking partitions with successful boots only applies to the GRUB-based boot format. Signed-off-by: Arnaldo Garcia Rincon <agarrcia@amazon.com>
Add xbootldr_partition(), which scans the OS disk's GPT for a partition of the XBOOTLDR type GUID and returns its path. Returns None when no such partition exists, which is the case on GRUB images, and fails if more than one is found since there would be no way to choose between them. A prior pass introduced generic disk- and partition-type-searching abstractions (disk.rs, partition_types.rs) to support this lookup, but a single-purpose function is simpler and sufficient for the one caller that needs it, so those files are removed in favor of this helper living alongside the rest of the partition-table logic in state.rs. Signed-off-by: Arnaldo Garcia Rincon <agarrcia@amazon.com>
prepare_boot previously always mounted the active partition set's ext4 boot partition. On UKI images, the boot partition is XBOOTLDR, a FAT filesystem that systemd-boot's firmware loader must be able to read. Scan the disk layout and check the UKI_IMAGE environment variable, which prepare-boot.service sets from image-format.env. If it is a UKI image, look up the XBOOTLDR partition and mount it as vfat with the mount options systemd-boot expects (umask, shortname, iocharset, and an SELinux context, since FAT has no extended attributes to carry a label). Otherwise, fall back to the existing ext4 mount of the active set's boot partition. Signed-off-by: Arnaldo Garcia Rincon <agarrcia@amazon.com>
Backport of upstream bb19b6104978b5ede792fa3f0cfc74272f20bf9c. Signed-off-by: Maher Homsi <maherhom@amazon.com>
337e9c8 to
53b84ce
Compare
| Requires: %{_cross_os}image-feature(uki-image) | ||
| Provides: %{_cross_os}bootloader(efi) | ||
| Conflicts: %{_cross_os}image-feature(no-uki-image) | ||
| Conflicts: %{_cross_os}image-feature(standalone-image) |
There was a problem hiding this comment.
standalone-image feature should be compatible with systemd-bootloader
| Conflicts: %{_cross_os}image-feature(standalone-image) |
| Patch9019: 9019-boot-remove-SMBIOS-Type-11-kernel-cmdline-extra-mech.patch | ||
| Patch9020: 9020-boot-vmspawn-finish-removing-SMBIOS-cmdline-extra-bi.patch |
There was a problem hiding this comment.
Do these need to be 2 separate patches? Looks like they're modifying the same file.
| The SDK cross sysroot mis-reports host_machine.cpu_family(), so systemd's | ||
| efi_arch lookup resolves to the wrong EFI target: 'ia32' on x86_64 and 'arm' on | ||
| aarch64. Correct both from host_machine.cpu(), and drop the IA-32 mixed-mode | ||
| alternate build, which cannot link in this sysroot. |
There was a problem hiding this comment.
This patch (as well as 9019 and 9020) is missing a Signed-off-by: line
Description of changes:
This series prepares the core kit to support Unified Kernel Images.
Build
systemd-bootandsystemd-stubfor systemd-257. A patch for systemd was needed to prevent it from building these binaries for the wrong CPU architectures (32 bits).The release package was updated to conditionally include
grub, since now there is another package that provides a bootloader.Given that in-place upgrades aren't supported for the time being,
signpostis skipped entirely as a binary. However, the library component was updated to find the correct FAT partition that includes the UKI to mount it at/boot. This is needed for other parts of the system, like the FIPS check.User-space PCR9 measurements are skipped for UKI-based images, since PCR9 is measured at the kernel level when systemd-boot is used.
Testing done:
As part of: bottlerocket-os/bottlerocket-kernel-kit#523
in-place-upgrades+ukiare usedTerms of contribution:
By submitting this pull request, I agree that this contribution is dual-licensed under the terms of both the Apache License, version 2.0, and the MIT license.