1
0
mirror of https://github.com/containers/bootc.git synced 2026-02-05 15:45:53 +01:00

Dockerfile: Use rpmbuild

We were bit before by just doing a `COPY` of our binaries overtop of
the base image because that doens't remove old files.

Replace the pre-build approach with rpmbuild, and then change to
do an rpm-based upgrade so that we fix that problem.

Note that we still preserve incremental rebuilds by overriding
some of the RPM build process.

Assisted-by: Claude Code (Sonnet 4.5)
Signed-off-by: Colin Walters <walters@verbum.org>
This commit is contained in:
Colin Walters
2025-11-16 11:48:43 -05:00
parent 509a2c3954
commit d68245d319
10 changed files with 258 additions and 103 deletions

View File

@@ -1,4 +1,5 @@
%bcond_without check
%bcond_with tests
%if 0%{?rhel} >= 9 || 0%{?fedora} > 41
%bcond_without ostree_ext
%else
@@ -21,7 +22,8 @@
%endif
Name: bootc
Version: 1.1.5
# Ensure this local build overrides anything else.
Version: 99999.0.0
Release: 1%{?dist}
Summary: Bootable container system
@@ -84,17 +86,49 @@ Recommends: podman
%description -n system-reinstall-bootc
This package provides a utility to simplify reinstalling the current system to a given bootc image.
%if %{with tests}
%package tests
Summary: Integration tests for bootc
Requires: %{name} = %{version}-%{release}
%description tests
This package contains the integration test suite for bootc.
%endif
%global system_reinstall_bootc_install_podman_path %{_prefix}/lib/system-reinstall-bootc/install-podman
%if 0%{?container_build}
# Source is already at /src, no subdirectory
%global _buildsubdir .
%endif
%prep
%if ! 0%{?container_build}
%autosetup -p1 -a1
# Default -v vendor config doesn't support non-crates.io deps (i.e. git)
cp .cargo/vendor-config.toml .
%cargo_prep -N
cat vendor-config.toml >> .cargo/config.toml
rm vendor-config.toml
%else
# Container build: source already at _builddir (/src), nothing to extract
# RPM's %mkbuilddir creates a subdirectory; symlink it back to the source
cd ..
rm -rf %{name}-%{version}-build
ln -s . %{name}-%{version}-build
cd %{name}-%{version}-build
%endif
%build
export SYSTEM_REINSTALL_BOOTC_INSTALL_PODMAN_PATH=%{system_reinstall_bootc_install_podman_path}
%if 0%{?container_build}
# Container build: use cargo directly with cached dependencies
export CARGO_HOME=/var/roothome/.cargo
cargo build -j%{_smp_build_ncpus} --release %{?with_rhsm:--features rhsm} \
--bin=bootc --bin=system-reinstall-bootc \
%{?with_tests:--bin tests-integration}
make manpages
%else
# Build the main bootc binary
%if %new_cargo_macros
%cargo_build %{?with_rhsm:-f rhsm}
@@ -104,7 +138,6 @@ rm vendor-config.toml
# Build the system reinstallation CLI binary
%global cargo_args -p system-reinstall-bootc
export SYSTEM_REINSTALL_BOOTC_INSTALL_PODMAN_PATH=%{system_reinstall_bootc_install_podman_path}
%if %new_cargo_macros
# In cargo-rpm-macros, the cargo_build macro does flag processing,
# so we need to pass '--' to signify that cargo_args is not part
@@ -118,18 +151,24 @@ export SYSTEM_REINSTALL_BOOTC_INSTALL_PODMAN_PATH=%{system_reinstall_bootc_insta
%endif
make manpages
%endif
%if ! 0%{?container_build}
%cargo_vendor_manifest
# https://pagure.io/fedora-rust/rust-packaging/issue/33
sed -i -e '/https:\/\//d' cargo-vendor.txt
%cargo_license_summary
%{cargo_license} > LICENSE.dependencies
%endif
%install
%make_install INSTALL="install -p -c"
%if %{with ostree_ext}
make install-ostree-hooks DESTDIR=%{?buildroot}
%endif
%if %{with tests}
install -D -m 0755 target/release/tests-integration %{buildroot}%{_bindir}/bootc-integration-tests
%endif
mkdir -p %{buildroot}/%{dirname:%{system_reinstall_bootc_install_podman_path}}
cat >%{?buildroot}/%{system_reinstall_bootc_install_podman_path} <<EOF
#!/bin/bash
@@ -153,8 +192,10 @@ fi
%files -f bootcdoclist.txt
%license LICENSE-MIT
%license LICENSE-APACHE
%if ! 0%{?container_build}
%license LICENSE.dependencies
%license cargo-vendor.txt
%endif
%doc README.md
%{_bindir}/bootc
%{_prefix}/lib/bootc/
@@ -169,5 +210,10 @@ fi
%{_bindir}/system-reinstall-bootc
%{system_reinstall_bootc_install_podman_path}
%if %{with tests}
%files tests
%{_bindir}/bootc-integration-tests
%endif
%changelog
%autochangelog

44
contrib/packaging/build-rpm Executable file
View File

@@ -0,0 +1,44 @@
#!/bin/bash
# Build bootc RPM package from source
set -xeuo pipefail
# Version can be passed via RPM_VERSION env var (set by Dockerfile ARG)
# or defaults to the hardcoded value in the spec file
VERSION="${RPM_VERSION:-}"
# Determine output directory (defaults to /out)
OUTPUT_DIR="${1:-/out}"
SRC_DIR="${2:-/src}"
if [ -n "${VERSION}" ]; then
echo "Building RPM with version: ${VERSION}"
else
echo "Building RPM with version from spec file"
fi
# Create temporary rpmbuild directories
mkdir -p /tmp/rpmbuild/{RPMS,BUILDROOT,SPECS}
# If version is provided, create modified spec file; otherwise use original
if [ -n "${VERSION}" ]; then
sed "s/^Version:.*/Version: ${VERSION}/" \
"${SRC_DIR}/contrib/packaging/bootc.spec" > /tmp/rpmbuild/SPECS/bootc.spec
SPEC_FILE=/tmp/rpmbuild/SPECS/bootc.spec
else
SPEC_FILE="${SRC_DIR}/contrib/packaging/bootc.spec"
fi
# Build RPM
rpmbuild -bb \
--define "_topdir /tmp/rpmbuild" \
--define "_builddir ${SRC_DIR}" \
--define "container_build 1" \
--with tests \
--nocheck \
"${SPEC_FILE}"
# Copy built RPMs to output directory
ARCH=$(uname -m)
mkdir -p "${OUTPUT_DIR}"
cp /tmp/rpmbuild/RPMS/${ARCH}/*.rpm "${OUTPUT_DIR}/"
rm -rf /tmp/rpmbuild

View File

@@ -0,0 +1,46 @@
#!/bin/bash
# Configure rootfs type for bootc installation
set -xeuo pipefail
VARIANT="${1:-}"
ROOTFS="${2:-}"
# Support overriding the rootfs at build time
CONFIG_DIR="/usr/lib/bootc/install"
mkdir -p "${CONFIG_DIR}"
# Do we have an explicit build-time override? Then write it.
if [ -n "$ROOTFS" ]; then
cat > "${CONFIG_DIR}/80-rootfs-override.toml" <<EOF
[install.filesystem.root]
type = "$ROOTFS"
EOF
else
# Query the default rootfs
base_rootfs=$(bootc install print-configuration | jq -r '.filesystem.root.type // ""')
# No filesystem override set. If we're doing composefs, we need a FS that
# supports fsverity. If btrfs is available we'll pick that, otherwise ext4.
fs=
case "${VARIANT}" in
composefs*)
btrfs=$(grep -qEe '^CONFIG_BTRFS_FS' /usr/lib/modules/*/config && echo btrfs || true)
fs=${btrfs:-ext4}
;;
*)
# No explicit filesystem set and we're not using composefs. Default to xfs
# with the rationale that we're trying to get filesystem coverage across
# all the cases in general.
if [ -z "${base_rootfs}" ]; then
fs=xfs
fi
;;
esac
if [ -n "$fs" ]; then
cat > "${CONFIG_DIR}/80-ext4-composefs.toml" <<EOF
[install.filesystem.root]
type = "${fs}"
EOF
fi
fi

View File

@@ -0,0 +1,26 @@
#!/bin/bash
# Configure system for a specific bootc variant
set -xeuo pipefail
VARIANT="${1:-}"
if [ -z "$VARIANT" ]; then
# No variant specified, nothing to do
exit 0
fi
# Handle variant-specific configuration
case "${VARIANT}" in
*-sdboot)
# Install systemd-boot and remove bootupd
dnf -y install systemd-boot-unsigned
# Uninstall bootupd
rpm -e bootupd
rm -rf /usr/lib/bootupd/updates
# Clean up package manager caches
dnf clean all
rm -rf /var/cache /var/lib/{dnf,rhsm} /var/log/*
;;
# Future variants can be added here
# For Debian support, this could check package manager type and use apt instead
esac

View File

@@ -5,3 +5,5 @@ rustfmt
clippy
git-core
jq
# We now always build a package in the container build
rpm-build

View File

@@ -0,0 +1,15 @@
#!/bin/bash
# Install buildroot requirements for Fedora derivatives
set -xeuo pipefail
cd $(dirname $0)
. /usr/lib/os-release
case $ID in
centos|rhel) dnf config-manager --set-enabled crb;;
fedora) dnf -y install dnf-utils 'dnf5-command(builddep)';;
esac
# Handle version skew, xref https://gitlab.com/redhat/centos-stream/containers/bootc/-/issues/1174
dnf -y distro-sync ostree{,-libs} systemd
# Install base build requirements
dnf -y builddep bootc.spec
# And extra packages
grep -Ev -e '^#' fedora-extra.txt | xargs dnf -y install

View File

@@ -0,0 +1,24 @@
#!/bin/bash
# Install bootc RPM and perform post-installation setup
set -xeuo pipefail
RPM_DIR="${1:-/tmp}"
# Install the RPM package
# Use rpm -Uvh with --oldpackage to allow replacing with dev version
rpm -Uvh --oldpackage "${RPM_DIR}"/*.rpm
rm -f "${RPM_DIR}"/*.rpm
# Regenerate initramfs if we have initramfs-setup
if [ -x /usr/lib/bootc/initramfs-setup ]; then
kver=$(cd /usr/lib/modules && echo *)
env DRACUT_NO_XATTR=1 dracut -vf /usr/lib/modules/$kver/initramfs.img $kver
fi
# Only in this containerfile, inject a file which signifies
# this comes from this development image. This can be used in
# tests to know we're doing upstream CI.
touch /usr/lib/.bootc-dev-stamp
# Workaround for https://github.com/bootc-dev/bootc/issues/1546
rm -rf /root/buildinfo