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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions