Files
computer-playbook/roles/update/files/shell/centos_mirror.sh
kevinveenbirkenbachandClaude Opus 5.5 4e060767f1 fix(update): resolve EPEL packages from dl.fedoraproject.org on CentOS
CentOS jobs also die on "Failed to download metadata for repo 'epel':
Cannot download repomd.xml ... All mirrors were tried" (feature/store-i18n
run 39658756830, Baserow#0 and Nextcloud#8 aarch64): the failing host's
librepo log shows mirrors that answered and then failed the checksum the
metalink expects, the stale-metalink signature already pinned away for
the CentOS Stream repos, plus TLS errors from two mirrors.

centos_mirror.sh now also rewrites the EPEL repo files: each section's
own commented `#baseurl=https://download.example/pub/epel/...` template
becomes the baseurl on dl.fedoraproject.org and the Fedora metalink line
goes. Using the file's template keeps the path variables of whichever
epel-release is installed (`$releasever${stream:+s}` on CentOS Stream,
`releasever_minor` in newer releases). A file whose metalinks lack that
template stops the script with an error instead of losing its source.

The Dockerfile runs the script again right after
scripts/install/filesystem.sh. Its first run precedes the EPEL install
(filesystem.sh adds epel-release for btrfs-progs), so the image shipped an
unpinned epel.repo, and the failing call, sys-svc-ssh's OpenSSH install,
runs before roles/update/tasks/centos.yml pins anything.

On CentOS Stream the template resolves to epel/10s/, which on
dl.fedoraproject.org serves the same aarch64 repomd.xml as epel/10.4/, the
only path the epel-10s metalink lists.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 20:36:48 +02:00

60 lines
2.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Param: none. Rewrites the CentOS Stream and EPEL repo files in /etc/yum.repos.d in place and prints the metalink repo or EPEL file of everything it pinned; prints nothing when there is nothing left to pin, exits 1 on an EPEL file whose metalinks lack their baseurl template.
set -euo pipefail
master="https://mirror.stream.centos.org"
repo_dir="/etc/yum.repos.d"
[[ -f "${repo_dir}/centos.repo" ]] || exit 0
pin() {
local metalink_repo="$1" path="$2" file
for file in "${repo_dir}/centos.repo" "${repo_dir}/centos-addons.repo"; do
[[ -f "${file}" ]] || continue
grep -q -E "^metalink=https://mirrors\.centos\.org/metalink\?repo=${metalink_repo}&" "${file}" || continue
sed -i -E "s|^metalink=https://mirrors\.centos\.org/metalink\?repo=${metalink_repo}&.*\$|baseurl=${master}/${path}/|" "${file}"
echo "${metalink_repo/\[\$\]stream/\$stream}"
done
}
declare -A directories=(
[baseos]=BaseOS
[appstream]=AppStream
[crb]=CRB
[highavailability]=HighAvailability
[nfv]=NFV
[rt]=RT
[resilientstorage]=ResilientStorage
)
for name in "${!directories[@]}"; do
directory="${directories[${name}]}"
pin "centos-${name}-[\$]stream" "\$stream/${directory}/\$basearch/os"
pin "centos-${name}-debug-[\$]stream" "\$stream/${directory}/\$basearch/debug/tree"
pin "centos-${name}-source-[\$]stream" "\$stream/${directory}/source/tree"
done
pin "centos-extras-sig-extras-common-[\$]stream" "SIGs/\$stream/extras/\$basearch/extras-common"
pin "centos-extras-sig-extras-common-source-[\$]stream" "SIGs/\$stream/extras/source/extras-common"
pin_epel() {
local file="$1" metalinks templates
metalinks="$(awk '/^metalink=https:\/\/mirrors\.fedoraproject\.org\// { n++ } END { print n + 0 }' "${file}")"
templates="$(awk '/^#baseurl=https:\/\/download\.example\/pub\/epel\// { n++ } END { print n + 0 }' "${file}")"
[[ "${metalinks}" -gt 0 ]] || return 0
if [[ "${templates}" -ne "${metalinks}" ]]; then
echo "ERROR: ${file} has ${metalinks} Fedora metalinks but ${templates} download.example baseurl templates" >&2
exit 1
fi
sed -i -E \
-e 's|^#baseurl=https://download\.example/pub/epel/|baseurl=https://dl.fedoraproject.org/pub/epel/|' \
-e '/^metalink=https:\/\/mirrors\.fedoraproject\.org\//d' \
"${file}"
echo "${file##*/}"
}
for file in "${repo_dir}"/epel*.repo; do
[[ -f "${file}" ]] || continue
pin_epel "${file}"
done