diff --git a/examples/bootc-bls/Containerfile b/examples/bootc-bls/Containerfile new file mode 100644 index 00000000..c6fbfcdb --- /dev/null +++ b/examples/bootc-bls/Containerfile @@ -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; diff --git a/examples/bootc-bls/build b/examples/bootc-bls/build new file mode 100755 index 00000000..3e3ec090 --- /dev/null +++ b/examples/bootc-bls/build @@ -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 \ diff --git a/examples/bootc-bls/extra/etc/dracut.conf.d/no-xattr.conf b/examples/bootc-bls/extra/etc/dracut.conf.d/no-xattr.conf new file mode 100644 index 00000000..b8d114a9 --- /dev/null +++ b/examples/bootc-bls/extra/etc/dracut.conf.d/no-xattr.conf @@ -0,0 +1 @@ +export DRACUT_NO_XATTR=1 diff --git a/examples/bootc-bls/extra/usr/lib/dracut/dracut.conf.d/37composefs.conf b/examples/bootc-bls/extra/usr/lib/dracut/dracut.conf.d/37composefs.conf new file mode 100644 index 00000000..1defe5de --- /dev/null +++ b/examples/bootc-bls/extra/usr/lib/dracut/dracut.conf.d/37composefs.conf @@ -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 " diff --git a/examples/bootc-bls/extra/usr/lib/dracut/modules.d/37composefs/composefs-setup-root.service b/examples/bootc-bls/extra/usr/lib/dracut/modules.d/37composefs/composefs-setup-root.service new file mode 100644 index 00000000..ffc404d6 --- /dev/null +++ b/examples/bootc-bls/extra/usr/lib/dracut/modules.d/37composefs/composefs-setup-root.service @@ -0,0 +1,34 @@ +# Copyright (C) 2013 Colin Walters +# +# 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 . + +[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 diff --git a/examples/bootc-bls/extra/usr/lib/dracut/modules.d/37composefs/module-setup.sh b/examples/bootc-bls/extra/usr/lib/dracut/modules.d/37composefs/module-setup.sh new file mode 100755 index 00000000..7fb85303 --- /dev/null +++ b/examples/bootc-bls/extra/usr/lib/dracut/modules.d/37composefs/module-setup.sh @@ -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' +} diff --git a/examples/bootc-uki/Containerfile.stage1 b/examples/bootc-uki/Containerfile.stage1 new file mode 100644 index 00000000..c6fbfcdb --- /dev/null +++ b/examples/bootc-uki/Containerfile.stage1 @@ -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; diff --git a/examples/bootc-uki/Containerfile.stage2 b/examples/bootc-uki/Containerfile.stage2 new file mode 100644 index 00000000..964a6f2a --- /dev/null +++ b/examples/bootc-uki/Containerfile.stage2 @@ -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 < /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 < /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 diff --git a/examples/bootc-uki/build_vars b/examples/bootc-uki/build_vars new file mode 100755 index 00000000..8008414b --- /dev/null +++ b/examples/bootc-uki/build_vars @@ -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" diff --git a/examples/bootc-uki/extra/etc/dracut.conf.d/no-xattr.conf b/examples/bootc-uki/extra/etc/dracut.conf.d/no-xattr.conf new file mode 100644 index 00000000..b8d114a9 --- /dev/null +++ b/examples/bootc-uki/extra/etc/dracut.conf.d/no-xattr.conf @@ -0,0 +1 @@ +export DRACUT_NO_XATTR=1 diff --git a/examples/bootc-uki/extra/usr/lib/dracut/dracut.conf.d/37composefs.conf b/examples/bootc-uki/extra/usr/lib/dracut/dracut.conf.d/37composefs.conf new file mode 100644 index 00000000..1defe5de --- /dev/null +++ b/examples/bootc-uki/extra/usr/lib/dracut/dracut.conf.d/37composefs.conf @@ -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 " diff --git a/examples/bootc-uki/extra/usr/lib/dracut/modules.d/37composefs/composefs-setup-root.service b/examples/bootc-uki/extra/usr/lib/dracut/modules.d/37composefs/composefs-setup-root.service new file mode 100644 index 00000000..ffc404d6 --- /dev/null +++ b/examples/bootc-uki/extra/usr/lib/dracut/modules.d/37composefs/composefs-setup-root.service @@ -0,0 +1,34 @@ +# Copyright (C) 2013 Colin Walters +# +# 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 . + +[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 diff --git a/examples/bootc-uki/extra/usr/lib/dracut/modules.d/37composefs/module-setup.sh b/examples/bootc-uki/extra/usr/lib/dracut/modules.d/37composefs/module-setup.sh new file mode 100755 index 00000000..7fb85303 --- /dev/null +++ b/examples/bootc-uki/extra/usr/lib/dracut/modules.d/37composefs/module-setup.sh @@ -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' +} diff --git a/examples/bootc-uki/install-grub.sh b/examples/bootc-uki/install-grub.sh new file mode 100755 index 00000000..88582604 --- /dev/null +++ b/examples/bootc-uki/install-grub.sh @@ -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 diff --git a/examples/bootc-uki/install-systemd-boot.sh b/examples/bootc-uki/install-systemd-boot.sh new file mode 100755 index 00000000..08e92107 --- /dev/null +++ b/examples/bootc-uki/install-systemd-boot.sh @@ -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