mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 19:01:54 +00:00
Two places decided independently what the pre-created <entity> network is called inside the compose project. render.py emits the key; create.yml asserted it was always `default`. They diverged in July and nobody noticed, because compose 5.3.1 resolved networks by name and never read the claim. Compose 5.4.0, published 2026-08-03T14:39:12Z, resolves them by label. For web-app-seaweedfs - the one deployed role that provides its own shared_net and therefore renders an unnamed `default` - the mislabelled `seaweedfs` network is adopted as the project default, `seaweedfs_default` is never created, and the containers fail to start against it. That failed web-app-nextcloud 0 and 3 in run 30830377785. _shared_network_key() is now the single derivation. render_compose_networks takes its branch from it, so the rendering decision IS the key decision; shared_network_compose_key() exports the same value, the shared_network_key lookup hands it to Ansible, and create.yml stamps it: `seaweedfs` for a self-provider, `default` for everyone else. Both true, both from the source that renders the file. Verified on one host with only the compose binary swapped: 5.4.0 network=default -> FAIL, network <project>_default not found 5.4.0 network=<entity> -> OK 5.3.1 network=default -> OK 5.3.1 network=<entity> -> OK so this is not a fix that trades one version for the other. test_key_matches_the_key_the_renderer_emits renders the block and asserts the reported key appears in it, for both role shapes and both modes. The drift that sat unnoticed for a month now breaks a test. The move of the attachment computation into utils/networks/attachments.py rides along because render.py would otherwise be broken between two commits: it is a pure relocation, re-exported so no importer changes, and it brings the file from 352 to 243 lines. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
61 lines
1.9 KiB
Python
61 lines
1.9 KiB
Python
"""Lookup `shared_network_key`: the compose networks key of the pre-created
|
|
``<entity>`` network of a role.
|
|
|
|
Docker compose stores that key in the ``com.docker.compose.network`` label of
|
|
every network it owns, so a caller pre-creating the network out of band has to
|
|
stamp the same value or compose will resolve the project's networks against a
|
|
claim the rendered file does not make. The key is derived from
|
|
``utils.networks.render``, which renders the file itself, so the two cannot
|
|
drift.
|
|
|
|
Examples:
|
|
|
|
- name: create the shared network
|
|
ansible.builtin.command:
|
|
argv:
|
|
- container
|
|
- network
|
|
- create
|
|
- --label
|
|
- "com.docker.compose.network={{ lookup('shared_network_key', role_id) }}"
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from ansible.errors import AnsibleError
|
|
from ansible.plugins.lookup import LookupBase
|
|
|
|
from utils.networks.lookup_context import build_context, resolve_var
|
|
from utils.networks.render import shared_network_compose_key
|
|
from utils.roles.entity.name import get_entity_name
|
|
|
|
|
|
class LookupModule(LookupBase):
|
|
def run(
|
|
self,
|
|
terms: list[Any] | None,
|
|
variables: dict[str, Any] | None = None,
|
|
**kwargs: Any,
|
|
) -> list[str]:
|
|
if not terms or len(terms) != 1:
|
|
raise AnsibleError(
|
|
"shared_network_key lookup requires exactly one term: application_id"
|
|
)
|
|
|
|
ctx = build_context(self, variables)
|
|
application_id = str(resolve_var(ctx.templar, terms[0]))
|
|
|
|
return [
|
|
shared_network_compose_key(
|
|
application_id=application_id,
|
|
deployment_mode=ctx.deployment_mode,
|
|
registry=ctx.registry,
|
|
get_entity_name=get_entity_name,
|
|
lookup_config=ctx.lookup_config,
|
|
lookup_database=ctx.lookup_database,
|
|
node_local=bool(kwargs.get("node_local", False)),
|
|
)
|
|
]
|