mirror of
https://github.com/containers/bootc.git
synced 2026-02-05 15:45:53 +01:00
Rework sealed build process
Main goal is to reduce signing logic duplication between the systemd-boot and UKI generation. However, this quickly snowballed into wanting to actually verify by providing a custom secure boot keys to bcvk that things worked. This depends on https://github.com/bootc-dev/bcvk/pull/170 Now as part of that, I ran into what I think are bugs in pesign; this cuts things back over to using sbsign. I'll file a tracker for that separately. Finally as part of this, just remove the TMT example that builds a sealed image but doesn't actually verify it works - it's already drifted from what we do outside here. Ultimately what we need is to shift some of this into the Fedora examples and we just fetch it here anyways. Assisted-by: Claude Code (Sonnet 4.5) Signed-off-by: Colin Walters <walters@verbum.org>
This commit is contained in:
17
.github/actions/bootc-ubuntu-setup/action.yml
vendored
17
.github/actions/bootc-ubuntu-setup/action.yml
vendored
@@ -65,19 +65,24 @@ runs:
|
|||||||
- name: Install libvirt and virtualization stack
|
- name: Install libvirt and virtualization stack
|
||||||
if: ${{ inputs.libvirt == 'true' }}
|
if: ${{ inputs.libvirt == 'true' }}
|
||||||
shell: bash
|
shell: bash
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
run: |
|
run: |
|
||||||
set -xeuo pipefail
|
set -xeuo pipefail
|
||||||
export BCVK_VERSION=0.8.0
|
export BCVK_VERSION=0.8.0
|
||||||
/bin/time -f '%E %C' sudo apt install -y libkrb5-dev pkg-config libvirt-dev genisoimage qemu-utils qemu-kvm virtiofsd libvirt-daemon-system
|
/bin/time -f '%E %C' sudo apt install -y libkrb5-dev pkg-config libvirt-dev genisoimage qemu-utils qemu-kvm virtiofsd libvirt-daemon-system python3-virt-firmware
|
||||||
# Something in the stack is overriding this, but we want session right now for bcvk
|
# Something in the stack is overriding this, but we want session right now for bcvk
|
||||||
echo LIBVIRT_DEFAULT_URI=qemu:///session >> $GITHUB_ENV
|
echo LIBVIRT_DEFAULT_URI=qemu:///session >> $GITHUB_ENV
|
||||||
td=$(mktemp -d)
|
td=$(mktemp -d)
|
||||||
cd $td
|
cd $td
|
||||||
# Install bcvk
|
# Install bcvk from PR 172
|
||||||
target=bcvk-$(arch)-unknown-linux-gnu
|
gh run download 20107212783 --name bcvk-binary-tests --repo bootc-dev/bcvk
|
||||||
/bin/time -f '%E %C' curl -LO https://github.com/bootc-dev/bcvk/releases/download/v${BCVK_VERSION}/${target}.tar.gz
|
sudo install -m 755 bcvk /usr/bin/bcvk
|
||||||
tar xzf ${target}.tar.gz
|
# Install bcvk from release
|
||||||
sudo install -T ${target} /usr/bin/bcvk
|
# target=bcvk-$(arch)-unknown-linux-gnu
|
||||||
|
# /bin/time -f '%E %C' curl -LO https://github.com/bootc-dev/bcvk/releases/download/v${BCVK_VERSION}/${target}.tar.gz
|
||||||
|
# tar xzf ${target}.tar.gz
|
||||||
|
# sudo install -T ${target} /usr/bin/bcvk
|
||||||
cd -
|
cd -
|
||||||
rm -rf "$td"
|
rm -rf "$td"
|
||||||
|
|
||||||
|
|||||||
21
Dockerfile
21
Dockerfile
@@ -41,12 +41,28 @@ WORKDIR /src
|
|||||||
# First we download all of our Rust dependencies
|
# First we download all of our Rust dependencies
|
||||||
RUN --mount=type=cache,target=/src/target --mount=type=cache,target=/var/roothome cargo fetch
|
RUN --mount=type=cache,target=/src/target --mount=type=cache,target=/var/roothome cargo fetch
|
||||||
|
|
||||||
|
FROM buildroot as sdboot-content
|
||||||
|
# Writes to /out
|
||||||
|
RUN /src/contrib/packaging/configure-systemdboot download
|
||||||
|
|
||||||
|
# NOTE: Every RUN instruction past this point should use `--network=none`; we want to ensure
|
||||||
|
# all external dependencies are clearly delineated.
|
||||||
|
|
||||||
FROM buildroot as build
|
FROM buildroot as build
|
||||||
# Version for RPM build (optional, computed from git in Justfile)
|
# Version for RPM build (optional, computed from git in Justfile)
|
||||||
ARG pkgversion
|
ARG pkgversion
|
||||||
# Build RPM directly from source, using cached target directory
|
# Build RPM directly from source, using cached target directory
|
||||||
RUN --mount=type=cache,target=/src/target --mount=type=cache,target=/var/roothome --network=none RPM_VERSION="${pkgversion}" /src/contrib/packaging/build-rpm
|
RUN --mount=type=cache,target=/src/target --mount=type=cache,target=/var/roothome --network=none RPM_VERSION="${pkgversion}" /src/contrib/packaging/build-rpm
|
||||||
|
|
||||||
|
FROM buildroot as sdboot-signed
|
||||||
|
# The secureboot key and cert are passed via Justfile
|
||||||
|
# We write the signed binary into /out
|
||||||
|
RUN --network=none \
|
||||||
|
--mount=type=bind,from=sdboot-content,target=/run/sdboot-package \
|
||||||
|
--mount=type=secret,id=secureboot_key \
|
||||||
|
--mount=type=secret,id=secureboot_cert \
|
||||||
|
/src/contrib/packaging/configure-systemdboot sign
|
||||||
|
|
||||||
# This "build" includes our unit tests
|
# This "build" includes our unit tests
|
||||||
FROM build as units
|
FROM build as units
|
||||||
# A place that we're more likely to be able to set xattrs
|
# A place that we're more likely to be able to set xattrs
|
||||||
@@ -62,7 +78,10 @@ RUN --mount=type=cache,target=/src/target --mount=type=cache,target=/var/roothom
|
|||||||
FROM base
|
FROM base
|
||||||
# See the Justfile for possible variants
|
# See the Justfile for possible variants
|
||||||
ARG variant
|
ARG variant
|
||||||
RUN --mount=type=bind,from=packaging,target=/run/packaging /run/packaging/configure-variant "${variant}"
|
RUN --network=none --mount=type=bind,from=packaging,target=/run/packaging \
|
||||||
|
--mount=type=bind,from=sdboot-content,target=/run/sdboot-content \
|
||||||
|
--mount=type=bind,from=sdboot-signed,target=/run/sdboot-signed \
|
||||||
|
/run/packaging/configure-variant "${variant}"
|
||||||
# Support overriding the rootfs at build time conveniently
|
# Support overriding the rootfs at build time conveniently
|
||||||
ARG rootfs
|
ARG rootfs
|
||||||
RUN --mount=type=bind,from=packaging,target=/run/packaging /run/packaging/configure-rootfs "${variant}" "${rootfs}"
|
RUN --mount=type=bind,from=packaging,target=/run/packaging /run/packaging/configure-rootfs "${variant}" "${rootfs}"
|
||||||
|
|||||||
@@ -1,27 +1,25 @@
|
|||||||
# Override via --build-arg=base=<image> to use a different base
|
# Override via --build-arg=base=<image> to use a different base
|
||||||
ARG base=localhost/bootc
|
ARG base=localhost/bootc
|
||||||
# This is where we get the tools to build the UKI
|
|
||||||
ARG buildroot=quay.io/centos/centos:stream10
|
|
||||||
|
|
||||||
FROM $base AS base
|
FROM $base AS base
|
||||||
|
|
||||||
FROM $buildroot as buildroot-base
|
FROM base as kernel
|
||||||
RUN <<EORUN
|
RUN <<EORUN
|
||||||
set -xeuo pipefail
|
set -xeuo pipefail
|
||||||
|
. /usr/lib/os-release
|
||||||
# systemd-udev is required for /usr/lib/systemd/systemd-measure which
|
case $ID in
|
||||||
# is used by ukify as invoked with the `--measure` flag below. Not
|
centos|rhel)
|
||||||
# strictly required, but nice to have the measured PCR values in the
|
dnf config-manager --set-enabled crb
|
||||||
# output.
|
# Enable EPEL for sbsigntools
|
||||||
dnf install -y systemd-ukify systemd-udev pesign openssl
|
dnf -y install epel-release
|
||||||
dnf clean all
|
;;
|
||||||
|
esac
|
||||||
|
dnf -y install systemd-ukify sbsigntools
|
||||||
EORUN
|
EORUN
|
||||||
|
|
||||||
FROM buildroot-base as kernel
|
|
||||||
# Must be passed
|
# Must be passed
|
||||||
ARG COMPOSEFS_FSVERITY
|
ARG COMPOSEFS_FSVERITY
|
||||||
RUN --mount=type=secret,id=key \
|
RUN --network=none \
|
||||||
--mount=type=secret,id=cert \
|
--mount=type=secret,id=secureboot_key \
|
||||||
|
--mount=type=secret,id=secureboot_cert \
|
||||||
--mount=type=bind,from=base,target=/target \
|
--mount=type=bind,from=base,target=/target \
|
||||||
<<EOF
|
<<EOF
|
||||||
set -xeuo pipefail
|
set -xeuo pipefail
|
||||||
@@ -31,13 +29,7 @@ RUN --mount=type=secret,id=key \
|
|||||||
|
|
||||||
cmdline="composefs=${COMPOSEFS_FSVERITY} console=ttyS0,115200n8 console=hvc0 enforcing=0 rw"
|
cmdline="composefs=${COMPOSEFS_FSVERITY} console=ttyS0,115200n8 console=hvc0 enforcing=0 rw"
|
||||||
|
|
||||||
# pesign uses NSS database so create it from input cert/key
|
# Use sbsign to re-sign the entire UKI with our key
|
||||||
mkdir pesign
|
|
||||||
certutil -N -d pesign --empty-password
|
|
||||||
openssl pkcs12 -export -password 'pass:' -inkey /run/secrets/key -in /run/secrets/cert -out db.p12
|
|
||||||
pk12util -i db.p12 -W '' -d pesign
|
|
||||||
subject=$(openssl x509 -in /run/secrets/cert -subject | grep '^subject=CN=' | sed 's/^subject=CN=//')
|
|
||||||
|
|
||||||
kver=$(cd /target/usr/lib/modules && echo *)
|
kver=$(cd /target/usr/lib/modules && echo *)
|
||||||
ukify build \
|
ukify build \
|
||||||
--linux "/target/usr/lib/modules/$kver/vmlinuz" \
|
--linux "/target/usr/lib/modules/$kver/vmlinuz" \
|
||||||
@@ -45,16 +37,16 @@ RUN --mount=type=secret,id=key \
|
|||||||
--uname="${kver}" \
|
--uname="${kver}" \
|
||||||
--cmdline "${cmdline}" \
|
--cmdline "${cmdline}" \
|
||||||
--os-release "@/target/usr/lib/os-release" \
|
--os-release "@/target/usr/lib/os-release" \
|
||||||
--signtool pesign \
|
--signtool sbsign \
|
||||||
--secureboot-certificate-dir "pesign" \
|
--secureboot-private-key "/run/secrets/secureboot_key" \
|
||||||
--secureboot-certificate-name "${subject}" \
|
--secureboot-certificate "/run/secrets/secureboot_cert" \
|
||||||
--measure \
|
--measure \
|
||||||
--json pretty \
|
--json pretty \
|
||||||
--output "/boot/$kver.efi"
|
--output "/boot/$kver.efi"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
FROM base as final
|
FROM base as final
|
||||||
RUN --mount=type=bind,from=kernel,target=/run/kernel <<EOF
|
RUN --network=none --mount=type=bind,from=kernel,target=/run/kernel <<EOF
|
||||||
set -xeuo pipefail
|
set -xeuo pipefail
|
||||||
kver=$(cd /usr/lib/modules && echo *)
|
kver=$(cd /usr/lib/modules && echo *)
|
||||||
mkdir -p /boot/EFI/Linux
|
mkdir -p /boot/EFI/Linux
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
# Override via --build-arg=base=<image> to use a different base
|
|
||||||
ARG base=localhost/bootc
|
|
||||||
# Image to sign systemd-boot first, BEFORE, installing onto the image
|
|
||||||
ARG buildroot=quay.io/centos/centos:stream10
|
|
||||||
|
|
||||||
FROM $base AS base-unsigned
|
|
||||||
|
|
||||||
FROM $buildroot as buildroot-base
|
|
||||||
RUN <<EORUN
|
|
||||||
set -xeuo pipefail
|
|
||||||
dnf install -y pesign openssl
|
|
||||||
dnf clean all
|
|
||||||
EORUN
|
|
||||||
|
|
||||||
|
|
||||||
FROM buildroot-base as signer
|
|
||||||
# Sign sdboot and put it on the target first
|
|
||||||
RUN --mount=type=secret,id=key \
|
|
||||||
--mount=type=secret,id=cert \
|
|
||||||
--mount=type=bind,from=base-unsigned,target=/target \
|
|
||||||
<<EORUN
|
|
||||||
set -xeuo pipefail
|
|
||||||
|
|
||||||
# pesign uses NSS database so create it from input cert/key
|
|
||||||
mkdir pesign
|
|
||||||
certutil -N -d pesign --empty-password
|
|
||||||
openssl pkcs12 -export -password 'pass:' -inkey /run/secrets/key -in /run/secrets/cert -out db.p12
|
|
||||||
pk12util -i db.p12 -W '' -d pesign
|
|
||||||
subject=$(openssl x509 -in /run/secrets/cert -subject | grep '^subject=CN=' | sed 's/^subject=CN=//')
|
|
||||||
|
|
||||||
# Sign systemd-boot as well
|
|
||||||
sdboot="target/usr/lib/systemd/boot/efi/systemd-bootx64.efi"
|
|
||||||
sdboot_out="/sdboot.efi"
|
|
||||||
pesign \
|
|
||||||
--certdir "pesign" \
|
|
||||||
--certificate "${subject}" \
|
|
||||||
--in "${sdboot}" \
|
|
||||||
--out "${sdboot_out}" \
|
|
||||||
--sign
|
|
||||||
EORUN
|
|
||||||
|
|
||||||
|
|
||||||
FROM base-unsigned as final
|
|
||||||
RUN --mount=type=bind,from=signer,target=/run/sdboot \
|
|
||||||
<<EORUN
|
|
||||||
set -xeuo pipefail
|
|
||||||
sdboot=/usr/lib/systemd/boot/efi/systemd-bootx64.efi
|
|
||||||
# copy signed sdboot from buildroot
|
|
||||||
cp "/run/sdboot/sdboot.efi" ${sdboot}
|
|
||||||
EORUN
|
|
||||||
52
Justfile
52
Justfile
@@ -25,6 +25,8 @@ base := env("BOOTC_base", "quay.io/centos-bootc/centos-bootc:stream10")
|
|||||||
buildroot_base := env("BOOTC_buildroot_base", "quay.io/centos/centos:stream10")
|
buildroot_base := env("BOOTC_buildroot_base", "quay.io/centos/centos:stream10")
|
||||||
|
|
||||||
testimage_label := "bootc.testimage=1"
|
testimage_label := "bootc.testimage=1"
|
||||||
|
# Images used by hack/lbi; keep in sync
|
||||||
|
lbi_images := "quay.io/curl/curl:latest quay.io/curl/curl-base:latest registry.access.redhat.com/ubi9/podman:latest"
|
||||||
# We used to have --jobs=4 here but sometimes that'd hit this
|
# We used to have --jobs=4 here but sometimes that'd hit this
|
||||||
# ```
|
# ```
|
||||||
# [2/3] STEP 2/2: RUN --mount=type=bind,from=context,target=/run/context <<EORUN (set -xeuo pipefail...)
|
# [2/3] STEP 2/2: RUN --mount=type=bind,from=context,target=/run/context <<EORUN (set -xeuo pipefail...)
|
||||||
@@ -34,21 +36,23 @@ testimage_label := "bootc.testimage=1"
|
|||||||
# /bin/sh: line 3: cd: /run/context/: Permission denied
|
# /bin/sh: line 3: cd: /run/context/: Permission denied
|
||||||
# ```
|
# ```
|
||||||
# TODO: Gather more info and file a buildah bug
|
# TODO: Gather more info and file a buildah bug
|
||||||
base_buildargs := ""
|
generic_buildargs := ""
|
||||||
buildargs := "--build-arg=base=" + base + " --build-arg=variant=" + variant
|
# Args for package building (no secrets needed, just builds RPMs)
|
||||||
|
base_buildargs := generic_buildargs + " --build-arg=base=" + base + " --build-arg=variant=" + variant
|
||||||
|
buildargs := base_buildargs + " --secret=id=secureboot_key,src=target/test-secureboot/db.key --secret=id=secureboot_cert,src=target/test-secureboot/db.crt"
|
||||||
|
# Args for build-sealed (no base arg, it sets that itself)
|
||||||
|
sealed_buildargs := "--build-arg=variant=" + variant + " --secret=id=secureboot_key,src=target/test-secureboot/db.key --secret=id=secureboot_cert,src=target/test-secureboot/db.crt"
|
||||||
|
|
||||||
# Build the container image from current sources.
|
# The default target: build the container image from current sources.
|
||||||
# Note commonly you might want to override the base image via e.g.
|
# Note commonly you might want to override the base image via e.g.
|
||||||
# `just build --build-arg=base=quay.io/fedora/fedora-bootc:42`
|
# `just build --build-arg=base=quay.io/fedora/fedora-bootc:42`
|
||||||
build: package
|
build: package _keygen
|
||||||
podman build {{base_buildargs}} -t {{base_img}}-bin {{buildargs}} .
|
podman build {{base_buildargs}} -t {{base_img}}-bin {{buildargs}} .
|
||||||
./tests/build-sealed {{variant}} {{base_img}}-bin {{base_img}} {{buildroot_base}}
|
./hack/build-sealed {{variant}} {{base_img}}-bin {{base_img}} {{sealed_buildargs}}
|
||||||
|
|
||||||
# Build the container image using pre-existing packages from PATH
|
# Generate Secure Boot keys (only for our own CI/testing)
|
||||||
build-from-package PATH:
|
_keygen:
|
||||||
# @just copy-packages-from {{PATH}}
|
./hack/generate-secureboot-keys
|
||||||
podman build {{base_buildargs}} -t {{base_img}}-bin {{buildargs}} .
|
|
||||||
./tests/build-sealed {{variant}} {{base_img}}-bin {{base_img}} {{buildroot_base}}
|
|
||||||
|
|
||||||
# Build a sealed image from current sources.
|
# Build a sealed image from current sources.
|
||||||
build-sealed:
|
build-sealed:
|
||||||
@@ -69,7 +73,7 @@ _packagecontainer:
|
|||||||
VERSION="${TIMESTAMP}.g${COMMIT}"
|
VERSION="${TIMESTAMP}.g${COMMIT}"
|
||||||
fi
|
fi
|
||||||
echo "Building RPM with version: ${VERSION}"
|
echo "Building RPM with version: ${VERSION}"
|
||||||
podman build {{base_buildargs}} {{buildargs}} --build-arg=pkgversion=${VERSION} -t localhost/bootc-pkg --target=build .
|
podman build {{base_buildargs}} --build-arg=pkgversion=${VERSION} -t localhost/bootc-pkg --target=build .
|
||||||
|
|
||||||
# Build packages (e.g. RPM) into target/packages/
|
# Build packages (e.g. RPM) into target/packages/
|
||||||
# Any old packages will be removed.
|
# Any old packages will be removed.
|
||||||
@@ -96,20 +100,28 @@ copy-packages-from PATH:
|
|||||||
chmod a+rx target target/packages
|
chmod a+rx target target/packages
|
||||||
chmod a+r target/packages/*.rpm
|
chmod a+r target/packages/*.rpm
|
||||||
|
|
||||||
|
# Build the container image using pre-existing packages from PATH
|
||||||
|
# Note: The Dockerfile reads from target/packages/, so copy the packages there first
|
||||||
|
# if they're in a different location.
|
||||||
|
build-from-package PATH: _keygen
|
||||||
|
@if [ "{{PATH}}" != "target/packages" ]; then just copy-packages-from {{PATH}}; fi
|
||||||
|
podman build {{base_buildargs}} -t {{base_img}}-bin {{buildargs}} .
|
||||||
|
./hack/build-sealed {{variant}} {{base_img}}-bin {{base_img}} {{sealed_buildargs}}
|
||||||
|
|
||||||
|
# Pull images used by hack/lbi
|
||||||
|
_pull-lbi-images:
|
||||||
|
podman pull -q --retry 5 --retry-delay 5s {{lbi_images}}
|
||||||
|
|
||||||
# This container image has additional testing content and utilities
|
# This container image has additional testing content and utilities
|
||||||
build-integration-test-image: build
|
build-integration-test-image: build _pull-lbi-images
|
||||||
cd hack && podman build {{base_buildargs}} -t {{integration_img}}-bin -f Containerfile .
|
cd hack && podman build {{base_buildargs}} -t {{integration_img}}-bin -f Containerfile .
|
||||||
./tests/build-sealed {{variant}} {{integration_img}}-bin {{integration_img}} {{buildroot_base}}
|
./hack/build-sealed {{variant}} {{integration_img}}-bin {{integration_img}} {{sealed_buildargs}}
|
||||||
# Keep these in sync with what's used in hack/lbi
|
|
||||||
podman pull -q --retry 5 --retry-delay 5s quay.io/curl/curl:latest quay.io/curl/curl-base:latest registry.access.redhat.com/ubi9/podman:latest
|
|
||||||
|
|
||||||
# Build integration test image using pre-existing packages from PATH
|
# Build integration test image using pre-existing packages from PATH
|
||||||
build-integration-test-image-from-package PATH:
|
build-integration-test-image-from-package PATH: _pull-lbi-images
|
||||||
@just build-from-package {{PATH}}
|
@just build-from-package {{PATH}}
|
||||||
cd hack && podman build {{base_buildargs}} -t {{integration_img}}-bin -f Containerfile .
|
cd hack && podman build {{base_buildargs}} -t {{integration_img}}-bin -f Containerfile .
|
||||||
./tests/build-sealed {{variant}} {{integration_img}}-bin {{integration_img}} {{buildroot_base}}
|
./hack/build-sealed {{variant}} {{integration_img}}-bin {{integration_img}} {{sealed_buildargs}}
|
||||||
# Keep these in sync with what's used in hack/lbi
|
|
||||||
podman pull -q --retry 5 --retry-delay 5s quay.io/curl/curl:latest quay.io/curl/curl-base:latest registry.access.redhat.com/ubi9/podman:latest
|
|
||||||
|
|
||||||
# Build+test using the `composefs-sealeduki-sdboot` variant.
|
# Build+test using the `composefs-sealeduki-sdboot` variant.
|
||||||
test-composefs:
|
test-composefs:
|
||||||
@@ -146,7 +158,7 @@ test-tmt *ARGS: build-integration-test-image _build-upgrade-image
|
|||||||
# Generate a local synthetic upgrade
|
# Generate a local synthetic upgrade
|
||||||
_build-upgrade-image:
|
_build-upgrade-image:
|
||||||
cat tmt/tests/Dockerfile.upgrade | podman build -t {{integration_upgrade_img}}-bin --from={{integration_img}}-bin -
|
cat tmt/tests/Dockerfile.upgrade | podman build -t {{integration_upgrade_img}}-bin --from={{integration_img}}-bin -
|
||||||
./tests/build-sealed {{variant}} {{integration_upgrade_img}}-bin {{integration_upgrade_img}} {{buildroot_base}}
|
./hack/build-sealed {{variant}} {{integration_upgrade_img}}-bin {{integration_upgrade_img}} {{sealed_buildargs}}
|
||||||
|
|
||||||
# Assume the localhost/bootc-integration image is up to date, and just run tests.
|
# Assume the localhost/bootc-integration image is up to date, and just run tests.
|
||||||
# Useful for iterating on tests quickly.
|
# Useful for iterating on tests quickly.
|
||||||
|
|||||||
29
contrib/packaging/configure-systemdboot
Executable file
29
contrib/packaging/configure-systemdboot
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Helper for signing and re-injecting systemd-boot
|
||||||
|
set -euo pipefail
|
||||||
|
op=$1
|
||||||
|
shift
|
||||||
|
|
||||||
|
sdboot="usr/lib/systemd/boot/efi/systemd-bootx64.efi"
|
||||||
|
sdboot_bn=$(basename ${sdboot})
|
||||||
|
|
||||||
|
case $op in
|
||||||
|
download)
|
||||||
|
mkdir -p /out
|
||||||
|
cd /out
|
||||||
|
dnf -y download systemd-boot-unsigned
|
||||||
|
;;
|
||||||
|
sign)
|
||||||
|
mkdir -p /out
|
||||||
|
rpm -Uvh /run/sdboot-package/out/*.rpm
|
||||||
|
# Sign with sbsign using db certificate and key
|
||||||
|
sbsign \
|
||||||
|
--key /run/secrets/secureboot_key \
|
||||||
|
--cert /run/secrets/secureboot_cert \
|
||||||
|
--output /out/${sdboot_bn} \
|
||||||
|
/${sdboot}
|
||||||
|
ls -al /out/${sdboot_bn}
|
||||||
|
;;
|
||||||
|
*) echo "Unknown operation $op" 1>&2; exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
# Configure system for a specific bootc variant
|
# Configure system for a specific bootc variant
|
||||||
set -xeuo pipefail
|
set -xeuo pipefail
|
||||||
|
|
||||||
|
dn=$(dirname $0)
|
||||||
|
|
||||||
VARIANT="${1:-}"
|
VARIANT="${1:-}"
|
||||||
|
|
||||||
if [ -z "$VARIANT" ]; then
|
if [ -z "$VARIANT" ]; then
|
||||||
@@ -12,8 +14,14 @@ fi
|
|||||||
# Handle variant-specific configuration
|
# Handle variant-specific configuration
|
||||||
case "${VARIANT}" in
|
case "${VARIANT}" in
|
||||||
*-sdboot)
|
*-sdboot)
|
||||||
# Install systemd-boot and remove bootupd
|
# Install systemd-boot and remove bootupd;
|
||||||
dnf -y install systemd-boot-unsigned
|
# We downloaded this in an earlier phase
|
||||||
|
sdboot="usr/lib/systemd/boot/efi/systemd-bootx64.efi"
|
||||||
|
sdboot_bn=$(basename ${sdboot})
|
||||||
|
rpm -Uvh /run/sdboot-content/out/*.rpm
|
||||||
|
# And override with our signed binary
|
||||||
|
install -m 0644 /run/sdboot-signed/out/${sdboot_bn} /${sdboot}
|
||||||
|
|
||||||
# Uninstall bootupd
|
# Uninstall bootupd
|
||||||
rpm -e bootupd
|
rpm -e bootupd
|
||||||
rm -rf /usr/lib/bootupd/updates
|
rm -rf /usr/lib/bootupd/updates
|
||||||
|
|||||||
@@ -7,3 +7,5 @@ git-core
|
|||||||
jq
|
jq
|
||||||
# We now always build a package in the container build
|
# We now always build a package in the container build
|
||||||
rpm-build
|
rpm-build
|
||||||
|
# Used for signing
|
||||||
|
sbsigntools
|
||||||
|
|||||||
2
contrib/packaging/fedora-systemd-boot.txt
Normal file
2
contrib/packaging/fedora-systemd-boot.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# This file defines the package name for systemd-boot
|
||||||
|
systemd-boot-unsigned
|
||||||
@@ -4,7 +4,11 @@ set -xeuo pipefail
|
|||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
. /usr/lib/os-release
|
. /usr/lib/os-release
|
||||||
case $ID in
|
case $ID in
|
||||||
centos|rhel) dnf config-manager --set-enabled crb;;
|
centos|rhel)
|
||||||
|
dnf config-manager --set-enabled crb
|
||||||
|
# Enable EPEL for sbsigntools
|
||||||
|
dnf -y install epel-release
|
||||||
|
;;
|
||||||
fedora) dnf -y install dnf-utils 'dnf5-command(builddep)';;
|
fedora) dnf -y install dnf-utils 'dnf5-command(builddep)';;
|
||||||
esac
|
esac
|
||||||
# Handle version skew, xref https://gitlab.com/redhat/centos-stream/containers/bootc/-/issues/1174
|
# Handle version skew, xref https://gitlab.com/redhat/centos-stream/containers/bootc/-/issues/1174
|
||||||
|
|||||||
@@ -22,4 +22,4 @@ env DRACUT_NO_XATTR=1 dracut --add bootc -vf /usr/lib/modules/$kver/initramfs.im
|
|||||||
touch /usr/lib/.bootc-dev-stamp
|
touch /usr/lib/.bootc-dev-stamp
|
||||||
|
|
||||||
# Workaround for https://github.com/bootc-dev/bootc/issues/1546
|
# Workaround for https://github.com/bootc-dev/bootc/issues/1546
|
||||||
rm -rf /root/buildinfo
|
rm -rf /root/buildinfo /var/roothome/buildinfo
|
||||||
|
|||||||
@@ -14,11 +14,8 @@ const VM_READY_TIMEOUT_SECS: u64 = 60;
|
|||||||
const SSH_CONNECTIVITY_MAX_ATTEMPTS: u32 = 60;
|
const SSH_CONNECTIVITY_MAX_ATTEMPTS: u32 = 60;
|
||||||
const SSH_CONNECTIVITY_RETRY_DELAY_SECS: u64 = 3;
|
const SSH_CONNECTIVITY_RETRY_DELAY_SECS: u64 = 3;
|
||||||
|
|
||||||
const COMMON_INST_ARGS: &[&str] = &[
|
// Base args - firmware type will be added dynamically based on secure boot key availability
|
||||||
// TODO: Pass down the Secure Boot keys for tests if present
|
const COMMON_INST_ARGS: &[&str] = &["--label=bootc.test=1"];
|
||||||
"--firmware=uefi-insecure",
|
|
||||||
"--label=bootc.test=1",
|
|
||||||
];
|
|
||||||
|
|
||||||
// Metadata field names
|
// Metadata field names
|
||||||
const FIELD_TRY_BIND_STORAGE: &str = "try_bind_storage";
|
const FIELD_TRY_BIND_STORAGE: &str = "try_bind_storage";
|
||||||
@@ -95,6 +92,51 @@ fn detect_distro_from_image(sh: &Shell, image: &str) -> Result<String> {
|
|||||||
Ok(distro.to_string())
|
Ok(distro.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Detect if image is a sealed image by checking for /boot/EFI
|
||||||
|
/// Sealed images have EFI boot components, non-sealed images don't
|
||||||
|
/// TODO: Have `bootc container status` expose this in a nice way instead of running podman
|
||||||
|
#[context("Detecting if image is sealed")]
|
||||||
|
fn is_sealed_image(sh: &Shell, image: &str) -> Result<bool> {
|
||||||
|
let result = cmd!(sh, "podman run --rm {image} ls /boot").read()?;
|
||||||
|
Ok(!result.is_empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Default path where secure boot keys are generated for testing
|
||||||
|
const DEFAULT_SB_KEYS_DIR: &str = "target/test-secureboot";
|
||||||
|
|
||||||
|
/// Build firmware arguments for bcvk based on whether the image is sealed
|
||||||
|
/// and whether secure boot keys are available.
|
||||||
|
///
|
||||||
|
/// For sealed images, secure boot keys must be present or an error is returned.
|
||||||
|
#[context("Building firmware arguments")]
|
||||||
|
fn build_firmware_args(sh: &Shell, image: &str) -> Result<Vec<String>> {
|
||||||
|
let is_sealed = is_sealed_image(sh, image)?;
|
||||||
|
let sb_keys_dir = Utf8Path::new(DEFAULT_SB_KEYS_DIR);
|
||||||
|
|
||||||
|
let r = if is_sealed {
|
||||||
|
if sb_keys_dir.try_exists()? {
|
||||||
|
let sb_keys_dir = sb_keys_dir.canonicalize_utf8()?;
|
||||||
|
println!(
|
||||||
|
"Sealed image detected, using secure boot with keys from: {}",
|
||||||
|
sb_keys_dir
|
||||||
|
);
|
||||||
|
vec![
|
||||||
|
"--firmware=uefi-secure".to_string(),
|
||||||
|
format!("--secure-boot-keys={}", sb_keys_dir),
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
anyhow::bail!(
|
||||||
|
"Sealed image detected but no secure boot keys found at {}. \
|
||||||
|
Run 'just generate-secureboot-keys' to generate them.",
|
||||||
|
sb_keys_dir
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
Ok(r)
|
||||||
|
}
|
||||||
|
|
||||||
/// Check if a distro supports --bind-storage-ro
|
/// Check if a distro supports --bind-storage-ro
|
||||||
/// CentOS 9 lacks systemd.extra-unit.* support required for bind-storage-ro
|
/// CentOS 9 lacks systemd.extra-unit.* support required for bind-storage-ro
|
||||||
fn distro_supports_bind_storage_ro(distro: &str) -> bool {
|
fn distro_supports_bind_storage_ro(distro: &str) -> bool {
|
||||||
@@ -240,6 +282,8 @@ pub(crate) fn run_tmt(sh: &Shell, args: &RunTmtArgs) -> Result<()> {
|
|||||||
println!("Using bcvk image: {}", image);
|
println!("Using bcvk image: {}", image);
|
||||||
println!("Detected distro: {}", distro);
|
println!("Detected distro: {}", distro);
|
||||||
|
|
||||||
|
let firmware_args = build_firmware_args(sh, image)?;
|
||||||
|
|
||||||
// Create tmt-workdir and copy tmt bits to it
|
// Create tmt-workdir and copy tmt bits to it
|
||||||
// This works around https://github.com/teemtee/tmt/issues/4062
|
// This works around https://github.com/teemtee/tmt/issues/4062
|
||||||
let workdir = Utf8Path::new("target/tmt-workdir");
|
let workdir = Utf8Path::new("target/tmt-workdir");
|
||||||
@@ -348,9 +392,10 @@ pub(crate) fn run_tmt(sh: &Shell, args: &RunTmtArgs) -> Result<()> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Launch VM with bcvk
|
// Launch VM with bcvk
|
||||||
|
let firmware_args_slice = firmware_args.as_slice();
|
||||||
let launch_result = cmd!(
|
let launch_result = cmd!(
|
||||||
sh,
|
sh,
|
||||||
"bcvk libvirt run --name {vm_name} --detach {COMMON_INST_ARGS...} {plan_bcvk_opts...} {image}"
|
"bcvk libvirt run --name {vm_name} --detach {firmware_args_slice...} {COMMON_INST_ARGS...} {plan_bcvk_opts...} {image}"
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
.context("Launching VM with bcvk");
|
.context("Launching VM with bcvk");
|
||||||
@@ -597,11 +642,14 @@ pub(crate) fn tmt_provision(sh: &Shell, args: &TmtProvisionArgs) -> Result<()> {
|
|||||||
println!(" Image: {}", image);
|
println!(" Image: {}", image);
|
||||||
println!(" VM name: {}\n", vm_name);
|
println!(" VM name: {}\n", vm_name);
|
||||||
|
|
||||||
|
let firmware_args = build_firmware_args(sh, image)?;
|
||||||
|
|
||||||
// Launch VM with bcvk
|
// Launch VM with bcvk
|
||||||
// Use ds=iid-datasource-none to disable cloud-init for faster boot
|
// Use ds=iid-datasource-none to disable cloud-init for faster boot
|
||||||
|
let firmware_args_slice = firmware_args.as_slice();
|
||||||
cmd!(
|
cmd!(
|
||||||
sh,
|
sh,
|
||||||
"bcvk libvirt run --name {vm_name} --detach {COMMON_INST_ARGS...} {image}"
|
"bcvk libvirt run --name {vm_name} --detach {firmware_args_slice...} {COMMON_INST_ARGS...} {image}"
|
||||||
)
|
)
|
||||||
.run()
|
.run()
|
||||||
.context("Launching VM with bcvk")?;
|
.context("Launching VM with bcvk")?;
|
||||||
|
|||||||
37
hack/build-sealed
Executable file
37
hack/build-sealed
Executable file
@@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
# This should turn into https://github.com/bootc-dev/bootc/issues/1498
|
||||||
|
|
||||||
|
dn=$(cd $(dirname $0) && pwd)
|
||||||
|
|
||||||
|
variant=$1
|
||||||
|
shift
|
||||||
|
# The un-sealed container image we want to use
|
||||||
|
input_image=$1
|
||||||
|
shift
|
||||||
|
# The output container image
|
||||||
|
output_image=$1
|
||||||
|
shift
|
||||||
|
|
||||||
|
runv() {
|
||||||
|
set -x
|
||||||
|
"$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
case $variant in
|
||||||
|
ostree)
|
||||||
|
# Nothing to do
|
||||||
|
echo "Not building a sealed image; forwarding tag"
|
||||||
|
runv podman tag $input_image $output_image
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
composefs-sealeduki*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown variant=$variant" 1>&2; exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
cfs_digest=$(${dn}/compute-composefs-digest $input_image)
|
||||||
|
runv podman build -t $output_image \
|
||||||
|
--build-arg=COMPOSEFS_FSVERITY=${cfs_digest} --build-arg=base=${input_image} "$@" -f Dockerfile.cfsuki .
|
||||||
11
hack/compute-composefs-digest
Executable file
11
hack/compute-composefs-digest
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
# This just runs `bootc container compute-composefs-digest` in a provided container image
|
||||||
|
image=$1
|
||||||
|
shift
|
||||||
|
# Find the container storage
|
||||||
|
graphroot=$(podman system info -f '{{.Store.GraphRoot}}')
|
||||||
|
# --pull=never because we don't want to pollute the output with progress and most use cases
|
||||||
|
# for this really should be operating on pre-pulled images.
|
||||||
|
exec podman run --pull=never --quiet --rm --privileged --read-only --security-opt=label=disable -v /sys:/sys:ro --net=none \
|
||||||
|
-v ${graphroot}:/run/host-container-storage:ro --tmpfs /var "$image" bootc container compute-composefs-digest
|
||||||
17
hack/generate-secureboot-keys
Executable file
17
hack/generate-secureboot-keys
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
# Generate Secure Boot keys, only intended to be used for our CI pipeline.
|
||||||
|
d=target/test-secureboot
|
||||||
|
# This file existing signals completion
|
||||||
|
if test -f "${d}/.done"; then exit 0; fi
|
||||||
|
mkdir -p "$d"
|
||||||
|
cd "$d"
|
||||||
|
systemd-id128 new -u > GUID.txt
|
||||||
|
openssl req -quiet -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 -quiet -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 -quiet -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
|
||||||
|
touch .done
|
||||||
|
echo "Generated Secure Boot keys in ${d}"
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -euo pipefail
|
|
||||||
# This should turn into https://github.com/bootc-dev/bootc/issues/1498
|
|
||||||
|
|
||||||
variant=$1
|
|
||||||
shift
|
|
||||||
# The un-sealed container image we want to use
|
|
||||||
input_image=$1
|
|
||||||
shift
|
|
||||||
# The output container image
|
|
||||||
output_image=$1
|
|
||||||
shift
|
|
||||||
# Buildroot base image for UKI build environment
|
|
||||||
buildroot_base=$1
|
|
||||||
shift
|
|
||||||
# Optional directory with secure boot keys; if none are provided, then we'll
|
|
||||||
# generate some under target/
|
|
||||||
secureboot=${1:-}
|
|
||||||
|
|
||||||
runv() {
|
|
||||||
set -x
|
|
||||||
"$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
case $variant in
|
|
||||||
ostree)
|
|
||||||
# Nothing to do
|
|
||||||
echo "Not building a sealed image; forwarding tag"
|
|
||||||
runv podman tag $input_image $output_image
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
composefs-sealeduki*)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Unknown variant=$variant" 1>&2; exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
|
|
||||||
if test -z "${secureboot}"; then
|
|
||||||
secureboot=$(pwd)/target/test-secureboot
|
|
||||||
mkdir -p ${secureboot}
|
|
||||||
cd $secureboot
|
|
||||||
if test '!' -f db.cer; then
|
|
||||||
echo "Generating test Secure Boot keys"
|
|
||||||
systemd-id128 new -u > GUID.txt
|
|
||||||
openssl req -quiet -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 -quiet -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 -quiet -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
|
|
||||||
else
|
|
||||||
echo "Reusing Secure Boot keys in ${secureboot}"
|
|
||||||
fi
|
|
||||||
cd -
|
|
||||||
fi
|
|
||||||
|
|
||||||
# handle sdboot signing before building the sealed UKI
|
|
||||||
sdboot_signed="${input_image}_signed"
|
|
||||||
runv podman build -t $sdboot_signed \
|
|
||||||
--build-arg=base=${input_image} \
|
|
||||||
--build-arg=buildroot=${buildroot_base} \
|
|
||||||
--secret=id=key,src=${secureboot}/db.key \
|
|
||||||
--secret=id=cert,src=${secureboot}/db.crt \
|
|
||||||
-f Dockerfile.sdboot .
|
|
||||||
|
|
||||||
graphroot=$(podman system info -f '{{.Store.GraphRoot}}')
|
|
||||||
echo "Computing composefs digest..."
|
|
||||||
cfs_digest=$(podman run --rm --privileged --read-only --security-opt=label=disable -v /sys:/sys:ro --net=none \
|
|
||||||
-v ${graphroot}:/run/host-container-storage:ro --tmpfs /var "$sdboot_signed" bootc container compute-composefs-digest)
|
|
||||||
|
|
||||||
runv podman build -t $output_image \
|
|
||||||
--build-arg=COMPOSEFS_FSVERITY=${cfs_digest} \
|
|
||||||
--build-arg=base=${sdboot_signed} \
|
|
||||||
--secret=id=key,src=${secureboot}/db.key \
|
|
||||||
--secret=id=cert,src=${secureboot}/db.crt \
|
|
||||||
-f Dockerfile.cfsuki .
|
|
||||||
@@ -102,17 +102,6 @@ execute:
|
|||||||
test:
|
test:
|
||||||
- /tmt/tests/tests/test-25-download-only-upgrade
|
- /tmt/tests/tests/test-25-download-only-upgrade
|
||||||
|
|
||||||
/plan-26-examples-build:
|
|
||||||
summary: Test bootc examples build scripts
|
|
||||||
discover:
|
|
||||||
how: fmf
|
|
||||||
test:
|
|
||||||
- /tmt/tests/tests/test-26-examples-build
|
|
||||||
adjust:
|
|
||||||
- when: running_env != image_mode
|
|
||||||
enabled: false
|
|
||||||
because: packit tests use RPM bootc and does not install /usr/lib/bootc/initramfs-setup
|
|
||||||
|
|
||||||
/plan-27-custom-selinux-policy:
|
/plan-27-custom-selinux-policy:
|
||||||
summary: Execute custom selinux policy test
|
summary: Execute custom selinux policy test
|
||||||
discover:
|
discover:
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
# number: 26
|
|
||||||
# tmt:
|
|
||||||
# summary: Test bootc examples build scripts
|
|
||||||
# duration: 45m
|
|
||||||
# adjust:
|
|
||||||
# - when: running_env != image_mode
|
|
||||||
# enabled: false
|
|
||||||
# because: packit tests use RPM bootc and does not install /usr/lib/bootc/initramfs-setup
|
|
||||||
#
|
|
||||||
#!/bin/bash
|
|
||||||
set -eux
|
|
||||||
|
|
||||||
# Test bootc-bls example
|
|
||||||
echo "Testing bootc-bls example..."
|
|
||||||
cd examples/bootc-bls
|
|
||||||
./build
|
|
||||||
|
|
||||||
# Test bootc-uki example
|
|
||||||
echo "Testing bootc-uki example..."
|
|
||||||
cd ../bootc-uki
|
|
||||||
./build.base
|
|
||||||
./build.final
|
|
||||||
|
|
||||||
echo "All example builds completed successfully"
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
FROM quay.io/fedora/fedora-bootc:42
|
|
||||||
COPY extra /
|
|
||||||
COPY bootc /usr/bin
|
|
||||||
|
|
||||||
RUN passwd -d root
|
|
||||||
|
|
||||||
# need to have bootc-initramfs-setup 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;
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eux
|
|
||||||
|
|
||||||
cd "${0%/*}"
|
|
||||||
|
|
||||||
cp /usr/bin/bootc .
|
|
||||||
cp /usr/lib/bootc/initramfs-setup extra/usr/lib/dracut/modules.d/37bootc/bootc-initramfs-setup
|
|
||||||
|
|
||||||
mkdir -p tmp
|
|
||||||
|
|
||||||
podman build \
|
|
||||||
-t quay.io/fedora/fedora-bootc-bls:42 \
|
|
||||||
-f Containerfile \
|
|
||||||
--iidfile=tmp/iid \
|
|
||||||
.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# we need to force these in via the initramfs because we don't have modules in
|
|
||||||
# the base image
|
|
||||||
force_drivers+=" virtio_net vfat "
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# Copyright (C) 2013 Colin Walters <walters@verbum.org>
|
|
||||||
#
|
|
||||||
# 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/bootc-initramfs-setup
|
|
||||||
StandardInput=null
|
|
||||||
StandardOutput=journal
|
|
||||||
StandardError=journal+console
|
|
||||||
RemainAfterExit=yes
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#!/usr/bin/bash
|
|
||||||
|
|
||||||
check() {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
depends() {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
install() {
|
|
||||||
inst \
|
|
||||||
"${moddir}/bootc-initramfs-setup" /usr/bin/bootc-initramfs-setup
|
|
||||||
inst \
|
|
||||||
"${moddir}/bootc-initramfs-setup.service" \
|
|
||||||
"${systemdsystemunitdir}/bootc-initramfs-setup.service"
|
|
||||||
|
|
||||||
$SYSTEMCTL -q --root "${initdir}" add-wants \
|
|
||||||
'initrd-root-fs.target' 'bootc-initramfs-setup.service'
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
FROM quay.io/fedora/fedora-bootc:42
|
|
||||||
COPY extra /
|
|
||||||
COPY bootc /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;
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
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
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eux
|
|
||||||
|
|
||||||
cd "${0%/*}"
|
|
||||||
|
|
||||||
cp /usr/bin/bootc .
|
|
||||||
cp /usr/lib/bootc/initramfs-setup extra/usr/lib/dracut/modules.d/37bootc/bootc-initramfs-setup
|
|
||||||
|
|
||||||
mkdir -p tmp
|
|
||||||
|
|
||||||
podman build \
|
|
||||||
-t quay.io/fedora/fedora-bootc-base-uki:42 \
|
|
||||||
-f Containerfile.stage1 \
|
|
||||||
--iidfile=tmp/iid \
|
|
||||||
.
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eux
|
|
||||||
|
|
||||||
cd "${0%/*}"
|
|
||||||
|
|
||||||
cp /usr/bin/bootc .
|
|
||||||
|
|
||||||
rm -rf tmp/sysroot
|
|
||||||
mkdir -p tmp/sysroot/composefs
|
|
||||||
|
|
||||||
# TODO port this over to container compute-composefs-digest
|
|
||||||
IMAGE_ID="$(sed s/sha256:// tmp/iid)"
|
|
||||||
./bootc internals cfs --repo tmp/sysroot/composefs --insecure oci pull containers-storage:"${IMAGE_ID}"
|
|
||||||
COMPOSEFS_FSVERITY="$(./bootc internals cfs --repo tmp/sysroot/composefs --insecure 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
|
|
||||||
systemd-id128 new -u > 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
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#!/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,3 +0,0 @@
|
|||||||
# we need to force these in via the initramfs because we don't have modules in
|
|
||||||
# the base image
|
|
||||||
force_drivers+=" virtio_net vfat "
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# Copyright (C) 2013 Colin Walters <walters@verbum.org>
|
|
||||||
#
|
|
||||||
# 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/bootc-initramfs-setup
|
|
||||||
StandardInput=null
|
|
||||||
StandardOutput=journal
|
|
||||||
StandardError=journal+console
|
|
||||||
RemainAfterExit=yes
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#!/usr/bin/bash
|
|
||||||
|
|
||||||
check() {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
depends() {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
install() {
|
|
||||||
inst \
|
|
||||||
"${moddir}/bootc-initramfs-setup" /usr/bin/bootc-initramfs-setup
|
|
||||||
inst \
|
|
||||||
"${moddir}/bootc-initramfs-setup.service" \
|
|
||||||
"${systemdsystemunitdir}/bootc-initramfs-setup.service"
|
|
||||||
|
|
||||||
$SYSTEMCTL -q --root "${initdir}" add-wants \
|
|
||||||
'initrd-root-fs.target' 'bootc-initramfs-setup.service'
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#!/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-backend \
|
|
||||||
--boot=uki \
|
|
||||||
--source-imgref="containers-storage:${IMAGE}" \
|
|
||||||
--target-imgref="${IMAGE}" \
|
|
||||||
--target-transport="docker" \
|
|
||||||
/dev/vdb \
|
|
||||||
--filesystem=ext4 \
|
|
||||||
--wipe
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
#!/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-backend \
|
|
||||||
--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
|
|
||||||
@@ -46,15 +46,6 @@
|
|||||||
duration: 40m
|
duration: 40m
|
||||||
test: nu booted/test-25-download-only-upgrade.nu
|
test: nu booted/test-25-download-only-upgrade.nu
|
||||||
|
|
||||||
/test-26-examples-build:
|
|
||||||
summary: Test bootc examples build scripts
|
|
||||||
duration: 45m
|
|
||||||
adjust:
|
|
||||||
- when: running_env != image_mode
|
|
||||||
enabled: false
|
|
||||||
because: packit tests use RPM bootc and does not install /usr/lib/bootc/initramfs-setup
|
|
||||||
test: bash booted/test-26-examples-build.sh
|
|
||||||
|
|
||||||
/test-27-custom-selinux-policy:
|
/test-27-custom-selinux-policy:
|
||||||
summary: Execute custom selinux policy test
|
summary: Execute custom selinux policy test
|
||||||
duration: 30m
|
duration: 30m
|
||||||
|
|||||||
Reference in New Issue
Block a user