Rework build system further

- Move everything related to base/ into that directory, including Containerfile
- Introduce `bootc-base-image-rebuild-self` that can be used to
  resynthesize the base image, and it has docs.
- Rework the standard image to put its build instructions in
  usr/share/doc/bootc-image-standard to serve as a reference

Signed-off-by: Colin Walters <walters@verbum.org>
This commit is contained in:
Colin Walters committed 2025-02-11 08:57:48 -05:00
1 parent fffbf8853f
commit 6de35e0fc2
14 files changed
+165 -51

No files matched your search

+46
View File
@@ -0,0 +1,46 @@
# This is a relatively minimal base image build; it's intended as a derivation
# point.
#
# This container build uses nested containerization to construct
# a target rootfs from scratch; so you must build with e.g.
# podman build --security-opt=label=disable --cap-add=all --device /dev/fuse <...>
# If you want to configure the input rpm-md repositories, just override this
# container image.
FROM quay.io/fedora/fedora:rawhide as repos
# We use stream10 to demonstrate that we support "cross builds".
FROM quay.io/centos/centos:stream10 as builder
RUN <<EORUN
set -xeuo pipefail
# For rpm-ostree v2025.5
curl -L -o /etc/yum.repos.d/coreos-continuous.repo https://copr.fedorainfracloud.org/coprs/g/CoreOS/continuous/repo/centos-stream-10/group_CoreOS-continuous-centos-stream-10.repo
dnf -y install rpm-ostree selinux-policy-targeted sqlite
EORUN
# Copy in our source code.
COPY . /src
WORKDIR /src
RUN --mount=type=bind,from=repos,src=/,dst=/repos,rw <<EORUN
set -xeuo pipefail
# Copy the build configuration into the builder image, as if it's the final image
cp -a . /usr/lib/sysimage/base-image-manifest
# And embed the rebuild script
install -m 0755 -t /usr/libexec ./bootc-base-image-rebuild-self
# Finally, run the build script in the same way we expect custom images to do.
/usr/libexec/bootc-base-image-rebuild-self /repos /target-rootfs
EORUN
# This pulls in the rootfs generated in the previous step
FROM scratch
COPY --from=builder /target-rootfs/ /
LABEL containers.bootc 1
# This is an ad-hoc way for us to reference bootc-image-builder in
# a way that in theory client tooling can inspect and find. Today
# it isn't widely used.
LABEL bootc.diskimage-builder quay.io/centos-bootc/bootc-image-builder
# https://pagure.io/fedora-kiwi-descriptions/pull-request/52
ENV container=oci
# Make systemd the default
STOPSIGNAL SIGRTMIN+3
CMD ["/sbin/init"]
+2
View File
@@ -0,0 +1,2 @@
install:
install -m 0755 -t $(DESTDIR)/usr/libexec bootc-base-image-rebuild-self
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
# This script regenerates this base image using a build
# configuration (list of packages, scripts) embedded in this current image.
# The actual *content* packages will come from the source root.
set -xeuo pipefail
source_root=$1
shift
target=$1
shift
if ! test -x /usr/bin/rpm-ostree; then
dnf -y install rpm-ostree
fi
rpm-ostree experimental compose rootfs --source-root-rw=$source_root /usr/lib/sysimage/base-image-manifest/manifest.yaml $target
# Finally, propagate the configuration and build script into the target root.
for f in /usr/lib/sysimage/base-image-manifest /usr/libexec/bootc-base-image-rebuild-self; do
cp -a $f $target/$f
done
+83
View File
@@ -0,0 +1,83 @@
# bootc-base-image-rebuild-self
A core premise of the bootc model is that rich
control over Linux system customization can be accomplished
with a "default" container build:
```
FROM <base image>
RUN ...
```
As of recently, it is possible to e.g. swap the kernel
and other fundamental components as part of default derivation.
## Understanding the base image content
Most, but not all content from the base image comes from RPMs.
There is some additional non-RPM content, as well as postprocessing
that operates on the filesystem root. At the current
time the implementation of the base image build uses `rpm-ostree`,
but this is considered an implementation detail subject to change.
## Rebuilding from externally controlled content
Some use cases want even more control - for example,
as an organization deploying a bootc system, I may want to ensure
the base image version carries a set of packages at
exactly specific versions (perhaps defined by a lockfile,
or an rpm-md repository). There are many tools which
manage snapshots of yum (rpm-md) repositories.
The `/usr/libexec/bootc-base-image-rebuild-self` which is
included in the base image is designed to enable this
level of control.
## Using bootc-base-image-rebuild-self
This tool takes just two arguments:
- A "repository configuration root" which should have an `/etc/yum.repos.d`
that defines the input RPM content.
- A path to the target root filesystem which will be generated
### Implementation
The current implementation uses `rpm-ostree` on a manifest (treefile)
embedded in the container image itself. The set of packages installed
is currently not configurable; however it is quite minimal and can
easily be customized further as we will see below.
The build tooling is designed to support "cross builds"; the
repository root could e.g. be CentOS Stream 10, while the
builder root is Fedora or RHEL, etc. In other words, one given
base image can be used as a "builder" to produce another
using different RPMs.
### Example: Generate a new image using CentOS Stream 10 content from RHEL
FROM quay.io/centos/centos:stream10 as repos
FROM registry.redhat.io/rhel10/rhel-bootc:10 as builder
RUN --mount=type=bind,from=repos,src=/,dst=/repos,rw /usr/libexec/bootc-base-image-rebuild-self /repos /target-rootfs
# This container image uses the "artifact pattern"; it has some
# basic configuration we expect to apply to multiple container images.
FROM quay.io/exampleos/baseconfig@sha256:.... as baseconfig
FROM scratch
COPY --from=builder /target-rootfs/ /
# Now we make other arbitrary changes. Copy our systemd units and
# other tweaks from the baseconfig container image.
COPY --from=baseconfig /usr/ /usr/
RUN <<EORUN
set -xeuo pipefail
# Install critical components
dnf -y install linux-firmware NetworkManager cloud-init cowsay
dnf clean all
bootc container lint
EORUN
LABEL containers.bootc 1
ENV container=oci
STOPSIGNAL SIGRTMIN+3
CMD ["/sbin/init"]