Files
computer-playbook/plugins/lookup/postgres_libraries.py
T
kevinveenbirkenbachandClaude Opus 4.7 300ea0a054 feat(sys-svc-rdbms): build per-consumer postgres image with required libraries for shared:false
Generalises the postgres image build to be driven by a declarative
extension→library registry instead of a hardcoded POSTGRES_VECTOR_ENABLED
flag. Same Dockerfile.j2 now serves both the central svc-db-postgres
image (libraries aggregated across all deployed consumers) and per-
consumer images for shared:false postgres consumers whose extensions
need libraries not in the postgis/postgis base (e.g. pgvector).
postgres.yml.j2 switches between image: and build: based on whether
custom libraries are needed. New postgres_libraries lookup filters
base-image extensions out and returns recipes for the rest. Dedicated
task path extracted into dedicated.yml + dedicated_postgres.yml so the
block-with-when size limit stays satisfied and the postgres-type check
happens once.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 16:55:01 +02:00

65 lines
2.0 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 postgis/postgis base image
(bloom, postgis, pg_trgm, 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)
- git_source: the upstream git repository to clone and build from
"""
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]] = {
"vector": {
"name": "pgvector",
"git_source": "https://github.com/pgvector/pgvector.git",
},
}
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]