utils package¶
Subpackages¶
- utils.annotations package
- utils.cache package
- utils.claude package
- utils.cleanup package
- utils.diagnostics package
- utils.docker package
- utils.domains package
- utils.env package
- utils.github package
- utils.handler package
- utils.install package
- Subpackages
- utils.install.lint package
- Subpackages
- Submodules
- utils.install.lint.actionlint module
- utils.install.lint.eslint module
- utils.install.lint.hadolint module
- utils.install.lint.markdownlint_cli2 module
- utils.install.lint.mbake module
- utils.install.lint.mermaid_cli module
- utils.install.lint.packages module
- utils.install.lint.php module
- utils.install.lint.pinned module
- utils.install.lint.playwright module
- utils.install.lint.ruby module
- utils.install.lint.ruff module
- utils.install.lint.shellcheck module
- utils.install.lint.shfmt module
- utils.install.lint.sqlfluff module
- utils.install.lint.stylelint module
- Module contents
- utils.install.lint package
- Submodules
- utils.install.collections module
- utils.install.github_release module
- utils.install.interpreters module
- utils.install.node module
- utils.install.npm module
- utils.install.php module
- utils.install.pip module
- utils.install.primitives module
- utils.install.ruby module
- utils.install.system_pkg module
- Module contents
- Subpackages
- utils.inventory package
- utils.mail package
- utils.manager package
- utils.meta package
- utils.networks package
- utils.nexus package
- utils.packages package
- utils.recovery package
- Submodules
- utils.recovery.base module
- utils.recovery.databases module
- utils.recovery.docker module
- utils.recovery.layout module
- utils.recovery.manifest module
- Module contents
- utils.roles package
- Subpackages
- utils.roles.applications package
- Subpackages
- Submodules
- utils.roles.applications.config module
- utils.roles.applications.in_group_deps module
- utils.roles.applications.mcp module
- utils.roles.applications.mounts module
- utils.roles.applications.security_headers module
- utils.roles.applications.status_codes module
- utils.roles.applications.topics module
- utils.roles.applications.variants module
- Module contents
- utils.roles.entity package
- utils.roles.rbac package
- utils.roles.validation package
- utils.roles.applications package
- Submodules
- utils.roles.categories module
- utils.roles.credits module
- utils.roles.dependency_resolver module
- utils.roles.deploy module
- utils.roles.display module
- utils.roles.guide module
- utils.roles.lifecycle module
- utils.roles.mapping module
- utils.roles.meta_lookup module
- utils.roles.order module
- utils.roles.required_by_coverage module
- utils.roles.stage module
- utils.roles.type module
- Module contents
- Subpackages
- utils.storage package
- utils.templating package
- utils.tests package
- utils.update package
- Submodules
- utils.update.addons module
- utils.update.base module
- utils.update.collection_source module
- utils.update.docker module
- utils.update.fetch module
- utils.update.follow module
- utils.update.galaxy module
- utils.update.pip module
- utils.update.repository module
- utils.update.runner module
- utils.update.source module
- Module contents
Submodules¶
utils.ansible_log module¶
SPOT for the line prefix Ansible writes into its log_path file.
Every line of the file named by ANSIBLE_LOG_PATH carries
``<ts> p=<pid> u=<user> n=<name> <LEVEL>| `` in front of the message that
also went to stdout. Left unstripped, that prefix defeats every
line-anchored matcher a reader applies, so a reader that mixes an anchored
match with an unanchored one silently sees an empty log instead of failing.
utils.api module¶
Proprietary API credential SPOT, read from group_vars/all/18_api.yml.
API is a plain mapping, so an inventory that configures three providers
replaces the whole declaration instead of merging into it, and every provider it
does not name disappears. Resolving a hidden provider then raises, and a raising
lookup inside a value the applications renderer is templating leaves the raw
{{ ... }} text in place: the consumer stores template text, and | bool
coerces it to False with a deprecation warning that fails the deploy on the
warning gate.
Merging the scope’s override over the declared defaults keeps every declared provider resolvable, so an override narrows values, never the provider set.
- utils.api.declared_api() dict[str, Any]¶
The
APImapping as declared in the group_vars SPOT.- Returns:
Provider name to credential mapping, every value a plain string.
- Raises:
TypeError – the SPOT does not declare
APIas a mapping.
- utils.api.provider_enabled(api: Mapping[str, Any], provider: str) bool¶
Whether every credential of a provider carries a value.
- Parameters:
api – an effective
APImapping, as returned byresolve_api.provider – the provider name, e.g.
github.
- Returns:
True when the provider declares at least one credential and none of them is empty.
- Raises:
KeyError – the provider is not declared in the SPOT.
- utils.api.resolve_api(variables: Mapping[str, Any] | None, templar: Any = None) dict[str, Any]¶
The effective
APImapping for a render scope.- Parameters:
variables – the scope’s variables; its
APIentry overrides the SPOT.templar – optional templar; renders the override and the merged values, so an inventory may source a credential from an env lookup.
- Returns:
The SPOT declaration with the scope’s override merged over it.
- Raises:
TypeError – the scope’s
APIis present but not a mapping.
utils.cert_utils module¶
- class utils.cert_utils.CertUtils¶
Bases:
object- classmethod build_snapshot(cert_base_path)¶
- classmethod ensure_cert_mapping(cert_base_path, debug=False)¶
- static extract_sans(cert_text)¶
- classmethod find_cert_for_domain(domain, cert_base_path, debug=False)¶
- static list_cert_files(cert_base_path)¶
- static matches(domain, san)¶
RFC compliant SAN matching.
- classmethod refresh_cert_mapping(cert_base_path, debug=False)¶
Build mapping: SAN -> list of entries entry = {
‘folder’: str, ‘cert_path’: str, ‘mtime’: float, ‘not_before’: int|None, ‘not_after’: int|None, ‘is_wildcard’: bool
}
- static run_openssl(cert_path)¶
- static run_openssl_dates(cert_path)¶
Returns (not_before_ts, not_after_ts) as POSIX timestamps or (None, None) on failure.
- classmethod snapshot_changed(cert_base_path)¶
utils.distros module¶
Distribution SPOT.
meta/distros.yml declares every distribution the project builds, tests
and deploys on: the id used as INFINITO_DISTRO, the os_family
ansible reports for it, the Galaxy platform name, and the templates the
pkgmgr base image and the environment image references are rendered from.
The upstream image the development-environment matrix boots each distro
from is pinned in roles/sys-os/meta/services.yml under the distro id,
where the docker updater, the mirror and the vulnerability scan find it.
Consumers MUST read the distro set through this module. A local tuple of
distro names or an f-string spelling out ghcr.io/.../pkgmgr-... is a
second source of truth and drifts; tests/lint/repository/test_distros_spot.py
guards against reintroducing one.
Registry owner, repository and tag are not declared here — they stay in
default.env, which is their SPOT. This module only renders them into
the templates.
Keep this module free of Ansible imports and cheap to import: it is pulled
in by the env layer and by utils.packages.schema, which reach contexts
where Ansible is not installed. It must also stay importable on the bare
bootstrap python, so the SPOT is read with the stdlib block reader instead
of PyYAML.
- exception utils.distros.UnknownDistroError¶
Bases:
ValueErrorRaised for a distro id or image that
meta/distros.ymldoes not declare.
- utils.distros.dev_runtime_image(distro: str) str¶
Upstream base image the development environment boots a distro from.
- utils.distros.dev_runtime_images() tuple[str, ...]¶
Upstream base images of the development-environment test matrix.
- utils.distros.distro_family() dict[str, str]¶
Map each distro id onto the
os_familyansible reports for it.
- utils.distros.distro_names() tuple[str, ...]¶
Every declared distro id, in declaration order.
- utils.distros.distro_of_dev_runtime_image(image: str) str¶
Distro id whose development environment boots from
image.
- utils.distros.environment_image(distro: str, owner: str, repository: str, tag: str) str¶
Reference of the environment image built for a distro.
- utils.distros.galaxy_platforms() list[dict[str, object]]¶
Canonical
galaxy_info.platformsblock for every role’s meta/main.yml.Sorted by platform name, which is the order the role files carry and which the schema lint compares against verbatim.
- utils.distros.image_template(kind: str) str¶
Raw reference template, for callers rendering a non-distro slug.
The shell-side installer scripts loop over distros with their own variable, so they render
{slug}themselves rather than per distro.
- utils.distros.pkgmgr_image(distro: str, owner: str, tag: str) str¶
Reference of the pkgmgr base image a distro’s container builds FROM.
- utils.distros.pkgmgr_virgin_image(distro: str, owner: str, tag: str) str¶
Reference of the untouched pkgmgr image the install tests boot.
utils.get_url module¶
- utils.get_url.get_url(domains, application_id, protocol)¶
utils.kcadm_json module¶
- utils.kcadm_json.json_from_noisy_stdout(text: Any) Any¶
Parse JSON from output that may contain leading non-JSON noise, including lines that start with ‘[’ (e.g. JVM warnings like “[0.001s][warning]…”).
- Deterministic strategy:
scan for all occurrences of ‘[’ and ‘{’ in the output
attempt json.loads() starting from each occurrence (in order)
return the first successfully parsed JSON value
raise ValueError if none work
utils.keycloak_scopes module¶
Client-scope list convergence for keycloak_kcadm_update.
A client PUT ignores default/optionalClientScopes (sub-resources with their own endpoints; verified against a live deploy) — these helpers converge them explicitly: DELETE unassigns, bodyless PUT assigns, removals first so a scope can move between the two lists.
run_kcadm is injected by the calling module (it owns retry/CID-recovery
semantics); every helper takes it as its first argument.
- utils.keycloak_scopes.converge_client_scope_lists(run_kcadm, module, object_id, desired, realm, kcadm_exec)¶
Converge a client’s default/optional client-scope lists to
desired.
- utils.keycloak_scopes.named_id_map(run_kcadm, module, cmd)¶
Run a kcadm list command and return a {name: id} map (empty on noise).
utils.parse_trace module¶
utils.paths module¶
Filesystem SPOT for the Python side, read from group_vars/all/05_paths.yml.
group_vars/all/05_paths.yml is the single source of truth for host paths.
The env layer (utils/env/handlers, exported by scripts/meta/env/load.sh) derives
the INFINITO_* env keys from it; a set env wins so callers can override.
When a tool runs outside that layer, e.g. a bare subprocess that does not
inherit the env build, the value is read straight from the group_vars SPOT, so
there is still no hardcoded literal default.
The SPOT is parsed with a plain-string line parser instead of PyYAML: the env
build runs during bootstrap (make install-system-python) before any Python
dependency exists, so this module must stay stdlib-only. Only plain
KEY: "value" entries can be read this way; a Jinja expression or a missing
key is a hard error.
- utils.paths.read_group_path(key: str) str¶
Plain-string path value from the group_vars paths SPOT.
- Parameters:
key – top-level variable name in group_vars/all/05_paths.yml.
- Returns:
The literal string value.
- Raises:
KeyError – the key is not defined in the SPOT.
ValueError – the value is not a plain string (e.g. a Jinja template).
- utils.paths.read_group_paths(key: str) list[str]¶
Plain-string list value from the group_vars paths SPOT.
- Parameters:
key – top-level variable name whose value is a YAML block sequence.
- Returns:
The literal string entries, in file order.
- Raises:
KeyError – the key is not defined in the SPOT or carries no entry.
utils.sizes module¶
Parse human-readable memory size strings to bytes.
SI/decimal units for the bare suffixes (k=10^3, m=10^6, g=10^9, …) and IEC
binary for the explicit *ib suffixes (kib=1024, mib=1024^2, …). Shared by
the node_max_old_space_size lookup and the peertube install_mem_limit
filter.
- utils.sizes.to_bytes(val)¶
Convert a numeric or string size (e.g. ‘512m’, ‘2GiB’, 1024) to bytes.
Returns None for None/empty input. Raises AnsibleFilterError on an unparseable value.
utils.symbol_glossary module¶
Single source of truth mapping short words to display emojis, and back.
Every emoji used as a STRUCTURED marker across the project (complexity-matrix columns, lifecycle stages, deploy modes, boolean/state cells) is defined here exactly once, so a glyph means the same thing everywhere it appears. Emojis are unique: the module fails to import if two words share a glyph.
Look up with to_emoji() (word -> emoji) and to_word() (emoji ->
canonical word); both pass unknown input through unchanged.
- utils.symbol_glossary.to_emoji(word: str) str¶
Return the emoji mapped to word, or word itself when unmapped.
- utils.symbol_glossary.to_word(emoji: str) str¶
Return the canonical word for emoji, or emoji itself when unmapped.
utils.terminal_aliases module¶
Fetch-once cache and parser for the operator’s terminal aliases.
Configuration comes exclusively from the generated .env
(make dotenv), which already folds in default.env, every
handler, and the operator’s custom.env overrides. The alias
repository (INFINITO_ALIAS_REPOSITORY) holds one
alias <name>='<command>' line per shortcut in an aliases file at
its root.
- utils.terminal_aliases.alias_repository() str¶
Effective terminal alias repository from the generated .env.
- utils.terminal_aliases.fetch_cached(repository: str, timeout: int = 15) str¶
Return the aliases file content, downloading once per repository.
- Parameters:
repository – git repository URL to fetch the
aliasesfile from.timeout – socket timeout in seconds for the one-time download.
- utils.terminal_aliases.local_alias_names() list[str]¶
Infinito.Nexus-specific alias names from the repo’s
aliasesfile.
- utils.terminal_aliases.parse_alias_names(text: str) list[str]¶
Alias names in file order.
- Parameters:
text – raw content of an aliases file.
- utils.terminal_aliases.raw_aliases_url(repository: str) str¶
Raw download URL of the repository’s root
aliasesfile.- Parameters:
repository – git repository URL (GitHub-style raw path layout).
utils.tls_common module¶
- utils.tls_common.align_domain_to_consumer(domains: dict, app_id: str, primary_domain: str, *, consumer: str = '', variables: dict | None = None, templar: Any = None) str¶
Family-align a cross-app reference: when a clearnet-primary consumer resolves an onion-primary target, return the target’s first clearnet domain from the merged map; keep
primary_domainwhenever the consumer is unknown/onion, the target is clearnet, or no clearnet sibling exists.
- utils.tls_common.collect_domains_for_app(domains: dict, app_id: str, *, err_prefix: str) list[str]¶
- utils.tls_common.collect_domains_global(domains: dict) list[str]¶
- utils.tls_common.iter_domains(value: Any) Iterable[str]¶
Flatten domains from the global domains mapping entry. Supports:
str
list[str]
dict[str, str] (only one level, legacy behavior)
- utils.tls_common.override_san_list(app: dict) list[str] | None¶
- utils.tls_common.resolve_app_id_from_domain(domains: dict, domain: str, *, err_prefix: str) str¶
Legacy reverse-lookup from the global domains mapping. This does NOT know about per-app aliases/canonicals stored in applications.
- utils.tls_common.resolve_enabled(app: dict, enabled_default: bool, *, primary_domain: str = '') bool¶
- utils.tls_common.resolve_le_name(app: dict, domain: str) str¶
- utils.tls_common.resolve_mode(app: dict, enabled: bool, mode_default: str, *, err_prefix: str) str¶
- utils.tls_common.resolve_primary_domain_from_app(domains: dict, app_id: str, *, err_prefix: str) str¶
- utils.tls_common.resolve_term(term: str, *, domains: dict, applications: dict | None = None, forced_mode: str, err_prefix: str) tuple[str, str]¶
Returns (app_id, primary_domain) where primary_domain is normalized lower-case.
- term can be:
application_id
domain (canonical or alias)
forced_mode: “auto” | “domain” | “app”
- Behavior:
If term is a domain and exists in global domains mapping -> primary_domain = that term (normalized).
If term is a domain and only exists in applications[*].domains -> map to app_id, and primary_domain = canonical primary from global domains mapping (first entry).
- utils.tls_common.uniq_preserve(items: Iterable[str]) list[str]¶
utils.tor_onion module¶
Offline Tor v3 onion-service key minting.
Deterministically derives a Tor v3 hidden-service address and the exact
HiddenServiceDir key files from an ed25519 seed, without running Tor.
The v3 address is base32(PUBKEY || CHECKSUM || VERSION) where
CHECKSUM = SHA3-256(".onion checksum" || PUBKEY || VERSION)[:2] and
VERSION = 0x03 (see spec.torproject.org/address-spec). Tor stores the
expanded ed25519 secret key clamp(SHA512(seed)[:32]) || SHA512(seed)[32:]
in hs_ed25519_secret_key; the public key clamp(SHA512(seed)[:32]) * B
equals the standard ed25519 public key, so it is taken straight from
cryptography without needing scalar multiplication.
- class utils.tor_onion.OnionKey(seed: bytes, address: str, hostname: bytes, public_key: bytes, secret_key: bytes)¶
Bases:
objectA minted Tor v3 onion key and its
HiddenServiceDirfile contents.- address: str¶
- files() dict[str, bytes]¶
Map
HiddenServiceDirfilenames to their exact byte contents.
- hostname: bytes¶
- public_key: bytes¶
- secret_key: bytes¶
- seed: bytes¶
- utils.tor_onion.identity_hs_dir(base_dir: str | Path) Path¶
Authoritative hidden-service key dir (
<base_dir>/.onion-identity/hs).Single source of truth for the node’s onion identity:
ensure_node_onionmints/reuses the key files here and thesvc-net-torrole copies them into the running daemon. Lives outside anything the deploy regenerates and is mounted into the DiD at{playbook_dir}/.onion-identity/hs.
- utils.tor_onion.mint(seed: bytes | None = None) OnionKey¶
Mint a v3 onion key from
seed(32 random bytes if omitted).
- utils.tor_onion.onion_address(public_key: bytes) str¶
Return the v3
.onionaddress for a 32-byte ed25519 public key.
utils.yaml_bootstrap module¶
Stdlib reader for the block-YAML subset the bootstrap SPOT files use.
This is a deliberate second YAML touchpoint outside utils.cache.yaml:
the modules that read the distro SPOT must import on the bare bootstrap
python, which runs the .env generator before any dependency is
installed, so they cannot reach the PyYAML-backed cache.
Supported: nested block mappings, block sequences of scalars, plain and
double-quoted string scalars, full-line and trailing comments, a single
leading document marker. Every other construct raises
BootstrapYamlError, so load_block(text) either equals
yaml.safe_load(text) or fails loud.
The plain-scalar rule is deliberately narrower than YAML’s: a plain scalar
must start with a letter, an underscore or a slash, and may then carry only
[A-Za-z0-9_./+@:-] and spaces. That excludes every leading character
PyYAML’s implicit resolvers key off, so no accepted plain scalar can come
back as an int, float, bool, timestamp or null.
- exception utils.yaml_bootstrap.BootstrapYamlError¶
Bases:
ValueErrorRaised for a construct outside the supported block subset.
- utils.yaml_bootstrap.load_block(text: str) dict¶
Parse text as a block mapping and return it.
- Parameters:
text – YAML source restricted to the supported block subset.
- Returns:
The root mapping, with every scalar as a
str.- Raises:
BootstrapYamlError – for any construct outside the subset.