Merge branch 'custom-base-more2' into 'wip-baseimage-rework'
Draft: Rework build system further See merge request fedora/bootc/base-images!89
This commit is contained in:
commit
1a3bfca9fa
|
|
@ -16,8 +16,10 @@ build:
|
|||
set -xeuo pipefail
|
||||
curl -L --fail -o /etc/yum.repos.d/coreos-continuous.repo https://copr.fedorainfracloud.org/coprs/g/CoreOS/continuous/repo/fedora-42/group_CoreOS-continuous-fedora-42.repo
|
||||
dnf -y install rpm-ostree
|
||||
buildah build "${hostbuildopts[@]}" -f Containerfile.base --no-cache --security-opt=label=disable --cap-add=all --device /dev/fuse -t ${IMAGE_PREFIX}-base:tmp .
|
||||
cd base
|
||||
buildah build "${hostbuildopts[@]}" -f Containerfile --no-cache --security-opt=label=disable --cap-add=all --device /dev/fuse -t ${IMAGE_PREFIX}-base:tmp .
|
||||
# Rechunk
|
||||
rpm-ostree experimental compose build-chunked-oci --bootc --format-version=1 \
|
||||
--from=${IMAGE_PREFIX}-base:tmp --output containers-storage:${IMAGE_PREFIX}-base
|
||||
cd ..
|
||||
buildah build "${hostbuildopts[@]}" -f Containerfile --no-cache --from ${IMAGE_PREFIX}-base -t ${IMAGE_PREFIX}-standard:tmp .
|
||||
|
|
|
|||
|
|
@ -1,42 +1,18 @@
|
|||
# This generates the default base image.
|
||||
# This generates the "standard" base image, deriving from the minimal base.
|
||||
|
||||
# This is a local reference by default because we haven't shipped this image yet.
|
||||
FROM localhost/fedora-bootc:base
|
||||
# Drop our package sets into /usr/share/doc, so that other things can parse it
|
||||
COPY packages*.txt /usr/share/doc/fedora-bootc/
|
||||
# Overlay our defaults
|
||||
# Copy in our configuration and build scripts. Most of the heavy lifting
|
||||
# is in `stage-install` which we emit into /usr/share/doc so it can be
|
||||
# used as a reference in other images.
|
||||
COPY usr/ /usr/
|
||||
RUN <<EORUN
|
||||
set -euo pipefail
|
||||
dnf_args=()
|
||||
echo "Loading packages-excluded"
|
||||
basedir=/usr/share/doc/fedora-bootc/
|
||||
for x in $(grep -E -v '^#' ${basedir}/packages-excluded.txt); do
|
||||
dnf_args+=(--exclude ${x})
|
||||
done
|
||||
echo "Loading packages"
|
||||
package_files=(${basedir}/packages-recommended-minimal.txt ${basedir}/packages.txt)
|
||||
pkgfile_for_arch=/usr/share/doc/fedora-bootc/packages-$(arch).txt
|
||||
if test -f ${pkgfile_for_arch}; then
|
||||
echo "Loading ${pkgfile_for_arch}"
|
||||
package_files+=(${pkgfile_for_arch})
|
||||
fi
|
||||
base_pkgs=$(grep -hE -v '^#' ${package_files[@]})
|
||||
dnf -y ${dnf_args[@]} install $base_pkgs
|
||||
|
||||
# Ensure we regenerate the initramfs with new content
|
||||
# https://docs.fedoraproject.org/en-US/bootc/initramfs/
|
||||
kver=$(cd /usr/lib/modules && echo *); dracut -vf /usr/lib/modules/$kver/initramfs.img $kver
|
||||
|
||||
# Undo RPM scripts enabling units; we want the presets to be canonical for the base image.
|
||||
# https://github.com/projectatomic/rpm-ostree/issues/1803
|
||||
rm -rf /etc/systemd/system/*
|
||||
systemctl preset-all
|
||||
rm -rf /etc/systemd/user/*
|
||||
systemctl --user --global preset-all
|
||||
|
||||
dnf clean all
|
||||
# Lots of cleaning
|
||||
rm -vrf /var/log /var/cache /var/lib/dnf
|
||||
set -xeuo pipefail
|
||||
# This script installs our default packages. These scripts
|
||||
# are not a stable API, but may become one in the future.
|
||||
/usr/share/doc/bootc-image-standard/stage-install
|
||||
# Cleanup
|
||||
/usr/share/doc/bootc-image-standard/stage-clean
|
||||
# And lint.
|
||||
bootc container lint
|
||||
EORUN
|
||||
|
|
|
|||
|
|
@ -8,26 +8,26 @@
|
|||
# If you want to configure the input rpm-md repositories, just override this
|
||||
# container image.
|
||||
FROM quay.io/fedora/fedora:rawhide as repos
|
||||
# See https://github.com/coreos/rpm-ostree/issues/3397
|
||||
RUN ln -sr /usr/lib/sysimage/rpm /usr/share/rpm
|
||||
|
||||
# BOOTSTRAPPING: This can be any image that has the following packages.
|
||||
FROM registry.gitlab.com/fedora/bootc/base-images-dev/fedora-bootc-dev:rawhide as builder
|
||||
RUN dnf -y install rpm-ostree selinux-policy-targeted sqlite
|
||||
# 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 <<EORUN
|
||||
RUN --mount=type=bind,from=repos,src=/,dst=/repos,rw <<EORUN
|
||||
set -xeuo pipefail
|
||||
# Synchronize the dnf/rpm configs from the repos container.
|
||||
for x in etc/dnf etc/yum.repos.d etc/pki/rpm-gpg; do
|
||||
rm -rf /"$x" && cp -a /repos/${x} /$x
|
||||
done
|
||||
# And copy to the workdir; TODO fix this in rpm-ostree
|
||||
cp /etc/yum.repos.d/*.repo base
|
||||
rpm-ostree experimental compose rootfs --source-root=/repos base/manifest.yaml /target-rootfs
|
||||
# Embed the configuration in the image itself, so that it can be used by later builds as well
|
||||
cp -a base /target-rootfs/usr/lib/sysimage/base-image-manifests
|
||||
# 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
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
install:
|
||||
install -m 0755 -t $(DESTDIR)/usr/libexec bootc-base-image-rebuild-self
|
||||
|
|
@ -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
|
||||
|
|
@ -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"]
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
set -xeuo pipefail
|
||||
dnf clean all
|
||||
# Lots of cleaning
|
||||
rm -vrf /var/log /var/cache /var/lib/dnf
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
dn=$(dirname $0)
|
||||
cd ${dn}
|
||||
dnf_args=()
|
||||
echo "Loading packages-excluded"
|
||||
for x in $(grep -E -v '^#' packages-excluded.txt); do
|
||||
dnf_args+=(--exclude ${x})
|
||||
done
|
||||
echo "Loading packages"
|
||||
package_files=(packages-recommended-minimal.txt packages.txt)
|
||||
pkgfile_for_arch=packages-$(arch).txt
|
||||
if test -f ${pkgfile_for_arch}; then
|
||||
echo "Loading ${pkgfile_for_arch}"
|
||||
package_files+=(${pkgfile_for_arch})
|
||||
fi
|
||||
base_pkgs=$(grep -hE -v '^#' ${package_files[@]})
|
||||
dnf -y ${dnf_args[@]} install $base_pkgs
|
||||
|
||||
# Ensure we regenerate the initramfs with new content
|
||||
# https://docs.fedoraproject.org/en-US/bootc/initramfs/
|
||||
kver=$(cd /usr/lib/modules && echo *); dracut -vf /usr/lib/modules/$kver/initramfs.img $kver
|
||||
|
||||
# Undo RPM scripts enabling units; we want the presets to be canonical for the base image.
|
||||
# https://github.com/projectatomic/rpm-ostree/issues/1803
|
||||
rm -rf /etc/systemd/system/*
|
||||
systemctl preset-all
|
||||
rm -rf /etc/systemd/user/*
|
||||
systemctl --user --global preset-all
|
||||
Loading…
Reference in New Issue