Skip to content

examples: Add bootc UKI & BLS examples #143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions examples/bootc-bls/Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM quay.io/fedora/fedora-bootc:42
COPY extra /
COPY cfsctl /usr/bin

RUN passwd -d root

# need to have composefs setup root in the initramfs so we need this
RUN set -x; \
kver=$(cd /usr/lib/modules && echo *); \
dracut -vf --install "/etc/passwd /etc/group" /usr/lib/modules/$kver/initramfs.img $kver;
17 changes: 17 additions & 0 deletions examples/bootc-bls/build
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

set -eux

cd "${0%/*}"

cargo build --release --features=pre-6.15 --bin cfsctl --bin composefs-setup-root

cp ../../target/release/cfsctl .
cp ../../target/release/composefs-setup-root extra/usr/lib/dracut/modules.d/37composefs/

mkdir -p tmp

sudo podman build \
-t quay.io/fedora/fedora-bootc-bls:42 \
-f Containerfile \
--iidfile=tmp/iid \
1 change: 1 addition & 0 deletions examples/bootc-bls/extra/etc/dracut.conf.d/no-xattr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export DRACUT_NO_XATTR=1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# we want to make sure the virtio disk drivers get included
hostonly=no

# we need to force these in via the initramfs because we don't have modules in
# the base image
force_drivers+=" virtio_net vfat "
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright (C) 2013 Colin Walters <[email protected]>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <https://www.gnu.org/licenses/>.

[Unit]
DefaultDependencies=no
ConditionKernelCommandLine=composefs
ConditionPathExists=/etc/initrd-release
After=sysroot.mount
Requires=sysroot.mount
Before=initrd-root-fs.target
Before=initrd-switch-root.target

OnFailure=emergency.target
OnFailureJobMode=isolate

[Service]
Type=oneshot
ExecStart=/usr/bin/composefs-setup-root
StandardInput=null
StandardOutput=journal
StandardError=journal+console
RemainAfterExit=yes
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/bash

check() {
return 0
}

depends() {
return 0
}

install() {
inst \
"${moddir}/composefs-setup-root" /usr/bin/composefs-setup-root
inst \
"${moddir}/composefs-setup-root.service" \
"${systemdsystemunitdir}/composefs-setup-root.service"

$SYSTEMCTL -q --root "${initdir}" add-wants \
'initrd-root-fs.target' 'composefs-setup-root.service'
}
10 changes: 10 additions & 0 deletions examples/bootc-uki/Containerfile.stage1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM quay.io/fedora/fedora-bootc:42
COPY extra /
COPY cfsctl /usr/bin

RUN passwd -d root

# need to have composefs setup root in the initramfs so we need this
RUN set -x; \
kver=$(cd /usr/lib/modules && echo *); \
dracut -vf --install "/etc/passwd /etc/group" /usr/lib/modules/$kver/initramfs.img $kver;
46 changes: 46 additions & 0 deletions examples/bootc-uki/Containerfile.stage2
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
FROM quay.io/fedora/fedora-bootc-base-uki:42 AS base

FROM base as kernel

ARG COMPOSEFS_FSVERITY

RUN --mount=type=secret,id=key \
--mount=type=secret,id=cert <<EOF
set -eux

mkdir -p /etc/kernel /etc/dracut.conf.d
echo "console=ttyS0,115200 composefs=${COMPOSEFS_FSVERITY} selinux=1 enforcing=0 systemd.debug_shell=1 root=UUID=6523f8ae-3eb1-4e2a-a05a-18b695ae656f rw" > /etc/kernel/cmdline

dnf install -y systemd-ukify sbsigntools systemd-boot-unsigned
kver=$(cd /usr/lib/modules && echo *)
ukify build \
--linux "/usr/lib/modules/$kver/vmlinuz" \
--initrd "/usr/lib/modules/$kver/initramfs.img" \
--uname="${kver}" \
--cmdline "@/etc/kernel/cmdline" \
--os-release "@/etc/os-release" \
--signtool sbsign \
--secureboot-private-key "/run/secrets/key" \
--secureboot-certificate "/run/secrets/cert" \
--measure \
--json pretty \
--output "/boot/$kver.efi"
sbsign \
--key "/run/secrets/key" \
--cert "/run/secrets/cert" \
"/usr/lib/systemd/boot/efi/systemd-bootx64.efi" \
--output "/boot/systemd-bootx64.efi"
EOF

FROM base as final

RUN --mount=type=bind,from=kernel,target=/_mount/kernel <<EOF
kver=$(cd /usr/lib/modules && echo *)
mkdir -p /boot/EFI/Linux
# We put the UKI in /boot for now due to composefs verity not being the
# same due to mtime of /usr/lib/modules being changed
cp /_mount/kernel/boot/$kver.efi /boot/EFI/Linux/$kver.efi
EOF

FROM base as final-final
COPY --from=final /boot /boot
18 changes: 18 additions & 0 deletions examples/bootc-uki/build.base
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

set -eux

cd "${0%/*}"

cargo build --release --features=pre-6.15 --bin cfsctl --bin composefs-setup-root

cp ../../target/release/cfsctl .
cp ../../target/release/composefs-setup-root extra/usr/lib/dracut/modules.d/37composefs/

mkdir -p tmp

sudo podman build \
-t quay.io/fedora/fedora-bootc-base-uki:42 \
-f Containerfile.stage1 \
--iidfile=tmp/iid \
.
47 changes: 47 additions & 0 deletions examples/bootc-uki/build.final
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/bash

set -eux

cd "${0%/*}"

cargo build --release --features=pre-6.15 --bin cfsctl --bin composefs-setup-root

cp ../../target/release/cfsctl .

rm -rf tmp/sysroot
mkdir -p tmp/sysroot/composefs

IMAGE_ID="$(sed s/sha256:// tmp/iid)"
./cfsctl --repo tmp/sysroot/composefs oci pull containers-storage:"${IMAGE_ID}"
COMPOSEFS_FSVERITY="$(./cfsctl --repo tmp/sysroot/composefs oci compute-id --bootable "${IMAGE_ID}")"

# See: https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot
# Alternative to generate keys for testing: `sbctl create-keys`
if [[ ! -d "secureboot" ]]; then
echo "Generating test Secure Boot keys"
mkdir secureboot
pushd secureboot > /dev/null
uuidgen --random > GUID.txt
openssl req -newkey rsa:4096 -nodes -keyout PK.key -new -x509 -sha256 -days 3650 -subj "/CN=Test Platform Key/" -out PK.crt
openssl x509 -outform DER -in PK.crt -out PK.cer
openssl req -newkey rsa:4096 -nodes -keyout KEK.key -new -x509 -sha256 -days 3650 -subj "/CN=Test Key Exchange Key/" -out KEK.crt
openssl x509 -outform DER -in KEK.crt -out KEK.cer
openssl req -newkey rsa:4096 -nodes -keyout db.key -new -x509 -sha256 -days 3650 -subj "/CN=Test Signature Database key/" -out db.crt
openssl x509 -outform DER -in db.crt -out db.cer
popd > /dev/null
fi

# For debugging, add --no-cache to podman command
sudo podman build \
-t quay.io/fedora/fedora-bootc-uki:42 \
--build-arg=COMPOSEFS_FSVERITY="${COMPOSEFS_FSVERITY}" \
-f Containerfile.stage2 \
--secret=id=key,src=secureboot/db.key \
--secret=id=cert,src=secureboot/db.crt \
--iidfile=tmp/iid2

rm -rf tmp/efi
mkdir -p tmp/efi
./cfsctl --repo tmp/sysroot/composefs oci pull containers-storage:"${IMAGE_ID}"
./cfsctl --repo tmp/sysroot/composefs oci compute-id --bootable "${IMAGE_ID}"
./cfsctl --repo tmp/sysroot/composefs oci prepare-boot "${IMAGE_ID}" --bootdir tmp/efi
20 changes: 20 additions & 0 deletions examples/bootc-uki/build_vars
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

set -eux

cd "${0%/*}"

if [[ ! -d "secureboot" ]]; then
echo "fail"
exit 1
fi

# See: https://github.com/rhuefi/qemu-ovmf-secureboot
# $ dnf install -y python3-virt-firmware
GUID=$(cat secureboot/GUID.txt)
virt-fw-vars --input "/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2" \
--secure-boot \
--set-pk $GUID "secureboot/PK.crt" \
--add-kek $GUID "secureboot/KEK.crt" \
--add-db $GUID "secureboot/db.crt" \
-o "VARS_CUSTOM.secboot.qcow2.template"
1 change: 1 addition & 0 deletions examples/bootc-uki/extra/etc/dracut.conf.d/no-xattr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export DRACUT_NO_XATTR=1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# we want to make sure the virtio disk drivers get included
hostonly=no

# we need to force these in via the initramfs because we don't have modules in
# the base image
force_drivers+=" virtio_net vfat "
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright (C) 2013 Colin Walters <[email protected]>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <https://www.gnu.org/licenses/>.

[Unit]
DefaultDependencies=no
ConditionKernelCommandLine=composefs
ConditionPathExists=/etc/initrd-release
After=sysroot.mount
Requires=sysroot.mount
Before=initrd-root-fs.target
Before=initrd-switch-root.target

OnFailure=emergency.target
OnFailureJobMode=isolate

[Service]
Type=oneshot
ExecStart=/usr/bin/composefs-setup-root
StandardInput=null
StandardOutput=journal
StandardError=journal+console
RemainAfterExit=yes
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/bash

check() {
return 0
}

depends() {
return 0
}

install() {
inst \
"${moddir}/composefs-setup-root" /usr/bin/composefs-setup-root
inst \
"${moddir}/composefs-setup-root.service" \
"${systemdsystemunitdir}/composefs-setup-root.service"

$SYSTEMCTL -q --root "${initdir}" add-wants \
'initrd-root-fs.target' 'composefs-setup-root.service'
}
29 changes: 29 additions & 0 deletions examples/bootc-uki/install-grub.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

set -eux

curl http://192.168.122.1:8000/bootc -o bootc
chmod +x bootc

IMAGE=quay.io/fedora/fedora-bootc-uki:42

# --env RUST_LOG=debug \
# --env RUST_BACKTRACE=1 \
podman run \
--rm --privileged \
--pid=host \
-v /dev:/dev \
-v /var/lib/containers:/var/lib/containers \
-v /srv/bootc:/usr/bin/bootc:ro,Z \
-v /var/tmp:/var/tmp \
--security-opt label=type:unconfined_t \
"${IMAGE}" \
bootc install to-disk \
--composefs-native \
--boot=uki \
--source-imgref="containers-storage:${IMAGE}" \
--target-imgref="${IMAGE}" \
--target-transport="docker" \
/dev/vdb \
--filesystem=ext4 \
--wipe
45 changes: 45 additions & 0 deletions examples/bootc-uki/install-systemd-boot.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/bash

set -eux

curl http://192.168.122.1:8000/bootc -o bootc
chmod +x bootc

IMAGE=quay.io/fedora/fedora-bootc-uki:42

if [[ ! -f /srv/systemd-bootx64.efi ]]; then
echo "Needs /srv/systemd-bootx64.efi to exists for now"
exit 1
fi

# --env RUST_LOG=debug \
# --env RUST_BACKTRACE=1 \
podman run \
--rm --privileged \
--pid=host \
-v /dev:/dev \
-v /var/lib/containers:/var/lib/containers \
-v /srv/bootc:/usr/bin/bootc:ro,Z \
-v /var/tmp:/var/tmp \
--security-opt label=type:unconfined_t \
"${IMAGE}" \
bootc install to-disk \
--composefs-native \
--boot=uki \
--source-imgref="containers-storage:${IMAGE}" \
--target-imgref="${IMAGE}" \
--target-transport="docker" \
/dev/vdb \
--filesystem=ext4 \
--wipe

mkdir -p efi
mount /dev/vdb2 /srv/efi

# Manual systemd-boot installation
cp /srv/systemd-bootx64.efi /srv/efi/EFI/fedora/grubx64.efi
mkdir -p /srv/efi/loader
echo "timeout 5" > /srv/efi/loader/loader.conf
rm -rf /srv/efi/EFI/fedora/grub.cfg

umount efi
Loading