Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/build-base-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ jobs:
- debian-11
- debian-12
- debian-13
- rhel-8
- rhel-9
- rhel-10
steps:
- name: Checkout repository
uses: actions/checkout@v6
Expand Down
5 changes: 4 additions & 1 deletion build-in-container-inner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@ for repo in $repos; do
# regardless of the host directory layout.
# Exclude acceptance test workdirs — they contain broken symlinks left
# over from previous test runs and are not needed for building.
# Also skip node_modules/vendor for hub builds.
if [ -d "$src" ] || [ -L "$src" ]; then
echo "Syncing $repo..."
sudo rsync -aL --exclude='config.cache' --exclude='workdir' --chown="$(id -u):$(id -g)" "$src/" "$BASEDIR/$repo/"
sudo rsync -aL --exclude='config.cache' --exclude='workdir' \
--exclude='node_modules' --exclude='vendor' \
--chown="$(id -u):$(id -g)" "$src/" "$BASEDIR/$repo/"
else
echo "ERROR: Required repository $repo not found" >&2
exit 1
Expand Down
43 changes: 31 additions & 12 deletions build-in-container.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,22 @@ None of the above arguments are required for `--update`.

## Supported platforms

| Name | Base image |
| ----------- | -------------- |
| `ubuntu-20` | `ubuntu:20.04` |
| `ubuntu-22` | `ubuntu:22.04` |
| `ubuntu-24` | `ubuntu:24.04` |
| `debian-11` | `debian:11` |
| `debian-12` | `debian:12` |
| `debian-13` | `debian:13` |
| Name | Base image |
| ----------- | -------------------------- |
| `ubuntu-20` | `ubuntu:20.04` |
| `ubuntu-22` | `ubuntu:22.04` |
| `ubuntu-24` | `ubuntu:24.04` |
| `debian-11` | `debian:11` |
| `debian-12` | `debian:12` |
| `debian-13` | `debian:13` |
| `rhel-8` | `rockylinux/rockylinux:8` |
| `rhel-9` | `rockylinux/rockylinux:9` |
| `rhel-10` | `rockylinux/rockylinux:10` |

RHEL packages are built on Rocky Linux base images. The build scripts detect
`OS=rhel` from `/etc/redhat-release` (which reports `Rocky Linux release ...`),
so the produced `.rpm`s are ordinary Red Hat / rpm packages. AlmaLinux is _not_
recognized by `build-scripts/detect-environment`, which is why Rocky is used.

Adding a new Debian/Ubuntu platform requires a new entry in `platforms.json`
and adding the platform name to the matrix in
Expand All @@ -85,8 +93,17 @@ The new entry in `platforms.json` needs:
--platform <new-platform>` and it will fetch the current digest from
Docker Hub and write it into `platforms.json`.

Adding a non-debian based platform (e.g.,
RHEL/CentOS) requires a new `container/Dockerfile.rhel` plus platform entries.
Adding another RHEL-family platform (a new Rocky/RHEL major version) works the
same way: add a `platforms.json` entry with `"dockerfile": "Dockerfile.rhel"`
and a matrix entry, then set any per-version `extra_build_args` — `CRB_REPO`
(`powertools` on 8, `crb` on 9+), `PHP_MODULE_STREAM` (`remi-8.3` where the
distro's default PHP is older than 8.3; RHEL 10 already ships 8.3), and
`EXTRA_PKGS` for version-specific packages. Note that `--update-sha` also works
for the namespaced `rockylinux/rockylinux` base images, not just official
Docker Hub library images.

Adding an entirely different, non-RHEL/non-Debian platform family (e.g. SUSE)
would require a new `container/Dockerfile.<family>` plus platform entries.

## How it works

Expand All @@ -100,8 +117,10 @@ The system has three components:
source repos from the read-only mount, then calls the existing build scripts
in order.

3. **`container/Dockerfile.debian`** -- parameterized Dockerfile shared by all
Debian/Ubuntu platforms via a `BASE_IMAGE` build arg.
3. **`container/Dockerfile.debian`** and **`container/Dockerfile.rhel`** --
parameterized Dockerfiles shared across platforms of the same family via a
`BASE_IMAGE` build arg (plus per-platform `extra_build_args` in
`platforms.json`, e.g. the CRB repo name and PHP module stream for RHEL).

### Container mounts

Expand Down
7 changes: 5 additions & 2 deletions build-in-container.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,12 @@ def update_platform_versions(platform_name=None):
def latest_base_image_digest(base_image):
"""Fetch current manifest digest from Docker Hub for a base image."""
# Docker Hub's v2 API path requires a namespace. Official images (ubuntu,
# debian, ...) live under "library/".
# debian, ...) carry no namespace and live under "library/"; images that
# already have an "org/name" namespace (e.g. rockylinux/rockylinux) are
# used as-is.
repo, tag = base_image.rsplit(":", 1)
repo = f"library/{repo}"
if "/" not in repo:
repo = f"library/{repo}"

# The v2 API requires a bearer token even for anonymous public pulls.
token_url = (
Expand Down
64 changes: 64 additions & 0 deletions container/Dockerfile.rhel
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
ARG BASE_IMAGE=rockylinux/rockylinux:9

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally we will use these to build our packages so it seems we should use ubi/rhel images and not rocky.

FROM ${BASE_IMAGE}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should duplicate in a different way what we do in the build host setup. I would be fine with choosing either policy or scripts but not both.


# allow older packages when the newest has unmet deps (as build hosts do).
RUN echo "best=False" >> /etc/dnf/dnf.conf

# Enable CRB (crb on 9+, powertools on 8) + EPEL for the -devel/build packages.
ARG CRB_REPO=crb
RUN dnf install -y dnf-plugins-core epel-release \
&& dnf config-manager --set-enabled ${CRB_REPO} \
&& dnf clean all

# Deps like zlib build without full debug symbols; disable debuginfo extraction
# so rpm doesn't abort with "No debugging symbols". We don't ship debuginfo here.
RUN echo '%debug_package %{nil}' > /etc/rpm/macros.cfengine-nodebug

# Build toolchain (see redhat section of ci/cfengine-build-host-setup.cf).
# "Development Tools" provides gcc, make, autotools, rpm-build, core perl, etc.
RUN dnf groupinstall -y "Development Tools" \
&& dnf install -y \
gcc-c++ pam-devel ncurses ncurses-devel expat expat-devel gettext \
rpm-build-libs selinux-policy selinux-policy-devel \
pkgconf pkgconf-pkg-config \
perl perl-Module-Load-Conditional perl-ExtUtils-MakeMaker perl-IPC-Cmd \
perl-IO-Compress \
python3 python3-pip python3-devel \
git rsync wget which psmisc unzip diffutils file sudo \
&& dnf clean all

# Hub tools: Node 20 (system nodejs too old for the node: protocol) + less.
RUN curl -fsSL https://rpm.nodesource.com/setup_20.x | bash - \
&& dnf install -y nodejs \
&& dnf clean all
RUN npm install -g less

ARG PHP_MODULE_STREAM=""
RUN if [ -n "${PHP_MODULE_STREAM}" ]; then \
dnf install -y https://rpms.remirepo.net/enterprise/remi-release-$(rpm -E %rhel).rpm \
&& dnf module reset -y php \
&& dnf module enable -y php:${PHP_MODULE_STREAM}; \
fi \
&& dnf install -y php-cli php-xml php-mbstring \
&& (dnf install -y php-json || true) \
&& (dnf install -y php-zip || dnf install -y php-pecl-zip || true) \
&& dnf clean all
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer.phar

# Rust + protobuf for the cargo-based leech2 dep (prebuilt tarballs, shared with Debian).
COPY --from=ci linux-install-protobuf.sh linux-install-rust.sh /tmp/
RUN /tmp/linux-install-protobuf.sh
RUN /tmp/linux-install-rust.sh

# Per-version extras (rhel-8: cfbs py3_shebang_fix macro; rhel-10: patch).
RUN if [ -n "${EXTRA_PKGS}" ]; then dnf install -y ${EXTRA_PKGS} && dnf clean all; fi

# Build user with passwordless sudo (needed by install-dependencies, package, etc.)
RUN useradd -m -s /bin/bash builder \
&& echo "builder ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/builder

USER builder
WORKDIR /home/builder

# Pre-create so a volume mounted here is owned by builder, not root.
RUN mkdir -p /home/builder/build
32 changes: 32 additions & 0 deletions platforms.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,37 @@
"base_image": "debian:13",
"base_image_sha": "sha256:d07d1b51c39f51188e60be9b64e6bf769fa94e187f092bc32b91305cfa34ba5a",
"dockerfile": "Dockerfile.debian"
},
"rhel-8": {
"image_name": "cfengine-builder-rhel-8",
"image_version": "latest",
"base_image": "rockylinux/rockylinux:8",
"base_image_sha": "sha256:e8a49c5403b687db05d4d67333fa45808fbe74f36e683cec7abb1f7d0f2338c6",
"dockerfile": "Dockerfile.rhel",
"extra_build_args": {
"CRB_REPO": "powertools",
"PHP_MODULE_STREAM": "remi-8.3",
"EXTRA_PKGS": "python3-rpm-macros platform-python-devel"
}
},
"rhel-9": {
"image_name": "cfengine-builder-rhel-9",
"image_version": "latest",
"base_image": "rockylinux/rockylinux:9",
"base_image_sha": "sha256:8101994123cf3d0a8fee517bee7f39e555c7d92bd2d9eb3303cc988a0eeed00f",
"dockerfile": "Dockerfile.rhel",
"extra_build_args": {
"PHP_MODULE_STREAM": "remi-8.3"
}
},
"rhel-10": {
"image_name": "cfengine-builder-rhel-10",
"image_version": "latest",
"base_image": "rockylinux/rockylinux:10",
"base_image_sha": "sha256:827d37bc128288ccf160ee318bb3cb92d591164cb217e92f8bc61e3982ae1834",
"dockerfile": "Dockerfile.rhel",
"extra_build_args": {
"EXTRA_PKGS": "patch"
}
}
}
Loading