From 854a8956ad4d2790b128dcb1636e216faa1b62e7 Mon Sep 17 00:00:00 2001 From: didericis Date: Tue, 21 Jul 2026 20:50:12 -0400 Subject: [PATCH] fix(macos): substitute the gateway address before the service starts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Third attempt at the same symptom, and the first at the right layer. podman's Docker-compatible API injects proxy settings from the *daemon* environment after containers.conf is applied, so neither the env list (892bfc16) nor http_proxy=false (21c144ae) could override it — the same compat-path blind spot already seen with hosts_file. Nested containers kept reporting `wget: bad address 'bot-bottle-gateway:9099'` through both. Substituting the resolved address into the service's own environment, before `podman system service` starts, is the one place it sticks. NO_PROXY keeps the name, which is matched against what a client asks for. Co-Authored-By: Claude Opus 4.8 --- .../macos_container/nested-containers-init.sh | 15 +++++++++++++++ tests/unit/test_macos_nested_containers.py | 12 ++++++++++++ 2 files changed, 27 insertions(+) diff --git a/bot_bottle/backend/macos_container/nested-containers-init.sh b/bot_bottle/backend/macos_container/nested-containers-init.sh index 0a18a01..41f29d2 100755 --- a/bot_bottle/backend/macos_container/nested-containers-init.sh +++ b/bot_bottle/backend/macos_container/nested-containers-init.sh @@ -178,6 +178,21 @@ if docker info >/dev/null 2>&1; then exit 0 fi +# The service's own environment is the last word on what a nested container +# gets. podman's Docker-compatible API injects proxy settings from the daemon +# environment *after* containers.conf is applied, so neither the `env` list +# below nor `http_proxy=false` can override it — the same blind spot the +# compat path has for `hosts_file`. Substituting here, before the service +# starts, is therefore the only place the address actually sticks. +# +# Assigned via command substitution, never echoed: these carry the bottle's +# identity token. +for var in HTTP_PROXY HTTPS_PROXY http_proxy https_proxy; do + eval "value=\${$var:-}" + [ -n "$value" ] || continue + eval "export $var=\"\${value%%$GATEWAY_NAME*}$gateway_ip\${value#*$GATEWAY_NAME}\"" +done + log=/tmp/bot-bottle-nested-containers.log nohup podman system service --time=0 \ "unix://$XDG_RUNTIME_DIR/podman.sock" \ diff --git a/tests/unit/test_macos_nested_containers.py b/tests/unit/test_macos_nested_containers.py index 1391eb2..e81fdad 100644 --- a/tests/unit/test_macos_nested_containers.py +++ b/tests/unit/test_macos_nested_containers.py @@ -174,6 +174,18 @@ class TestInitScript(unittest.TestCase): self.assertIn('$2 == name { print $1; exit }', self.script) self.assertIn('value.replace(name, ip)', self.script) + def test_substitutes_the_address_into_the_service_environment(self) -> None: + """The compat API injects proxy settings from the daemon environment + after containers.conf is applied, so neither the env list nor + http_proxy=false can override it — the same blind spot it has for + hosts_file. Substituting before the service starts is the only place + the address sticks.""" + launch = self.script[self.script.index("podman system service"):] + self.assertNotIn("$GATEWAY_NAME", launch) # substitution precedes it + setup = self.script[:self.script.index("podman system service")] + self.assertIn("for var in HTTP_PROXY HTTPS_PROXY http_proxy https_proxy", + setup) + def test_disables_podmans_own_proxy_passthrough(self) -> None: """podman copies the host's proxy vars into every container by default, and that copy overrides the env we set — putting the