The Production block never set one. inventory provision writes only
ansible_connection for a local host, so DOMAIN_PRIMARY stayed at the
group_vars default of infinito.localhost and the deployment served a zone its
own resolver knows nothing about. CoreDNS templates answers for
INFINITO_DOMAIN_RE and nothing else, so every lookup of the deployment's own
name came back NXDOMAIN.
Mastodon is where that surfaced. tootctl accounts create validates the address
through EmailMxValidator, which resolves MX and then, for the domain itself,
A and AAAA. All six queries returned NXDOMAIN in run 33574056480, the
validator recorded email :unreachable, and the admin account was never created.
Only the guide rows were affected: the matrix rows write
DOMAIN_PRIMARY: "{{ lookup('env', 'INFINITO_DOMAIN') }}" into their host_vars
and resolve fine.
The template now carries DOMAIN=<your-domain> in both the host and the
container form and threads it into --vars, with the container form passing it
through the docker run boundary as well. The two guide runners substitute it
the way they already substitute the SSH key, so the replay deploys under
INFINITO_DOMAIN like every other CI deploy. compose_deploy.sh moves its env
load ahead of the substitutions to have the value; host_deploy.sh had no env
load at all.
A production reader is asked for a domain now instead of silently inheriting
infinito.localhost, which no real deployment wants either. The shipped default
keeps its value: sys-svc-nss documents that *.localhost resolves through the
myhostname NSS module without any zone, and host-side tasks lean on it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5.0 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 of three task files grouped by package-manager family. Debian and
Ubuntu both use apt, Fedora and CentOS both use dnf, so each pair shares a
single task file. 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 / CentOS |
fedora.yml |
ansible.builtin.dnf |
| anything else | unsupported.yml |
ansible.builtin.fail |
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).