84 lines
2.9 KiB
Markdown
84 lines
2.9 KiB
Markdown
# 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"]
|