diff --git a/src/lib/onboard/docker-gpu-patch.test.ts b/src/lib/onboard/docker-gpu-patch.test.ts index ea2ce9c27aa..1807488fb53 100644 --- a/src/lib/onboard/docker-gpu-patch.test.ts +++ b/src/lib/onboard/docker-gpu-patch.test.ts @@ -214,7 +214,10 @@ describe("docker-gpu-patch", () => { expect(args).toEqual( expect.arrayContaining(["--env", "OPENSHELL_ENDPOINT=http://127.0.0.1:8080/"]), ); - expect(args).not.toEqual( + // --add-host writes to /etc/hosts (mount namespace), not the network + // stack, so it must survive even when --network=host is explicitly + // requested (#3562, #3568). + expect(args).toEqual( expect.arrayContaining(["--add-host", "host.openshell.internal:172.17.0.1"]), ); expect(args).not.toEqual(expect.arrayContaining(["--network-alias", "openshell-alpha"])); @@ -226,7 +229,7 @@ describe("docker-gpu-patch", () => { }); it("reports the Docker GPU patch network mode", () => { - expect(getDockerGpuPatchNetworkMode({})).toBe("host"); + expect(getDockerGpuPatchNetworkMode({})).toBe("preserve"); expect(getDockerGpuPatchNetworkMode({ NEMOCLAW_DOCKER_GPU_PATCH_NETWORK: "host" })).toBe( "host", ); @@ -394,9 +397,11 @@ describe("docker-gpu-patch", () => { "--security-opt", "apparmor=unconfined", "--network", - "host", + "openshell-docker", + "--add-host", + "host.openshell.internal:172.17.0.1", "--env", - "OPENSHELL_ENDPOINT=http://127.0.0.1:8080/", + "OPENSHELL_ENDPOINT=http://host.openshell.internal:8080/", ]), expect.objectContaining({ ignoreError: true }), ); diff --git a/src/lib/onboard/docker-gpu-patch.ts b/src/lib/onboard/docker-gpu-patch.ts index efc94d9c938..a04700143df 100644 --- a/src/lib/onboard/docker-gpu-patch.ts +++ b/src/lib/onboard/docker-gpu-patch.ts @@ -358,9 +358,9 @@ export function getDockerGpuPatchNetworkMode( env: Record = process.env, ): "host" | "preserve" { const networkOverride = String(env[DOCKER_GPU_PATCH_NETWORK_ENV] || "").trim().toLowerCase(); + if (networkOverride === "host") return "host"; if (networkOverride === "preserve" || networkOverride === "bridge") return "preserve"; - if (networkOverride && networkOverride !== "host") return "preserve"; - return "host"; + return "preserve"; } function dockerNetworkAliases( @@ -449,9 +449,11 @@ export function buildDockerGpuCloneRunArgs( securityOpt.add("apparmor=unconfined"); } for (const opt of securityOpt) args.push("--security-opt", opt); - if (networkMode !== "host") { - for (const hostEntry of stringArray(host.ExtraHosts)) args.push("--add-host", hostEntry); - } + // --add-host writes to the container's /etc/hosts (mount namespace), not + // the network stack, so OpenShell's host.openshell.internal mapping must + // survive even when the caller explicitly opts into --network=host via + // NEMOCLAW_DOCKER_GPU_PATCH_NETWORK=host (#3562, #3568). + for (const hostEntry of stringArray(host.ExtraHosts)) args.push("--add-host", hostEntry); for (const group of stringArray(host.GroupAdd)) args.push("--group-add", group); if (networkMode !== "host") { for (const dns of stringArray(host.Dns)) args.push("--dns", dns);