bootc-dev / bootc-dev/bootc

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

Open
#1,976 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
2.3k
Forks
230
Avg merge
3d 12h
Merged PRs (30d)
38

Description

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

```shell
# […]
# 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)](https://github.com/gucci-on-fleek/maxchernoff.ca/blob/4c9c0d78c189d9c5cc90a2a9d8612cf5b115375d/builder/containers/fedora-iot/final.containerfile)

and I'm generating the disk image with

```shell
podman run --privileged \
bootc install to-disk \
--generic-image \
--bootloader=systemd \
--composefs-backend \
--via-loopback \
/output/fedora-bootc.raw
```

Full command

```shell
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

https://github.com/bootc-dev/bootc/blob/1b898758c94e25b50d08283841ad188999b26aaa/crates/lib/src/bootc_composefs/boot.rs#L880

https://github.com/bootc-dev/bootc/blob/1b898758c94e25b50d08283841ad188999b26aaa/crates/lib/src/bootc_composefs/boot.rs#L1026-L1031

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/.efi`, then `systemd-boot` displays all 3 profiles, and I'm able to boot all 3 as expected.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.