mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 02:54:26 +00:00
A module that dies on an unhandled exception carries no msg: the AnsiballZ wrapper returns only failed and exception, whose event holds the sole account of what went wrong. The aggregation defaulted to the literal string package install failed and discarded it, so an AUR fetch that threw in run 30713666732 reported nothing at all and took a full investigation to place. Walk msg, exception.event.msg, exception, module_stderr, stderr instead, and tag every result with the module that produced it. This applies to apt, dnf, pacman and every other module the plugin drives, not only to the AUR. The aur module fetches the RPC record and the snapshot tarball through bare open_url calls with no error handling, so one blip kills a deploy; distribution repositories need none of this because apt, dnf and pacman retry inside their own transport. Give the calls that reach an endpoint of their own a single shared policy. Only the AUR path is declared today; copr, ppa and build carry it against the day they are. Split the result along its responsibilities so no file passes 250 lines: calls.py holds the vocabulary, sources.py one builder per acquisition path, plan.py only the dispatcher, outcome.py the reporting and facts.py the fact shapes. The action plugin is left with executing modules. Tests follow the code. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
30 lines
972 B
Python
30 lines
972 B
Python
"""Read the gathered facts a package plan needs off either fact shape."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
|
|
def read_fact(facts: dict[str, Any], name: str) -> str:
|
|
"""Read a fact from either the task_vars shape or the setup-module one.
|
|
|
|
Args:
|
|
facts: an ``ansible_facts`` mapping. task_vars carries bare keys,
|
|
the setup module returns them ``ansible_``-prefixed.
|
|
name: the unprefixed fact name.
|
|
"""
|
|
for key in (name, f"ansible_{name}"):
|
|
value = facts.get(key)
|
|
if value:
|
|
return str(value).strip()
|
|
return ""
|
|
|
|
|
|
def distribution_and_family(facts: dict[str, Any]) -> tuple[str, str]:
|
|
"""Return ``(distribution, os_family)``, or ``("", "")`` if either is absent."""
|
|
distribution = read_fact(facts, "distribution").lower()
|
|
os_family = read_fact(facts, "os_family")
|
|
if not distribution or not os_family:
|
|
return "", ""
|
|
return distribution, os_family
|