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
|
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
|
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
|
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
|
# Rechunk
|
||||||
rpm-ostree experimental compose build-chunked-oci --bootc --format-version=1 \
|
rpm-ostree experimental compose build-chunked-oci --bootc --format-version=1 \
|
||||||
--from=${IMAGE_PREFIX}-base:tmp --output containers-storage:${IMAGE_PREFIX}-base
|
--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 .
|
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.
|
# This is a local reference by default because we haven't shipped this image yet.
|
||||||
FROM localhost/fedora-bootc:base
|
FROM localhost/fedora-bootc:base
|
||||||
# Drop our package sets into /usr/share/doc, so that other things can parse it
|
# Copy in our configuration and build scripts. Most of the heavy lifting
|
||||||
COPY packages*.txt /usr/share/doc/fedora-bootc/
|
# is in `stage-install` which we emit into /usr/share/doc so it can be
|
||||||
# Overlay our defaults
|
# used as a reference in other images.
|
||||||
COPY usr/ /usr/
|
COPY usr/ /usr/
|
||||||
RUN <<EORUN
|
RUN <<EORUN
|
||||||
set -euo pipefail
|
set -xeuo pipefail
|
||||||
dnf_args=()
|
# This script installs our default packages. These scripts
|
||||||
echo "Loading packages-excluded"
|
# are not a stable API, but may become one in the future.
|
||||||
basedir=/usr/share/doc/fedora-bootc/
|
/usr/share/doc/bootc-image-standard/stage-install
|
||||||
for x in $(grep -E -v '^#' ${basedir}/packages-excluded.txt); do
|
# Cleanup
|
||||||
dnf_args+=(--exclude ${x})
|
/usr/share/doc/bootc-image-standard/stage-clean
|
||||||
done
|
# And lint.
|
||||||
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
|
|
||||||
bootc container lint
|
bootc container lint
|
||||||
EORUN
|
EORUN
|
||||||
|
|
|
||||||
|
|
@ -8,26 +8,26 @@
|
||||||
# If you want to configure the input rpm-md repositories, just override this
|
# If you want to configure the input rpm-md repositories, just override this
|
||||||
# container image.
|
# container image.
|
||||||
FROM quay.io/fedora/fedora:rawhide as repos
|
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.
|
# We use stream10 to demonstrate that we support "cross builds".
|
||||||
FROM registry.gitlab.com/fedora/bootc/base-images-dev/fedora-bootc-dev:rawhide as builder
|
FROM quay.io/centos/centos:stream10 as builder
|
||||||
RUN dnf -y install rpm-ostree selinux-policy-targeted sqlite
|
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 in our source code.
|
||||||
COPY . /src
|
COPY . /src
|
||||||
WORKDIR /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
|
set -xeuo pipefail
|
||||||
# Synchronize the dnf/rpm configs from the repos container.
|
# Copy the build configuration into the builder image, as if it's the final image
|
||||||
for x in etc/dnf etc/yum.repos.d etc/pki/rpm-gpg; do
|
cp -a . /usr/lib/sysimage/base-image-manifest
|
||||||
rm -rf /"$x" && cp -a /repos/${x} /$x
|
# And embed the rebuild script
|
||||||
done
|
install -m 0755 -t /usr/libexec ./bootc-base-image-rebuild-self
|
||||||
# And copy to the workdir; TODO fix this in rpm-ostree
|
# Finally, run the build script in the same way we expect custom images to do.
|
||||||
cp /etc/yum.repos.d/*.repo base
|
/usr/libexec/bootc-base-image-rebuild-self /repos /target-rootfs
|
||||||
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
|
|
||||||
EORUN
|
EORUN
|
||||||
|
|
||||||
# This pulls in the rootfs generated in the previous step
|
# 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