# bootc-base-imagectl A core premise of the bootc model is that rich control over Linux system customization can be accomplished with a "default" container build: ``` FROM RUN ... ``` As of recently, it is possible to e.g. swap the kernel and other fundamental components as part of default derivation. However, 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. There are currently issues where it won't quite work to e.g. `dnf -y upgrade selinux-policy-targeted`. The `/usr/libexec/bootc-base-imagectl` tool which is included in the base image is designed to enable building a root filesystem in ostree-container format from a set of RPMs controlled by the user. ## 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. ## Using bootc-base-imagectl build-rootfs The core operation is `bootc-base-imagectl build-rootfs`. This command takes just two arguments: - A "source root" which should have an `/etc/yum.repos.d` that defines the input RPM content. This source root is also used to control things like the `$releasever`. - A path to the target root filesystem which will be generated as a directory. The target should not already exist (but its parent must exist). ### Other options `bootc-base-imagectl list` will enumerate available configurations that can be selected by passing `--manifest` to `build-rootfs`. ### Implementation The current implementation uses `rpm-ostree` on a manifest (treefile) embedded in the container image itself. These manifests are not intended to be editable directly. To emphasize: the implementation of this command (especially the configuration files that it reads) are subject to change. ### Cross builds and the builder image 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-imagectl build-rootfs --manifest=minimal /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 <