A deployment that keeps the shipped DOMAIN_PRIMARY serves names under
infinito.localhost. Those exist in no zone - coredns only knows the outer
stack's domain - so anything reaching the deployment's own domain from the host
depends on the myhostname NSS module, which maps *.localhost to loopback per RFC
6761. 3ebc4d152 established that and titled it "on every target", but the role
carrying it is reachable from exactly one place, sys-svc-mail, so a deploy
without mail never gets the guarantee.
web-app-bigbluebutton is where that surfaces. Job 94846729503 of run
31823654078 replays the role's README per distro; fedora and arch answered its
Greenlight gate with 200, and debian failed 30 attempts with elapsed: 0 and
"<urlopen error [Errno -2] Name or service not known>". In that distro's window
sys-hostname does not appear at all - the play reaches sys-stk-front-proxy at
18:27:45 and the gate at 18:30:06, both before anything pulls the role in. The
asymmetry is declared, not incidental: meta/packages.yml gives Debian
libnss-myhostname and both other families an empty list, because there the
module ships inside systemd.
The front proxy is the chokepoint every domain-serving role passes through, and
it stands up two domain probes of its own, so the guarantee belongs in front of
it. Including sys-hostname there would have been wrong: half that role is
gated only on DOCKER_IN_CONTAINER, so on a production target it would newly run
ansible.builtin.hostname on every domain-serving deploy and rename hosts whose
inventory entry is an alias. CI cannot show this - it always runs in a
container, where exactly those tasks skip.
So the resolution half moves to sys-svc-nss and sys-hostname includes it,
leaving the mail path unchanged while the front proxy takes only what it needs.
required_by names both callers rather than taking the coverage opt-out
sys-hostname still carries as a TODO.
Verified: tests/lint 335 passed / 307 subtests, tests/integration/roles 107
passed / 610 subtests, make readme-check clean. The role itself is unchanged in
behaviour and was already exercised on all five CI distros in job 94636437319 -
ubuntu and debian install the package, fedora, arch and centos skip it, and the
nsswitch line is a no-op everywhere.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replaces the raw package modules at 76 call sites with package_install, moves
each role's distribution mapping into its own meta/packages.yml, and turns the
inventory PACKAGES variable from source-keyed literal names into a list of
declared package ids. The lint that forbids the raw modules is enabled here,
because the migration burns it down from 76 offenders to zero.
Removes sys-aur, sys-aur-install and sys-package. The AUR build user, the
passwordless pacman rule and the inventory-driven install are part of the plan
the action plugin executes, so the roles no longer carry them.
Declaring the mappings surfaced breakage the raw modules had hidden: on Debian
the `which` binary comes from debianutils, jrnl is in no Debian or Ubuntu
suite, chromium-browser is absent from Debian stable, JDK 11 is unobtainable on
RedHat, wireguard had no RedHat branch at all, qbittorrent was built from the
AUR although Arch ships it in extra, and desk-docker installed a Docker variant
that conflicts with the one sys-svc-container installs.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add tests/lint/repository/test_task_file_numbering.py: numbered task
files use exactly two leading digits, a numbered *_core.yml must be
00_core.yml, per directory the numbers are unique/consecutive and start
at 01 (00 with a core file), numbered includes appear in ascending
order, and shared helpers live in tasks/utils/ instead of the numbered
chain.
Apply it across every role: rename NN_core.yml to 00_core.yml with a
consecutive down-shift of the siblings, move letter-suffix children into
a subdirectory named after their parent task, relocate helpers included
from more than one place into tasks/utils/, and update every reference
(include_tasks, path_absolute, .ansible-lint-ignore, requirement docs).
Legacy narration comments in the touched files are deleted; the upstream
xwiki.properties reference block opts out via nocheck. The unused
MAILU_IP6_PUBLIC var (only ever named in now-removed comments) is dropped.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The guide matrix rolled debian, whose image ships neither libnss_myhostname nor a myhostname nsswitch entry, so *.infinito.localhost fell through to DNS, coredns only knows the outer stack's domain, and hlth-webserver died on NXDOMAIN; arch passed because its base enables nss-myhostname out of the box. Install libnss-myhostname on the Debian family and append myhostname to the nsswitch hosts line idempotently, also inside containers - mirroring the host-mode guide fix. Probed across all five CI distros: fedora/centos/arch already resolve out of the box (both tasks no-op), debian/ubuntu gain exactly the missing pieces.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add tests/lint/repository/test_name_emoji_and_length.py: every Ansible task
name and GitHub Actions workflow/job/step name must start with an emoji (first
char not 0-9/A-Za-z) and be <= 80 chars.
- emit emoji names at the source: cli/build/include generator now writes
"🔧 setup <app>" / "🚿 flush handlers after <app>" so generated
tasks/groups/*-roles.yml satisfy the convention too
- convert existing task/step/job/workflow names to emoji-prefixed, choosing a
task-fitting icon per action (📦 install, ✅ ensure, 🔍 probe, 🥾 bootstrap,
🚀 deploy, 🧩 service-module load, ⬇️ checkout, 📂 include-routines, ...)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* scripts/lint/autoformat.sh:
- rename run_sort_claude_settings worker to run_claude (matches the
renamed scripts/lint/claude.sh).
- drop the EXIT trap that wiped status_dir; cleanup happens explicitly
after `wait` returns, so a parallel worker that interrupts the
parent never races a vanished status dir.
- each worker now captures its tool's exit code and writes one of
OK / SKIP / FAIL. Tolerated `expected violations remain`-style exits
(markdownlint-cli2 rc≤1, ansible-lint rc≤2) still count as OK; only
real failures count as FAIL.
- all workers run to completion regardless of individual tool failures
(so the user always sees the full picture); after the summary, the
script exits 1 if any worker reported FAIL.
* scripts/lint/sort_claude_settings.sh -> scripts/lint/claude.sh
(history preserved via git mv); update test_claude_settings_sorted.py
fix-hint accordingly.
Plus working-tree drift across roles/, group_vars/, inventories/,
requirements/, and .pre-commit-config.yaml accumulated from the
make-test setup phase regenerating generated artefacts during recent
test runs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Replace Arch-only inetutils installation with distro-agnostic package mapping
- Use inetutils on Arch and hostname package on all other distros
- Ensure hostname command is available consistently across environments
https://chatgpt.com/share/696a5b7d-6854-800f-b890-3fd72f37d547
- Replace DEFAULT_SYSTEM_EMAIL merge with flat SYSTEM_EMAIL_* variables
- Update templates across apps to new variable names
- Fix msmtp health check to use -t and local username fallback
- Improve postfix localhost config (localdomain, mydestination, timeouts)
- Extend sys-hostname to ensure /etc/hosts mapping once
https://chatgpt.com/share/695e8f39-0694-800f-b91c-a74f4b78d7c8