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>
5.6 KiB
Package update
Description
Operating-system package managers such as apt, pacman and dnf keep installed software in sync with their upstream distribution repositories. Each one ships with a different command surface but they all serve the same goal: refresh the index and upgrade every installed package on the host.
Overview
This role refreshes the package index and upgrades every installed package on
the host. tasks/main.yml reads ansible_facts['distribution'] and dispatches
to one task file per package-manager family. Debian and Ubuntu both use
apt, so they share a single task file; Fedora and CentOS both use dnf, and
CentOS reaches fedora.yml through centos.yml. A separate unsupported.yml fails loudly with a clear
message when a host runs a distribution that this role does not yet cover.
ansible_facts['distribution'] |
Task file | Module |
|---|---|---|
Archlinux |
arch.yml |
community.general.pacman |
Debian / Ubuntu |
debian.yml |
ansible.builtin.apt |
Fedora |
fedora.yml |
ansible.builtin.dnf |
CentOS |
centos.yml |
ansible.builtin.dnf |
| anything else | unsupported.yml |
ansible.builtin.fail |
centos.yml first runs centos_mirror.sh, which replaces every metalink= of the CentOS Stream repo files with a baseurl= on mirror.stream.centos.org and every metalink= of the EPEL repo files with the file's own baseurl template on dl.fedoraproject.org, and then includes fedora.yml. The Dockerfile runs the same script before its first dnf call, so the CentOS dev and swarm-node images resolve against the same source.
Cosmos
The diagram places Package update in the Infinito.Nexus cosmos: the components it deploys (capabilities), the central services it consumes (dependencies), and its outward reach (federation and bridged external networks).
flowchart LR
subgraph role [update 💻]
svc_update["update"]
end
Solid 1:1 edges are fixed relationships; dashed 0..1 edges are conditional (enabled only in matching deployments); red 0..0 edges are turned off in this role. Node markers show the role's deploy modes (💻 host, 🐳 compose, 🐝 swarm); ❌ marks a service that is explicitly turned off, and ⚙️ an Ansible role dependency declared in meta/main.yml.
Features
- Per-family dispatch: Routes by
ansible_facts['distribution']so the caller never has to gate the role with awhen:clause. - Five-distro coverage: Supports the five default CI distros (Archlinux, Debian, Ubuntu, Fedora, CentOS) without duplicated task code.
- Loud on unsupported hosts: Fails with a clear message instead of silently skipping when the host runs an unmapped distribution.
- Once-per-play idempotency: Wraps the dispatch in
when: run_once_update is not definedand writes the flag viatasks/utils/once/flag.yml, so repeated invocations within one play are no-ops.
Quick Setup
Development
Clone, set up the workstation, and deploy Package update onto the local stack:
git clone https://github.com/infinito-nexus/core.git
cd core
make onboard
make compose-deploy mode=reinstall apps=update full_cycle=false
Production
Install Package update directly onto the target machine: clone the repository, install the OS prerequisites and the repository toolchain, then deploy against localhost over a local connection (no SSH, no container):
git clone https://github.com/infinito-nexus/core.git
cd core
bash scripts/install/package.sh
make install
source scripts/meta/env/load.sh
APP=update
DOMAIN=<your-domain>
TLS_MODE=self_signed
SSH_PUBLIC_KEY="<your-ssh-public-key>"
INVENTORY=inventories/production
infinito administration inventory provision "$INVENTORY" \
--inventory-file "$INVENTORY/devices.yml" \
--host localhost \
--include "$APP" \
--vars "{\"TLS_MODE\": \"$TLS_MODE\", \"DOMAIN_PRIMARY\": \"$DOMAIN\", \"users\": {\"administrator\": {\"authorized_keys\": [\"$SSH_PUBLIC_KEY\"]}}}"
infinito administration deploy dedicated "$INVENTORY/devices.yml" \
--password-file "$INVENTORY/.password" \
--diff -vv
Developer Notes
To extend support for a new distribution, add the distribution name to the
lookup dict in main.yml. When the new distribution shares
a package manager with an existing entry, point it at that entry's task file.
When it brings a new package manager, add a new family file under
tasks/ and keep meta/main.yml platforms in
sync.
Further Resources
Credits
Implemented by Kevin Veen-Birkenbach. Part of the Infinito.Nexus Project and maintained by Kevin Veen-Birkenbach. Licensed under the Infinito.Nexus Community License (Non-Commercial).