Skip to content

Commit 621e141

Browse files
committed
build-sys: Re-seal upgrade image for composefs UKI builds
The upgrade test image (localhost/bootc-upgrade) was previously a simple one-layer addition on top of localhost/bootc that did not go through the sealing pipeline. This meant sealed composefs builds could not properly test upgrades, since the upgrade image lacked a signed UKI with the correct composefs digest. Rework Dockerfile.upgrade into a multi-stage build that mirrors the main Dockerfile sealing flow: when boot_type=uki, it computes the composefs digest of the upgrade rootfs, generates and optionally signs a UKI via seal-uki, and finalizes it with finalize-uki. For non-UKI builds, the extra stages are effectively no-ops and the image remains a simple derived layer. Update _build-upgrade-image in the Justfile to pass the required build arguments (boot_type, seal_state, filesystem) and build secrets (secureboot keys). Extra container capabilities (CAP_ALL, fuse device) are only added for UKI builds that need composefs support. Assisted-by: OpenCode (claude-opus-4) Signed-off-by: Colin Walters <walters@verbum.org>
1 parent eebb1fe commit 621e141

File tree

2 files changed

+81
-5
lines changed

2 files changed

+81
-5
lines changed

Justfile

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ test-composefs bootloader filesystem boot_type seal_state *ARGS:
141141
--seal-state={{seal_state}} \
142142
--boot-type={{boot_type}} \
143143
{{ARGS}} \
144-
$(if [ "{{boot_type}}" = "uki" ]; then echo "readonly"; else echo "integration"; fi)
144+
$(if [ "{{boot_type}}" = "uki" ]; then echo "readonly composefs-upgrade"; else echo "integration"; fi)
145145

146146
# Run upgrade test: boot VM from published base image (with tmt deps added),
147147
# upgrade to locally-built image, reboot, then run readonly tests to verify.
@@ -362,7 +362,24 @@ _keygen:
362362
./hack/generate-secureboot-keys
363363

364364
_build-upgrade-image:
365-
cat tmt/tests/Dockerfile.upgrade | podman build -t {{upgrade_img}} --from={{base_img}} -
365+
#!/bin/bash
366+
set -xeuo pipefail
367+
# Secrets are always available (test-tmt depends on build which runs _keygen).
368+
# Extra capabilities are only needed for UKI builds (composefs + fuse).
369+
extra_args=()
370+
if [ "{{boot_type}}" = "uki" ]; then
371+
extra_args+=(--cap-add=all --security-opt=label=type:container_runtime_t --device /dev/fuse)
372+
fi
373+
podman build \
374+
--build-arg "boot_type={{boot_type}}" \
375+
--build-arg "seal_state={{seal_state}}" \
376+
--build-arg "filesystem={{filesystem}}" \
377+
--secret=id=secureboot_key,src=target/test-secureboot/db.key \
378+
--secret=id=secureboot_cert,src=target/test-secureboot/db.crt \
379+
"${extra_args[@]}" \
380+
-t {{upgrade_img}} \
381+
-f tmt/tests/Dockerfile.upgrade \
382+
.
366383

367384
# Build the upgrade source image: base image + tmt dependencies (rsync, nu, cloud-init)
368385
_build-upgrade-source-image:

tmt/tests/Dockerfile.upgrade

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,62 @@
1-
# Just creates a file as a new layer for a synthetic upgrade test
2-
FROM localhost/bootc
3-
RUN touch --reference=/usr/bin/bash /usr/share/testing-bootc-upgrade-apply
1+
# Creates a synthetic upgrade image for testing.
2+
# For non-UKI builds, this just adds a marker file on top of localhost/bootc.
3+
# For UKI builds (boot_type=uki), the image is re-sealed with a new composefs
4+
# digest and (optionally signed) UKI.
5+
#
6+
# Build secrets required (for sealed builds):
7+
# secureboot_key, secureboot_cert
8+
ARG boot_type=bls
9+
ARG seal_state=unsealed
10+
ARG filesystem=ext4
11+
12+
# Capture contrib/packaging scripts for use in later stages
13+
FROM scratch AS packaging
14+
COPY contrib/packaging /
15+
16+
# Create the upgrade content (a simple marker file).
17+
# For UKI builds, we also remove the existing UKI so that seal-uki can
18+
# regenerate it with the correct composefs digest for this derived image.
19+
FROM localhost/bootc AS upgrade-base
20+
ARG boot_type
21+
RUN touch --reference=/usr/bin/bash /usr/share/testing-bootc-upgrade-apply && \
22+
if test "${boot_type}" = "uki"; then rm -rf /boot/EFI/Linux/*.efi; fi
23+
24+
# Tools for sealing (only meaningfully used for UKI builds)
25+
FROM localhost/bootc AS tools
26+
RUN --mount=type=tmpfs,target=/run --mount=type=tmpfs,target=/tmp \
27+
--mount=type=bind,from=packaging,src=/,target=/run/packaging \
28+
/run/packaging/initialize-sealing-tools
29+
30+
# Generate a sealed UKI for the upgrade image.
31+
# bootc is already installed in localhost/bootc (our tools base); the
32+
# container ukify command it provides is needed for seal-uki.
33+
FROM tools AS sealed-upgrade-uki
34+
ARG boot_type seal_state filesystem
35+
RUN --network=none --mount=type=tmpfs,target=/run --mount=type=tmpfs,target=/tmp \
36+
--mount=type=secret,id=secureboot_key \
37+
--mount=type=secret,id=secureboot_cert \
38+
--mount=type=bind,from=packaging,src=/,target=/run/packaging \
39+
--mount=type=bind,from=upgrade-base,src=/,target=/run/target <<EORUN
40+
set -xeuo pipefail
41+
42+
allow_missing_verity=false
43+
if [ "${filesystem}" = "xfs" ]; then
44+
allow_missing_verity=true
45+
fi
46+
47+
if test "${boot_type}" = "uki"; then
48+
/run/packaging/seal-uki /run/target /out /run/secrets "${allow_missing_verity}" "${seal_state}"
49+
fi
50+
EORUN
51+
52+
# Final stage: the upgrade image, optionally with a re-sealed UKI
53+
FROM upgrade-base
54+
ARG boot_type
55+
RUN --network=none --mount=type=tmpfs,target=/run --mount=type=tmpfs,target=/tmp \
56+
--mount=type=bind,from=packaging,src=/,target=/run/packaging \
57+
--mount=type=bind,from=sealed-upgrade-uki,src=/,target=/run/sealed-uki <<EORUN
58+
set -xeuo pipefail
59+
if test "${boot_type}" = "uki"; then
60+
/run/packaging/finalize-uki /run/sealed-uki/out
61+
fi
62+
EORUN

0 commit comments

Comments
 (0)