Skip to content

fix(docker): route macOS callbacks via host-gateway#1653

Open
akram wants to merge 1 commit into
NVIDIA:mainfrom
akram:fix/macos-docker-driver-host-gateway-bind
Open

fix(docker): route macOS callbacks via host-gateway#1653
akram wants to merge 1 commit into
NVIDIA:mainfrom
akram:fix/macos-docker-driver-host-gateway-bind

Conversation

@akram
Copy link
Copy Markdown

@akram akram commented Jun 1, 2026

On macOS, Docker-compatible runtimes keep bridge networking inside a VM. Binding the gateway listener to the bridge gateway IP (e.g. Podman machine at 10.89.0.1) fails with EADDRNOTAVAIL. Always use host-gateway aliases for docker-driver callback routing on macOS hosts.

Add docker_gateway_route unit tests for the OpenShell issue 1358 regression, including Podman-machine-style daemon info.

Summary

Related Issue

Fixes #1358

Changes

  • Always return true from uses_host_gateway_alias() on macOS (cfg!(target_os = "macos")), so the docker driver never selects a Bridge route that would bind the gateway to a VM-internal bridge IP (e.g. Podman machine 10.89.0.1).
  • Add a macOS-only docker_gateway_route regression test for Podman-machine-style SystemInfo (fedora, localhost.localdomain, bridge gateway 10.89.0.1).
  • Update docker_gateway_route_uses_bridge_gateway_for_linux_docker so macOS expects HostGateway when exercising the Linux-native routing path via docker_gateway_route_for_host(..., false).

Testing

  • mise run pre-commit passes
  • Unit tests added/updated
  • E2E tests added/updated (if applicable)

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Architecture docs updated (if applicable)

On macOS, Docker-compatible runtimes keep bridge networking inside a VM.
Binding the gateway listener to the bridge gateway IP (e.g. Podman machine
at 10.89.0.1) fails with EADDRNOTAVAIL. Always use host-gateway aliases
for docker-driver callback routing on macOS hosts.

Add docker_gateway_route unit tests for the OpenShell issue 1358 regression,
including Podman-machine-style daemon info.

Signed-off-by: Akram <akram.benaissi@gmail.com>
@akram akram requested review from a team, derekwaynecarr, maxamillion and mrunalp as code owners June 1, 2026 15:18
@copy-pr-bot
Copy link
Copy Markdown

copy-pr-bot Bot commented Jun 1, 2026

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 1, 2026

All contributors have signed the DCO ✍️ ✅
Posted by the DCO Assistant Lite bot.

@akram
Copy link
Copy Markdown
Author

akram commented Jun 1, 2026

I have read the DCO document and I hereby sign the DCO.

@akram
Copy link
Copy Markdown
Author

akram commented Jun 1, 2026

recheck

@TaylorMutch
Copy link
Copy Markdown
Collaborator

/ok to test 5925108

Copy link
Copy Markdown
Collaborator

@drew drew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think #1516 fixed the issue. Is the fix in this PR necessary? If possible I'd like to avoid adding extra branches.

This PR could keep the new Podman-machine regression test and improve docs, but avoid adding a second macOS decision inside uses_host_gateway_alias().

diff --git a/crates/openshell-driver-docker/src/lib.rs b/crates/openshell-driver-docker/src/lib.rs
index 214de6ca..27bb8f7b 100644
--- a/crates/openshell-driver-docker/src/lib.rs
+++ b/crates/openshell-driver-docker/src/lib.rs
@@ -1902,6 +1902,11 @@ fn docker_gateway_route_for_host(
 }

 fn host_runtime_requires_host_gateway_alias() -> bool {
+    // On macOS, Docker-compatible runtimes run Linux networking inside a VM.
+    // The bridge gateway IP is not assigned on the host interface where the
+    // gateway process runs, so binding the gateway listener to that IP fails
+    // with EADDRNOTAVAIL. Always route callbacks via host-gateway aliases.
     cfg!(target_os = "macos")
 }

@@ -1914,15 +1919,6 @@ fn host_runtime_requires_host_gateway_alias() -> bool {
 /// Each runtime is detected via the daemon's reported OS string or hostname,
 /// supplemented by labels where the runtime publishes them.
 fn uses_host_gateway_alias(info: &SystemInfo) -> bool {
-    // On macOS, Docker-compatible runtimes (Docker Desktop, Colima, Podman
-    // machine, etc.) run Linux networking inside a VM. The bridge gateway IP is
-    // therefore not assigned on the host interface where the gateway process
-    // runs, so binding the gateway listener to that IP fails with
-    // EADDRNOTAVAIL. Always route callbacks via host-gateway aliases.
-    if cfg!(target_os = "macos") {
-        return true;
-    }
-
     let operating_system = info
         .operating_system
         .as_deref()
diff --git a/crates/openshell-driver-docker/src/tests.rs b/crates/openshell-driver-docker/src/tests.rs
index d8945db8..57e5be3a 100644
--- a/crates/openshell-driver-docker/src/tests.rs
+++ b/crates/openshell-driver-docker/src/tests.rs
@@ -282,31 +282,20 @@ fn docker_gateway_route_uses_bridge_gateway_for_linux_docker() {
         false,
     );

-    if cfg!(target_os = "macos") {
-        assert_eq!(route, DockerGatewayRoute::HostGateway);
-        assert_eq!(
-            docker_extra_hosts(&route),
-            vec![
-                "host.docker.internal:host-gateway".to_string(),
-                "host.openshell.internal:host-gateway".to_string()
-            ]
-        );
-    } else {
-        assert_eq!(
-            route,
-            DockerGatewayRoute::Bridge {
-                bind_address: "172.18.0.1:17670".parse().unwrap(),
-                host_alias_ip: IpAddr::V4(Ipv4Addr::new(172, 18, 0, 1)),
-            }
-        );
-        assert_eq!(
-            docker_extra_hosts(&route),
-            vec![
-                "host.docker.internal:172.18.0.1".to_string(),
-                "host.openshell.internal:172.18.0.1".to_string()
-            ]
-        );
-    }
+    assert_eq!(
+        route,
+        DockerGatewayRoute::Bridge {
+            bind_address: "172.18.0.1:17670".parse().unwrap(),
+            host_alias_ip: IpAddr::V4(Ipv4Addr::new(172, 18, 0, 1)),
+        }
+    );
+    assert_eq!(
+        docker_extra_hosts(&route),
+        vec![
+            "host.docker.internal:172.18.0.1".to_string(),
+            "host.openshell.internal:172.18.0.1".to_string()
+        ]
+    );
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: gateway crash-loops on macOS — binds to VM-internal podman bridge IP (10.89.0.1) on host

3 participants