From 8bf20c670c2d5b413ec39ee81cd352bbb55a3c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Lehmann?= Date: Fri, 1 Aug 2025 19:28:55 +0200 Subject: [PATCH 1/4] Remove XCP-ng 7 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gaëtan Lehmann --- src/xcp_ng_dev/build.sh | 4 -- src/xcp_ng_dev/files/Dockerfile-7.x | 78 ----------------------------- 2 files changed, 82 deletions(-) delete mode 100644 src/xcp_ng_dev/files/Dockerfile-7.x diff --git a/src/xcp_ng_dev/build.sh b/src/xcp_ng_dev/build.sh index c2300fb..0328d2f 100755 --- a/src/xcp_ng_dev/build.sh +++ b/src/xcp_ng_dev/build.sh @@ -81,10 +81,6 @@ case "$1" in DOCKERFILE=files/Dockerfile-8.x : ${PLATFORM:=linux/amd64} ;; - 7.*) - DOCKERFILE=Dockerfile-7.x - : ${PLATFORM:=linux/amd64} - ;; *) echo >&2 "Unsupported release '$1'" exit 1 diff --git a/src/xcp_ng_dev/files/Dockerfile-7.x b/src/xcp_ng_dev/files/Dockerfile-7.x deleted file mode 100644 index f74ad6f..0000000 --- a/src/xcp_ng_dev/files/Dockerfile-7.x +++ /dev/null @@ -1,78 +0,0 @@ -ARG CENTOS_VERSION=7.2.1511 - -FROM centos:${CENTOS_VERSION} - -ARG CUSTOM_BUILDER_UID="" -ARG CUSTOM_BUILDER_GID="" - -# Remove all repositories -RUN rm /etc/yum.repos.d/* - -# Add only the specific CentOS 7.2 repositories, because that's what XS used for the majority of packages -ARG CENTOS_VERSION -COPY files/CentOS-Vault.repo.in /etc/yum.repos.d/CentOS-Vault-7.2.repo -RUN sed -e "s/@CENTOS_VERSION@/${CENTOS_VERSION}/g" -i /etc/yum.repos.d/CentOS-Vault-7.2.repo - -# Add our repositories -# Repository file depends on the target version of XCP-ng, and is pre-processed by build.sh -ARG XCP_NG_BRANCH=7.6 -COPY files/xcp-ng.repo.7.x.in /etc/yum.repos.d/xcp-ng.repo -RUN sed -e "s/@XCP_NG_BRANCH@/${XCP_NG_BRANCH}/g" -i /etc/yum.repos.d/xcp-ng.repo - -# Fix invalid rpmdb checksum error with overlayfs, see https://github.com/docker/docker/issues/10180 -RUN yum install -y yum-plugin-ovl - -# Use priorities so that packages from our repositories are preferred over those from CentOS repositories -RUN yum install -y yum-plugin-priorities - -# Update -RUN yum update -y - -# Build requirements -RUN yum install -y --exclude=gcc-xs \ - gcc \ - gcc-c++ \ - git \ - git-lfs \ - make \ - mercurial \ - mock \ - rpm-build \ - rpm-python \ - sudo \ - yum-utils \ - epel-release - -# Niceties -RUN yum install -y \ - vim \ - wget \ - which - -# clean package cache to avoid download errors -RUN yum clean all - -# OCaml in XS is slightly older than in CentOS -RUN sed -i "/gpgkey/a exclude=ocaml*" /etc/yum.repos.d/Cent* /etc/yum.repos.d/epel* - -# Set up the builder user -RUN bash -c ' \ - OPTS=(); \ - if [ -n "${CUSTOM_BUILDER_UID}" ]; then \ - OPTS+=("-u" "${CUSTOM_BUILDER_UID}"); \ - fi; \ - if [ -n "${CUSTOM_BUILDER_GID}" ]; then \ - OPTS+=("-g" "${CUSTOM_BUILDER_GID}"); \ - if ! getent group "${CUSTOM_BUILDER_GID}" >/dev/null; then \ - groupadd -g "${CUSTOM_BUILDER_GID}" builder; \ - fi; \ - fi; \ - useradd "${OPTS[@]}" builder; \ - ' \ - && echo "builder:builder" | chpasswd \ - && echo "builder ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers \ - && usermod -G mock builder - -RUN mkdir -p /usr/local/bin -COPY files/init-container.sh /usr/local/bin/init-container.sh -COPY files/rpmmacros /home/builder/.rpmmacros From 1f232a5f59ef6dd264d0c2fdabcbdee5f76428da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Lehmann?= Date: Thu, 24 Jul 2025 14:46:00 +0200 Subject: [PATCH 2/4] Don't include the uid/gid of the host user in the image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This way the image is usable by everybody, independantly of its ids. With docker, we modify the builder user in the entrypoint to match the uid:gid of the user launching the container, and then continue with the builder user thanks to gosu. With podman we use the `--userns` option to map the builder user to the user on the system. I haven't found a way with podman to use the same mechanism as in docker, and vis versa. Signed-off-by: Gaëtan Lehmann --- src/xcp_ng_dev/build.sh | 22 -------------------- src/xcp_ng_dev/cli.py | 14 +++++++++---- src/xcp_ng_dev/files/Dockerfile-8.x | 32 +++++++++++------------------ src/xcp_ng_dev/files/Dockerfile-9.x | 29 +++++++++----------------- src/xcp_ng_dev/files/entrypoint.sh | 23 +++++++++++++++++++++ 5 files changed, 55 insertions(+), 65 deletions(-) create mode 100755 src/xcp_ng_dev/files/entrypoint.sh diff --git a/src/xcp_ng_dev/build.sh b/src/xcp_ng_dev/build.sh index 0328d2f..30f64a8 100755 --- a/src/xcp_ng_dev/build.sh +++ b/src/xcp_ng_dev/build.sh @@ -67,8 +67,6 @@ fi cd $(dirname "$0") -CUSTOM_ARGS=() - ALMA_VERSION= CENTOS_VERSION= case "$1" in @@ -87,28 +85,8 @@ case "$1" in ;; esac -CUSTOM_UID="$(id -u)" -CUSTOM_GID="$(id -g)" - -if [ "${CUSTOM_UID}" -eq 0 ] || [ "${CUSTOM_GID}" -eq 0 ]; then - if [ -z "${SUDO_GID}" ] || [ -z "${SUDO_UID}" ] || [ -z "${SUDO_USER}" ] || \ - [ -z "${SUDO_COMMAND}" ] || [ "${SUDO_GID}" -eq 0 ] || [ "${SUDO_UID}" -eq 0 ]; then - echo -e "[ERROR] This operation cannot be performed by the 'root' user directly:" - echo -e "\tplease use an unprivileged user (eventually with 'sudo')" - exit 1 - fi - CUSTOM_UID="${SUDO_UID}" - CUSTOM_GID="${SUDO_GID}" -fi - -# Support for seamless use of current host user -# and Docker user "builder" inside the image -CUSTOM_ARGS+=( "--build-arg" "CUSTOM_BUILDER_UID=${CUSTOM_UID}" ) -CUSTOM_ARGS+=( "--build-arg" "CUSTOM_BUILDER_GID=${CUSTOM_GID}" ) - "$RUNNER" build \ --platform "$PLATFORM" \ - "${CUSTOM_ARGS[@]}" \ -t ghcr.io/xcp-ng/xcp-ng-build-env:${1} \ --build-arg XCP_NG_BRANCH=${1} \ --ulimit nofile=1024 \ diff --git a/src/xcp_ng_dev/cli.py b/src/xcp_ng_dev/cli.py index e6a3ef1..642d543 100755 --- a/src/xcp_ng_dev/cli.py +++ b/src/xcp_ng_dev/cli.py @@ -144,11 +144,17 @@ def buildparser(): return parser def container(args): - docker_args = [RUNNER, "run", "-i", "-t", - "-u", "builder", - ] + docker_args = [RUNNER, "run", "-i", "-t"] + if is_podman(RUNNER): - docker_args += ["--userns=keep-id", "--security-opt", "label=disable"] + # With podman we use the `--userns` option to map the builder user to the user on the system. + # The container will start with that user and not as root as with docker + docker_args += ["--userns=keep-id:uid=1000,gid=1000", "--security-opt", "label=disable"] + else: + # With docker, the container starts as root and modify the builder user in the entrypoint to + # match the uid:gid of the user launching the container, and then continue with the builder + # user thanks to gosu. + docker_args += ["-e", f'BUILDER_UID={os.getuid()}', "-e", f'BUILDER_GID={os.getgid()}'] # common args if args.no_exit: diff --git a/src/xcp_ng_dev/files/Dockerfile-8.x b/src/xcp_ng_dev/files/Dockerfile-8.x index d087e4d..f3d35d2 100644 --- a/src/xcp_ng_dev/files/Dockerfile-8.x +++ b/src/xcp_ng_dev/files/Dockerfile-8.x @@ -2,22 +2,19 @@ ARG CENTOS_VERSION=7.5.1804 FROM centos:${CENTOS_VERSION} -ARG CUSTOM_BUILDER_UID="" -ARG CUSTOM_BUILDER_GID="" - # Remove all repositories RUN rm /etc/yum.repos.d/* # Add only the specific CentOS 7.5 repositories, because that's what XS used for the majority of packages ARG CENTOS_VERSION COPY files/CentOS-Vault.repo.in /etc/yum.repos.d/CentOS-Vault-7.5.repo -RUN sed -e "s/@CENTOS_VERSION@/${CENTOS_VERSION}/g" -i /etc/yum.repos.d/CentOS-Vault-7.5.repo +RUN sed -i -e "s/@CENTOS_VERSION@/${CENTOS_VERSION}/g" /etc/yum.repos.d/CentOS-Vault-7.5.repo # Add our repositories # Repository file depends on the target version of XCP-ng, and is pre-processed by build.sh ARG XCP_NG_BRANCH=8.3 COPY files/xcp-ng.repo.8.x.in /etc/yum.repos.d/xcp-ng.repo -RUN sed -e "s/@XCP_NG_BRANCH@/${XCP_NG_BRANCH}/g" -i /etc/yum.repos.d/xcp-ng.repo +RUN sed -i -e "s/@XCP_NG_BRANCH@/${XCP_NG_BRANCH}/g" /etc/yum.repos.d/xcp-ng.repo # Install GPG key RUN curl -sSf https://xcp-ng.org/RPM-GPG-KEY-xcpng -o /etc/pki/rpm-gpg/RPM-GPG-KEY-xcpng @@ -58,23 +55,18 @@ RUN yum clean all # OCaml in XS may be older than in CentOS RUN sed -i "/gpgkey/a exclude=ocaml*" /etc/yum.repos.d/Cent* /etc/yum.repos.d/epel* -# Set up the builder user -RUN bash -c ' \ - OPTS=(); \ - if [ -n "${CUSTOM_BUILDER_UID}" ]; then \ - OPTS+=("-u" "${CUSTOM_BUILDER_UID}"); \ - fi; \ - if [ -n "${CUSTOM_BUILDER_GID}" ]; then \ - OPTS+=("-g" "${CUSTOM_BUILDER_GID}"); \ - if ! getent group "${CUSTOM_BUILDER_GID}" >/dev/null; then \ - groupadd -g "${CUSTOM_BUILDER_GID}" builder; \ - fi; \ - fi; \ - useradd "${OPTS[@]}" builder; \ - ' \ +# create the builder user +RUN groupadd -g 1000 builder \ + && useradd -u 1000 -g 1000 builder \ && echo "builder:builder" | chpasswd \ && echo "builder ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers RUN mkdir -p /usr/local/bin +RUN curl -fsSL "https://github.com/tianon/gosu/releases/download/1.17/gosu-amd64" -o /usr/local/bin/gosu \ + && chmod +x /usr/local/bin/gosu COPY files/init-container.sh /usr/local/bin/init-container.sh -COPY files/rpmmacros /home/builder/.rpmmacros +COPY files/entrypoint.sh /usr/local/bin/entrypoint.sh +COPY --chown=builder:builder files/rpmmacros /home/builder/.rpmmacros + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +CMD ["bash"] diff --git a/src/xcp_ng_dev/files/Dockerfile-9.x b/src/xcp_ng_dev/files/Dockerfile-9.x index e6a34ce..a3e79ba 100644 --- a/src/xcp_ng_dev/files/Dockerfile-9.x +++ b/src/xcp_ng_dev/files/Dockerfile-9.x @@ -1,8 +1,5 @@ FROM ghcr.io/almalinux/10-base:10.0 -ARG CUSTOM_BUILDER_UID="" -ARG CUSTOM_BUILDER_GID="" - # Add our repositories # temporary bootstrap repository COPY files/xcp-ng-8.99.repo /etc/yum.repos.d/xcp-ng.repo @@ -55,25 +52,19 @@ RUN dnf config-manager --enable crb # workaround sudo not working (e.g. in podman 4.9.3 in Ubuntu 24.04) RUN chmod 0400 /etc/shadow -# Set up the builder user -RUN bash -c ' \ - OPTS=(); \ - if [ -n "${CUSTOM_BUILDER_UID}" ]; then \ - OPTS+=("-u" "${CUSTOM_BUILDER_UID}"); \ - fi; \ - if [ -n "${CUSTOM_BUILDER_GID}" ]; then \ - OPTS+=("-g" "${CUSTOM_BUILDER_GID}"); \ - if ! getent group "${CUSTOM_BUILDER_GID}" >/dev/null; then \ - groupadd -g "${CUSTOM_BUILDER_GID}" builder; \ - fi; \ - fi; \ - useradd "${OPTS[@]}" builder; \ - ' \ +# create the builder user +RUN groupadd -g 1000 builder \ + && useradd -u 1000 -g 1000 builder \ && echo "builder:builder" | chpasswd \ && echo "builder ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers RUN mkdir -p /usr/local/bin +RUN curl -fsSL "https://github.com/tianon/gosu/releases/download/1.17/gosu-amd64" -o /usr/local/bin/gosu \ + && chmod +x /usr/local/bin/gosu COPY files/init-container.sh /usr/local/bin/init-container.sh - +COPY files/entrypoint.sh /usr/local/bin/entrypoint.sh # FIXME: check it we really need any of this -# COPY files/rpmmacros /home/builder/.rpmmacros +# COPY --chown=builder:builder files/rpmmacros /home/builder/.rpmmacros + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +CMD ["bash"] diff --git a/src/xcp_ng_dev/files/entrypoint.sh b/src/xcp_ng_dev/files/entrypoint.sh new file mode 100755 index 0000000..23781bd --- /dev/null +++ b/src/xcp_ng_dev/files/entrypoint.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -e +if [ -n "${SCRIPT_DEBUG}" ]; then + set -x +fi + +if [ "${BUILDER_UID}" ]; then + # BUILDER_UID is defined, update the builder ids, and continue with the builder user + if [ "${BUILDER_GID}" != "1000" ]; then + groupmod -g "${BUILDER_GID}" builder + fi + if [ "${BUILDER_UID}" != "1000" ]; then + usermod -u "${BUILDER_UID}" -g "${BUILDER_GID}" builder + fi + find ~builder -maxdepth 1 -type f | xargs chown builder:builder + # use gosu to switch user to make the command run the root process and properly + # deal with signals + exec /usr/local/bin/gosu builder "$@" +else + # no BUILDER_ID, just continue as the current user + exec "$@" +fi From 8b03843002606b78aaae0aa00e98df913607d04f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Lehmann?= Date: Thu, 24 Jul 2025 15:46:04 +0200 Subject: [PATCH 3/4] Use ghcr.io to store the images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The images are always built, but only pushed to the registry when running on the master branch. Signed-off-by: Gaëtan Lehmann --- .github/workflows/docker.yml | 83 ++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..bd92760 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,83 @@ +name: Build and Push Docker Image to GHCR + +on: push + +permissions: + contents: read # Required to checkout the repo code + packages: write # Required to push packages to GHCR + +jobs: + xcp-ng-build-env-82: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: docker/setup-buildx-action@v3 + with: + driver: docker-container + - uses: docker/login-action@v3 + if: github.ref == 'refs/heads/master' + with: + registry: ghcr.io + username: ${{ github.actor }} # Uses the GitHub user/org name that triggered the workflow + password: ${{ secrets.GITHUB_TOKEN }} # Automatically provided by GitHub + - uses: docker/build-push-action@v5 # Using v5 for latest features + with: + context: ./src/xcp_ng_dev/ + file: ./src/xcp_ng_dev/files/Dockerfile-8.x + push: ${{ github.ref == 'refs/heads/master' }} + tags: ghcr.io/${{ github.repository }}:8.2 + cache-from: type=gha,scope=${{ github.ref_name }}-82 # Cache layers to speed up builds + cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-82 # Store layers in cache for future builds + build-args: | + XCP_NG_BRANCH=8.2 + platforms: | + linux/amd64 + + xcp-ng-build-env-83: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: docker/setup-buildx-action@v3 + with: + driver: docker-container + - uses: docker/login-action@v3 + if: github.ref == 'refs/heads/master' + with: + registry: ghcr.io + username: ${{ github.actor }} # Uses the GitHub user/org name that triggered the workflow + password: ${{ secrets.GITHUB_TOKEN }} # Automatically provided by GitHub + - uses: docker/build-push-action@v5 # Using v5 for latest features + with: + context: ./src/xcp_ng_dev/ + file: ./src/xcp_ng_dev/files/Dockerfile-8.x + push: ${{ github.ref == 'refs/heads/master' }} + tags: ghcr.io/${{ github.repository }}:8.3 + cache-from: type=gha,scope=${{ github.ref_name }}-83 # Cache layers to speed up builds + cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-83 # Store layers in cache for future builds + platforms: | + linux/amd64 + + # TODO: uncomment once we have a public xcp-ng 9.0 repository + # xcp-ng-build-env-90: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # - uses: docker/setup-buildx-action@v3 + # with: + # driver: docker-container + # - uses: docker/login-action@v3 + # if: github.ref == 'refs/heads/master' + # with: + # registry: ghcr.io + # username: ${{ github.actor }} # Uses the GitHub user/org name that triggered the workflow + # password: ${{ secrets.GITHUB_TOKEN }} # Automatically provided by GitHub + # - uses: docker/build-push-action@v5 # Using v5 for latest features + # with: + # context: ./src/xcp_ng_dev/ + # file: ./src/xcp_ng_dev/files/Dockerfile-9.x + # platforms: | + # linux/amd64/v2 + # push: ${{ github.ref == 'refs/heads/master' }} + # tags: ghcr.io/${{ github.repository }}:9.0 + # cache-from: type=gha,scope=${{ github.ref_name }}-90 # Cache layers to speed up builds + # cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-90 # Store layers in cache for future builds From 1c18d26260700a14917a80185c15a9f1aab151e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Lehmann?= Date: Fri, 25 Jul 2025 10:41:38 +0200 Subject: [PATCH 4/4] DNF update, install and clean in the same layer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit for a significantly smaller image size. Before: ghcr.io/xcp-ng/xcp-ng-build-env 8.2 e985e704c252 10 minutes ago 1.03 GB ghcr.io/xcp-ng/xcp-ng-build-env 8.3 b557dcb6d541 11 minutes ago 1.14 GB ghcr.io/xcp-ng/xcp-ng-build-env 9.0 c738df7d5577 11 minutes ago 857 MB After: ghcr.io/xcp-ng/xcp-ng-build-env 8.2 a9a91fa03db8 7 seconds ago 491 MB ghcr.io/xcp-ng/xcp-ng-build-env 8.3 a36b1399ac01 About a minute ago 557 MB ghcr.io/xcp-ng/xcp-ng-build-env 9.0 78011dcbd6f3 11 minutes ago 708 MB Signed-off-by: Gaëtan Lehmann --- src/xcp_ng_dev/files/Dockerfile-8.x | 33 +++++++++++-------------- src/xcp_ng_dev/files/Dockerfile-9.x | 37 +++++++++++++---------------- 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/src/xcp_ng_dev/files/Dockerfile-8.x b/src/xcp_ng_dev/files/Dockerfile-8.x index f3d35d2..b6e404c 100644 --- a/src/xcp_ng_dev/files/Dockerfile-8.x +++ b/src/xcp_ng_dev/files/Dockerfile-8.x @@ -19,18 +19,15 @@ RUN sed -i -e "s/@XCP_NG_BRANCH@/${XCP_NG_BRANCH}/g" /etc/yum.repos.d/xcp-ng # Install GPG key RUN curl -sSf https://xcp-ng.org/RPM-GPG-KEY-xcpng -o /etc/pki/rpm-gpg/RPM-GPG-KEY-xcpng -# Fix invalid rpmdb checksum error with overlayfs, see https://github.com/docker/docker/issues/10180 -# (still needed?) -RUN yum install -y yum-plugin-ovl - -# Use priorities so that packages from our repositories are preferred over those from CentOS repositories -RUN yum install -y yum-plugin-priorities - # Update -RUN yum update -y - -# Common build requirements -RUN yum install -y \ +RUN yum update -y \ + # Fix invalid rpmdb checksum error with overlayfs, see https://github.com/docker/docker/issues/10180 + # (still needed?) + && yum install -y yum-plugin-ovl \ + # Use priorities so that packages from our repositories are preferred over those from CentOS repositories + && yum install -y yum-plugin-priorities \ + # Common build requirements + && yum install -y \ gcc \ gcc-c++ \ git \ @@ -41,16 +38,14 @@ RUN yum install -y \ sudo \ yum-utils \ epel-release \ - epel-rpm-macros - -# Niceties -RUN yum install -y \ + epel-rpm-macros \ + # Niceties + && yum install -y \ vim \ wget \ - which - -# clean package cache to avoid download errors -RUN yum clean all + which \ + # clean package cache to avoid download errors + && yum clean all # OCaml in XS may be older than in CentOS RUN sed -i "/gpgkey/a exclude=ocaml*" /etc/yum.repos.d/Cent* /etc/yum.repos.d/epel* diff --git a/src/xcp_ng_dev/files/Dockerfile-9.x b/src/xcp_ng_dev/files/Dockerfile-9.x index a3e79ba..be318d0 100644 --- a/src/xcp_ng_dev/files/Dockerfile-9.x +++ b/src/xcp_ng_dev/files/Dockerfile-9.x @@ -10,10 +10,9 @@ COPY files/Alma10-devel.repo /etc/yum.repos.d/ RUN curl -sSf https://xcp-ng.org/RPM-GPG-KEY-xcpng -o /etc/pki/rpm-gpg/RPM-GPG-KEY-xcpng # Update -RUN dnf update -y - -# Common build requirements -RUN dnf install -y \ +RUN dnf update -y \ + # Common build requirements + && dnf install -y \ gcc \ gcc-c++ \ git \ @@ -23,28 +22,24 @@ RUN dnf install -y \ python3-rpm \ sudo \ dnf-plugins-core \ - epel-release - -# EPEL: needs epel-release installed first -RUN dnf install -y \ + epel-release \ + # EPEL: needs epel-release installed first + && dnf install -y \ epel-rpm-macros \ - almalinux-git-utils - -# Niceties -RUN dnf install -y \ + almalinux-git-utils \ + # Niceties + && dnf install -y \ bash-completion \ vim \ wget \ - which - -# clean package cache to avoid download errors -RUN yum clean all - -# -release*, to be commented out to boostrap the build-env until it gets built -# FIXME: isn't it already pulled as almalinux-release when available? -RUN dnf install -y \ + which \ + # -release*, to be commented out to boostrap the build-env until it gets built + # FIXME: isn't it already pulled as almalinux-release when available? + && dnf install -y \ xcp-ng-release \ - xcp-ng-release-presets + xcp-ng-release-presets \ + # clean package cache to avoid download errors + && yum clean all # enable repositories commonly required to build RUN dnf config-manager --enable crb