2025-09-28 22:58:27 +02:00
# Build this project from source and write the updated content
# (i.e. /usr/bin/bootc and systemd units) to a new derived container
# image. See the `Justfile` for an example
2025-06-06 11:11:58 -04:00
Rework GHA testing: Use bcvk, cover composefs with tmt
Part 1: Use bcvk
For local tests, right now testcloud+tmt doesn't support UEFI, see
https://github.com/teemtee/tmt/issues/4203
This is a blocker for us doing more testing with UKIs.
In this patch we switch to provisioning VMs with bcvk, which
fixes this - but beyond that a really compelling thing about
this is that bcvk is *also* designed to be ergonomic and efficient
beyond just being a test runner, with things like virtiofs
mounting of host container storage, etc.
In other words, bcvk is the preferred way to run local virt
with bootc, and this makes our TMT tests use it.
Now a major downside of this though is we're effectively
implementing a new "provisioner" for tmt (bypassing the
existing `virtual`). In the more medium term I think we
want to add `bcvk` as a provisioner option to tmt.
Anyways for now, this works by discovers test plans via `tmt plan ls`,
spawning a separate VM per test, and then using uses tmt's connect
provisioner to run tests targeting these externally provisioned
systems.
Part 2: Rework the Justfile and Dockerfile
This adds `base` and `variant` arguments which are propagated through
the system, and we have a new `variant` for sealed composefs.
The readonly tests now pass with composefs.
Drop the continuous repo tests...as while we could keep
that it's actually a whole *other* entry in this matrix.
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
2025-11-04 09:20:56 -05:00
# Note this is usually overridden via Justfile
2025-09-28 22:58:27 +02:00
ARG base = quay.io/centos-bootc/centos-bootc:stream10
2025-06-06 11:11:58 -04:00
2025-09-28 22:58:27 +02:00
# This first image captures a snapshot of the source code,
# note all the exclusions in .dockerignore.
2025-06-06 11:11:58 -04:00
FROM scratch as src
COPY . /src
2025-11-16 11:48:43 -05:00
# And this image only captures contrib/packaging separately
# to ensure we have more precise cache hits.
FROM scratch as packaging
COPY contrib/packaging /
2025-06-06 11:11:58 -04:00
# This image installs build deps, pulls in our source code, and installs updated
# bootc binaries in /out. The intention is that the target rootfs is extracted from /out
2025-09-28 22:58:27 +02:00
# back into a final stage (without the build deps etc) below.
2025-12-17 13:19:24 -05:00
FROM $base as buildroot
2025-09-24 14:27:34 -04:00
# Flip this off to disable initramfs code
ARG initramfs = 1
2025-11-16 11:48:43 -05:00
# This installs our buildroot, and we want to cache it independently of the rest.
# Basically we don't want changing a .rs file to blow out the cache of packages.
2026-01-20 15:21:05 +00:00
RUN --mount= type = tmpfs,target= /run --mount= type = tmpfs,target= /tmp \
2026-01-14 13:54:38 -05:00
--mount= type = bind,from= packaging,src= /,target= /run/packaging \
/run/packaging/install-buildroot
2025-06-06 11:11:58 -04:00
# Now copy the rest of the source
COPY --from= src /src /src
WORKDIR /src
# See https://www.reddit.com/r/rust/comments/126xeyx/exploring_the_problem_of_faster_cargo_docker/
# We aren't using the full recommendations there, just the simple bits.
2025-10-31 21:02:39 -04:00
# First we download all of our Rust dependencies
2026-01-20 15:21:05 +00:00
RUN --mount= type = tmpfs,target= /run --mount= type = tmpfs,target= /tmp --mount= type = cache,target= /src/target --mount= type = cache,target= /var/roothome cargo fetch
2025-11-16 11:48:43 -05:00
2025-12-02 20:45:40 -05:00
FROM buildroot as sdboot-content
# Writes to /out
2026-01-20 15:21:05 +00:00
RUN --mount= type = tmpfs,target= /run --mount= type = tmpfs,target= /tmp /src/contrib/packaging/configure-systemdboot download
2025-12-02 20:45:40 -05:00
2025-12-17 13:19:24 -05:00
# We always do a "from scratch" build
# https://docs.fedoraproject.org/en-US/bootc/building-from-scratch/
# because this fixes https://github.com/containers/composefs-rs/issues/132
# NOTE: Until we have https://gitlab.com/fedora/bootc/base-images/-/merge_requests/317
# this stage will end up capturing whatever RPMs we find at this time.
# NOTE: This is using the *stock* bootc binary, not the one we want to build from
# local sources. We'll override it later.
# NOTE: All your base belong to me.
FROM $base as target-base
2026-01-16 14:03:49 -05:00
# Handle version skew between base image and mirrors for CentOS Stream
# xref https://gitlab.com/redhat/centos-stream/containers/bootc/-/issues/1174
2026-01-20 15:21:05 +00:00
RUN --mount= type = tmpfs,target= /run --mount= type = tmpfs,target= /tmp \
2026-01-16 14:03:49 -05:00
--mount= type = bind,from= packaging,src= /,target= /run/packaging \
/run/packaging/enable-compose-repos
2026-01-20 15:21:05 +00:00
RUN --mount= type = tmpfs,target= /run --mount= type = tmpfs,target= /tmp /usr/libexec/bootc-base-imagectl build-rootfs --manifest= standard /target-rootfs
2025-12-17 13:19:24 -05:00
FROM scratch as base
COPY --from= target-base /target-rootfs/ /
2026-01-06 14:56:15 -05:00
# SKIP_CONFIGS=1 skips LBIs, test kargs, and install configs (for FCOS testing)
ARG SKIP_CONFIGS
2026-01-20 15:21:05 +00:00
# Use tmpfs for /run and /tmp with bind mounts inside to avoid leaking mount stubs into the image
RUN --mount= type = tmpfs,target= /run --mount= type = tmpfs,target= /tmp \
2026-01-14 13:54:38 -05:00
--mount= type = bind,from= src,src= /src/hack,target= /run/hack \
cd /run/hack/ && SKIP_CONFIGS = " ${ SKIP_CONFIGS } " ./provision-derived.sh
2025-12-17 13:19:24 -05:00
# Note we don't do any customization here yet
# Mark this as a test image
LABEL bootc.testimage= "1"
# Otherwise standard metadata
LABEL containers.bootc 1
LABEL ostree.bootable 1
# https://pagure.io/fedora-kiwi-descriptions/pull-request/52
ENV container = oci
# Optional labels that only apply when running this image as a container. These keep the default entry point running under systemd.
STOPSIGNAL SIGRTMIN+3
CMD [ "/sbin/init" ]
2025-12-17 16:36:30 -05:00
# -------------
# external dependency cutoff point:
2025-12-02 20:45:40 -05:00
# NOTE: Every RUN instruction past this point should use `--network=none`; we want to ensure
# all external dependencies are clearly delineated.
2025-12-17 16:36:30 -05:00
# This is verified in `cargo xtask check-buildsys`.
# -------------
2025-12-02 20:45:40 -05:00
2025-11-16 11:48:43 -05:00
FROM buildroot as build
2025-11-27 17:03:36 +08:00
# Version for RPM build (optional, computed from git in Justfile)
ARG pkgversion
2025-12-16 13:31:22 -05:00
# For reproducible builds, SOURCE_DATE_EPOCH must be exported as ENV for rpmbuild to see it
ARG SOURCE_DATE_EPOCH
ENV SOURCE_DATE_EPOCH = ${ SOURCE_DATE_EPOCH }
2025-11-16 11:48:43 -05:00
# Build RPM directly from source, using cached target directory
2026-01-20 15:21:05 +00:00
RUN --network= none --mount= type = tmpfs,target= /run --mount= type = tmpfs,target= /tmp --mount= type = cache,target= /src/target --mount= type = cache,target= /var/roothome RPM_VERSION = " ${ pkgversion } " /src/contrib/packaging/build-rpm
2025-06-06 11:11:58 -04:00
2025-12-02 20:45:40 -05:00
FROM buildroot as sdboot-signed
# The secureboot key and cert are passed via Justfile
# We write the signed binary into /out
2026-01-20 15:21:05 +00:00
RUN --network= none --mount= type = tmpfs,target= /run --mount= type = tmpfs,target= /tmp \
2026-01-14 13:54:38 -05:00
--mount= type = bind,from= sdboot-content,src= /,target= /run/sdboot-package \
2025-12-02 20:45:40 -05:00
--mount= type = secret,id= secureboot_key \
--mount= type = secret,id= secureboot_cert \
/src/contrib/packaging/configure-systemdboot sign
2025-09-22 14:48:13 -04:00
# This "build" includes our unit tests
2025-06-06 11:11:58 -04:00
FROM build as units
2025-09-22 14:48:13 -04:00
# A place that we're more likely to be able to set xattrs
VOLUME /var/tmp
ENV TMPDIR = /var/tmp
2026-01-20 15:21:05 +00:00
RUN --network= none --mount= type = tmpfs,target= /run --mount= type = tmpfs,target= /tmp --mount= type = cache,target= /src/target --mount= type = cache,target= /var/roothome make install-unit-tests
2025-09-22 14:48:13 -04:00
# This just does syntax checking
2025-12-16 13:31:22 -05:00
FROM buildroot as validate
2026-01-20 15:21:05 +00:00
RUN --network= none --mount= type = tmpfs,target= /run --mount= type = tmpfs,target= /tmp --mount= type = cache,target= /src/target --mount= type = cache,target= /var/roothome make validate
2025-06-06 11:11:58 -04:00
2025-12-16 13:31:22 -05:00
# Common base for final images: configures variant, rootfs, and injects extra content
FROM base as final-common
Rework GHA testing: Use bcvk, cover composefs with tmt
Part 1: Use bcvk
For local tests, right now testcloud+tmt doesn't support UEFI, see
https://github.com/teemtee/tmt/issues/4203
This is a blocker for us doing more testing with UKIs.
In this patch we switch to provisioning VMs with bcvk, which
fixes this - but beyond that a really compelling thing about
this is that bcvk is *also* designed to be ergonomic and efficient
beyond just being a test runner, with things like virtiofs
mounting of host container storage, etc.
In other words, bcvk is the preferred way to run local virt
with bootc, and this makes our TMT tests use it.
Now a major downside of this though is we're effectively
implementing a new "provisioner" for tmt (bypassing the
existing `virtual`). In the more medium term I think we
want to add `bcvk` as a provisioner option to tmt.
Anyways for now, this works by discovers test plans via `tmt plan ls`,
spawning a separate VM per test, and then using uses tmt's connect
provisioner to run tests targeting these externally provisioned
systems.
Part 2: Rework the Justfile and Dockerfile
This adds `base` and `variant` arguments which are propagated through
the system, and we have a new `variant` for sealed composefs.
The readonly tests now pass with composefs.
Drop the continuous repo tests...as while we could keep
that it's actually a whole *other* entry in this matrix.
Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
2025-11-04 09:20:56 -05:00
ARG variant
2026-01-20 15:21:05 +00:00
RUN --network= none --mount= type = tmpfs,target= /run --mount= type = tmpfs,target= /tmp \
2026-01-14 13:54:38 -05:00
--mount= type = bind,from= packaging,src= /,target= /run/packaging \
--mount= type = bind,from= sdboot-content,src= /,target= /run/sdboot-content \
--mount= type = bind,from= sdboot-signed,src= /,target= /run/sdboot-signed \
2025-12-02 20:45:40 -05:00
/run/packaging/configure-variant " ${ variant } "
2025-12-16 13:31:22 -05:00
ARG rootfs = ""
2026-01-20 15:21:05 +00:00
RUN --network= none --mount= type = tmpfs,target= /run --mount= type = tmpfs,target= /tmp \
2026-01-14 13:54:38 -05:00
--mount= type = bind,from= packaging,src= /,target= /run/packaging \
/run/packaging/configure-rootfs " ${ variant } " " ${ rootfs } "
2025-11-18 22:06:44 -05:00
COPY --from= packaging /usr-extras/ /usr/
2025-12-16 13:31:22 -05:00
2026-01-14 13:54:38 -05:00
# Final target: installs pre-built packages from the 'packages' build context.
# Use with: podman build --target=final --build-context packages=path/to/packages
# We use --build-context instead of -v to avoid volume mount stubs leaking into /run.
2025-12-16 13:31:22 -05:00
FROM final-common as final
2026-01-20 15:21:05 +00:00
RUN --network= none --mount= type = tmpfs,target= /run --mount= type = tmpfs,target= /tmp \
2026-01-14 13:54:38 -05:00
--mount= type = bind,from= packaging,src= /,target= /run/packaging \
--mount= type = bind,from= packages,src= /,target= /run/packages \
2025-12-16 13:31:22 -05:00
/run/packaging/install-rpm-and-setup /run/packages
2026-01-20 15:21:05 +00:00
# lint: allow non-tmpfs
RUN --network= none <<EORUN
set -xeuo pipefail
# workaround for https://github.com/containers/buildah/pull/6233
rm -vrf /run/systemd
bootc container lint --fatal-warnings
EORUN