fix(ci): read CentOS repository metadata from the mirrorlist

Both image jobs of run 37494541850 fail building the centos image:

    Downloading successful, but checksum doesn't match.
      Calculated: 76995e25878232ab...  Expected: 0ebc31a075dcba98...
    Error: Failed to download metadata for repo 'baseos':
      Cannot download repomd.xml: All mirrors were tried
    [filesystem] ERROR: 'dnf install -y epel-release' failed after 3 attempts

The retry added in d0b0b464e7 does not help and the log says why: the
Calculated digest is byte-identical on all three attempts, so dropping the dnf
metadata cache between them changes nothing. The stale bytes were never local.

Probing the sources directly settles where they come from. The metalink
advertises 0ebc31a075... for x86_64 BaseOS, matching the job's Expected value
hours later, while mirror.plusline.net and mirrors.xtom.de both serve a
repomd.xml hashing to 76995e25..., matching the job's Calculated value. The
mirrors agree with each other; the metalink is the outlier, and no retry can
reconcile a digest that no mirror serves.

The metalink exists to carry that digest alongside the mirror list, which
means the bytes and the hash for the same file arrive from two sources that
can drift apart. The mirrorlist offers the same mirrors without the second
source, so the failure class disappears rather than being retried. Mirror
redundancy is unchanged; no host is pinned.

Scoped to mirrors.centos.org. Fedora ships the same metalink shape, is not
affected by the desync, and keeps its repositories as upstream set them.
Distros without /etc/yum.repos.d exit before the rewrite.

Verified against the files the image actually ships, extracted from
centos-stream-repos-10.0-18.el10.noarch.rpm: all 23 metalink lines convert, 9
in centos.repo and 14 in centos-addons.repo. The three repositories that are
enabled there -- baseos, appstream and extras-sig-extras-common -- all resolve
through the mirrorlist endpoint.

This gives up the metalink's integrity check on repomd.xml itself. Packages
remain GPG-verified through gpgcheck.

No image has been built from this and no CI run has exercised it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5 committed 2026-10-06 21:27:08 +02:00
1 parent b76cc8e4ad
commit 7a836f934c
2 files changed
+17

No files matched your search

+1
View File
@@ -33,6 +33,7 @@ COPY scripts/install ${INFINITO_SRC_DIR}/scripts/install
RUN set -euo pipefail; \
source <(grep -hE '^INFINITO_(FILESYSTEM_INSTALL_SCRIPT|APT_UBUNTU_MIRRORS)=' "${INFINITO_SRC_DIR}/default.env"); \
INFINITO_APT_UBUNTU_MIRRORS="${INFINITO_APT_UBUNTU_MIRRORS:?}" /bin/bash "${INFINITO_SRC_DIR}/scripts/install/apt-mirrors.sh"; \
/bin/bash "${INFINITO_SRC_DIR}/scripts/install/dnf-mirrors.sh"; \
/bin/bash "${INFINITO_SRC_DIR}/${INFINITO_FILESYSTEM_INSTALL_SCRIPT:?}"
COPY roles/dev-python/files/shell ${INFINITO_SRC_DIR}/roles/dev-python/files/shell
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# CentOS' metalink carries its own sha512 for repomd.xml, so the digest and
# the bytes arrive from two sources that can disagree; when they do, every
# mirror fails the checksum and no retry clears it. The mirrorlist serves the
# same mirrors with no second digest to contradict them, giving up the
# metalink's integrity check on repomd.xml while packages stay GPG-verified.
# Fedora ships the same metalink shape unaffected, so it is left alone.
set -euo pipefail
shopt -s nullglob
repos=(/etc/yum.repos.d/*.repo)
if [[ ${#repos[@]} -eq 0 ]]; then
exit 0
fi
sed -i -E 's#^metalink=(https?://mirrors\.centos\.org)/metalink\?#mirrorlist=\1/mirrorlist?#' "${repos[@]}"