Files
computer-playbook/plugins/lookup/postgres_libraries.py
T
kevinveenbirkenbachandClaude Opus 5 46445552b8 fix(docs): emit the Architecture section only where its page is written
`sphinx -b gettext -q -W` turns a warning into a failure, and
`make i18n-extract` had been dying on 512 of them. 505 were one defect
repeated: the README template emitted an Architecture section for every
role, while `generate_architecture_page` writes ARCHITECTURE.md only for
invokable ones. 101 roles therefore linked five times each to a page
that does not exist. The section now carries the same
`application_invokable` gate as the page, measured from 101 mismatched
roles to 0.

The remaining seven were separate markup defects, each fatal on its own
under -W. architecture.py's four-entry block was an indented paragraph
that docutils read as a definition list ending abruptly, so it becomes a
literal block. branding.py held a double-backtick literal spanning four
lines, which RST does not allow; it becomes a literal block too.
container_extra_hosts.py wrote `Kwargs:`, which napoleon does not know -
a blank line is measurably not enough, the section has to reach
napoleon, so it is `Keyword Args:`. postgres_libraries.py needed one
blank line before its bullet list, and the cleanup skill an H1 above its
first `##`.

conf.py gains two settings. autodoc_mock_imports covers
`ansible.module_utils.kcadm_json`: that import is correct for an Ansible
module, which resolves module_utils only inside a play, so autodoc on
the control host is what has to yield, not the module.
napoleon_use_ivar stops an `Attributes:` section from emitting
`.. attribute::` directives that collide with the dataclass fields
autodoc already documents - eight duplicate-object warnings, reproduced
and cleared on demand.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-18 01:24:35 +02:00

72 lines
2.1 KiB
Python

"""Resolve postgres-extension library install recipes.
Usage::
{{ lookup('postgres_libraries', ['vector', 'bloom']) }}
Takes a list of extension names and returns the subset that needs a
custom library install on top of the official postgres base image
(the contrib extensions bloom, pg_trgm and unaccent are already in the
base — those are filtered out). Each returned entry is a dict with:
- extension: the extension name (matches the SQL identifier)
- name: the library/source name (used in the Dockerfile context)
- apt_package: the PGDG package suffix, installed as
postgresql-<major>-<apt_package>
"""
from __future__ import annotations
from typing import TYPE_CHECKING, Any
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
if TYPE_CHECKING:
from collections.abc import Sequence
_REGISTRY: dict[str, dict[str, str]] = {
"postgis": {
"name": "postgis",
"apt_package": "postgis-3",
},
"vector": {
"name": "pgvector",
"apt_package": "pgvector",
},
}
class LookupModule(LookupBase):
def run(
self,
terms: Sequence[Any] | None,
variables: dict[str, Any] | None = None,
**kwargs: Any,
) -> list[Any]:
terms = list(terms or [])
if len(terms) != 1:
raise AnsibleError(
"postgres_libraries: expected exactly one term — a list "
"of extension names."
)
extensions = terms[0]
if not isinstance(extensions, (list, tuple)):
raise AnsibleError(
"postgres_libraries: first term must be a list of extension names."
)
recipes: list[dict[str, str]] = []
seen: set[str] = set()
for ext in extensions:
ext_name = str(ext).strip()
if not ext_name or ext_name in seen:
continue
seen.add(ext_name)
recipe = _REGISTRY.get(ext_name)
if recipe is not None:
recipes.append({"extension": ext_name, **recipe})
return [recipes]