mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
fix(container-dns): advertise the bridge resolver only where a listener exists
TOR_CONTAINER_DNS_HOST is empty in swarm mode by design, so no dnsmasq listener appears on the docker bridge there. The lookup gated on the tor group alone and wrote 172.17.0.1 into daemon.json anyway, handing every nested container a resolver nothing answers on — nested image builds then died resolving dl-cdn.alpinelinux.org. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
5dbbaca4a1
commit
e308e18923
2 files changed
+23
-1
No files matched your search
@@ -5,6 +5,7 @@ from typing import Any
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
_TOR_ROLE = "svc-net-tor"
|
||||
_BRIDGE_MODE = "compose"
|
||||
|
||||
|
||||
def resolve_container_dns(variables: dict[str, Any]) -> list[str]:
|
||||
@@ -16,18 +17,28 @@ def resolve_container_dns(variables: dict[str, Any]) -> list[str]:
|
||||
bridge address because docker discards loopback resolvers, and it is
|
||||
absent before docker itself is installed, hence the guard.
|
||||
|
||||
Only compose mode gets the bridge: TOR_CONTAINER_DNS_HOST creates the
|
||||
matching dnsmasq listener there and nowhere else.
|
||||
|
||||
The clearnet resolver stays as a second entry so that losing dnsmasq costs
|
||||
onion names rather than all name resolution.
|
||||
"""
|
||||
facts = variables.get("ansible_facts") or {}
|
||||
bridge = ((facts.get("docker0") or {}).get("ipv4") or {}).get("address") or ""
|
||||
on_tor_node = _TOR_ROLE in (variables.get("group_names") or [])
|
||||
bridge_reachable = (
|
||||
str(variables.get("DEPLOYMENT_MODE") or "").strip() == _BRIDGE_MODE
|
||||
)
|
||||
|
||||
clearnet = ((variables.get("networks") or {}).get("internet") or {}).get(
|
||||
"dns"
|
||||
) or ""
|
||||
|
||||
return [str(r) for r in (bridge if on_tor_node else "", clearnet) if r]
|
||||
return [
|
||||
str(r)
|
||||
for r in (bridge if (on_tor_node and bridge_reachable) else "", clearnet)
|
||||
if r
|
||||
]
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
|
||||
@@ -22,6 +22,7 @@ def _vars(**overrides):
|
||||
"ansible_facts": _BRIDGE,
|
||||
"group_names": ["svc-net-tor"],
|
||||
"networks": _CLEARNET,
|
||||
"DEPLOYMENT_MODE": "compose",
|
||||
}
|
||||
variables.update(overrides)
|
||||
return variables
|
||||
@@ -37,6 +38,16 @@ class TestResolveContainerDns(unittest.TestCase):
|
||||
def test_without_tor_only_clearnet(self):
|
||||
self.assertEqual(resolve_container_dns(_vars(group_names=[])), ["172.30.0.53"])
|
||||
|
||||
def test_swarm_node_skips_the_bridge_resolver(self):
|
||||
self.assertEqual(
|
||||
resolve_container_dns(_vars(DEPLOYMENT_MODE="swarm")), ["172.30.0.53"]
|
||||
)
|
||||
|
||||
def test_swarm_node_without_clearnet_yields_empty_list(self):
|
||||
self.assertEqual(
|
||||
resolve_container_dns(_vars(DEPLOYMENT_MODE="swarm", networks={})), []
|
||||
)
|
||||
|
||||
def test_without_bridge_only_clearnet(self):
|
||||
self.assertEqual(
|
||||
resolve_container_dns(_vars(ansible_facts={})), ["172.30.0.53"]
|
||||
|
||||
Reference in new issue
Block a user