Skip to content

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

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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