Skip to content

UKI profiles ignored with install to-disk --bootloader=systemd --composefs-backend #1976

@gucci-on-fleek

Description

@gucci-on-fleek

I've built an image containing a UKI with multiple profiles, but because of how bootc install to-disk generates the EFI partition, systemd-boot seems to ignore it. I'm generating the UKIs with the following script

UKI generation script
# […]
# Determine kernel version
kver="$(cd /usr/lib/modules && echo *)"
kernel_path="/usr/lib/modules/$kver"

# Create cmdline file
echo "composefs=${COMPOSEFS_ID} root=gpt-auto rw" > /etc/cmdline

# Get the UKI name
uki_name="$(\
    source /usr/lib/os-release && \
    echo "${OSTREE_VERSION//./-}" \
)"

# Build profiles
mkdir -p /tmp/profiles/

ukify build \
    --profile="TITLE=$uki_name: Debug Mode
ID=debug" \
    --cmdline="$(cat /etc/cmdline) systemd.debug_shell=1 console=tty1 enforcing=0" \
    --output="/tmp/profiles/debug.efi"

ukify build \
    --profile="TITLE=$uki_name: Emergency Mode
ID=debug" \
    --cmdline="$(cat /etc/cmdline) rd.systemd.unit=emergency.target" \
    --output="/tmp/profiles/emergency.efi"

# Build systemd-boot EFI executable
mkdir -p "/boot/EFI/Linux/"
ukify build \
    --linux="$kernel_path/vmlinuz" \
    --initrd="$kernel_path/initramfs.img" \
    --cmdline="@/etc/cmdline" \
    --os-release="@/usr/lib/os-release" \
    --profile="TITLE=$uki_name: Main" \
    --join-profile="/tmp/profiles/debug.efi" \
    --join-profile="/tmp/profiles/emergency.efi" \
    --uname="$kver" \
    --measure \
    --output="/boot/EFI/Linux/$uki_name+03-00.efi"

mkdir -p /boot/EFI/BOOT/ /boot/EFI/systemd/
cp /usr/lib/systemd/boot/efi/systemd-bootx64.efi /boot/EFI/BOOT/BOOTX64.EFI
cp /usr/lib/systemd/boot/efi/systemd-bootx64.efi /boot/EFI/systemd/systemd-bootx64.efi
# […]

(Full script)

and I'm generating the disk image with

podman run --privileged <image> \
    bootc install to-disk \
        --generic-image \
        --bootloader=systemd \
        --composefs-backend \
        --via-loopback \
        /output/fedora-bootc.raw
Full command
truncate -s 10G fedora-bootc.raw
sudo podman run \
    --pull=newer \
    --rm \
    --privileged \
    --pid=host \
    --security-opt=label=type:unconfined_t \
    --volume=/var/lib/containers/:/var/lib/containers/ \
    --volume=./fedora-bootc.raw:/output/fedora-bootc.raw \
    maxchernoff.ca/fedora-iot:latest \
        bootc install to-disk \
            --generic-image \
            --bootloader=systemd \
            --composefs-backend \
            --filesystem=btrfs \
            --via-loopback \
            /output/fedora-bootc.raw

When booting the image, I would expect to see 3 choices in the systemd-boot menu, but I only see 1. I think that this might be because the following code unconditionally writes out a .conf file

PEType::Uki => &format!("{}{}", uki_id.to_hex(), EFI_EXT),

entries_dir
.atomic_write(
type1_entry_conf_file_name(os_id, &bls_conf.version(), FILENAME_PRIORITY_PRIMARY),
bls_conf.to_string().as_bytes(),
)
.context("Writing conf file")?;

while systemd-boot will only load multiple profiles if the .efi file is directly in /boot/EFI/Linux/ (maybe?).

If I mount the generated disk image, delete /boot/loader entirely, and move /boot/EFI/Linux/bootc/*.efi to /boot/EFI/Linux/<version-number>.efi, then systemd-boot displays all 3 profiles, and I'm able to boot all 3 as expected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions