Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/lib/actions/sandbox/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,15 @@ function probeSandboxInferenceRoute(
}

function shouldUseLegacyDnsProxyRepair(sb: SandboxEntry | null): boolean {
return sb?.openshellDriver !== "vm";
// The legacy repair patches CoreDNS inside an `openshell-cluster-<name>`
// container, which only the k3s/kubernetes gateway runs. The docker driver
// runs the gateway as `nemoclaw-openshell-gateway` with host networking, and
// the vm driver has no cluster container either, so both recover the route via
// `openshell inference set` instead of the cluster CoreDNS patch. Mirrors
// usesGatewayMetadataProbe (snapshot.ts) and the `!== "docker"` guard on the
// snapshot DNS-proxy step. (#3403)
const driver = sb?.openshellDriver;
return driver !== "vm" && driver !== "docker";
}

function buildInferenceSetArgs(provider: string, model: string): string[] {
Expand Down
59 changes: 56 additions & 3 deletions test/sandbox-connect-inference.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ describe("sandbox connect inference route swap (#1248)", () => {
);

it(
"repairs the sandbox DNS proxy when inference.local returns 503",
"repairs the kubernetes sandbox DNS proxy when inference.local returns 503",
testTimeoutOptions(20_000),
() => {
const { tmpDir, stateFile, sandboxName } = setupFixture(
Expand All @@ -488,7 +488,7 @@ describe("sandbox connect inference route swap (#1248)", () => {
model: "nvidia/nemotron-3-super-120b-a12b",
provider: "nvidia-prod",
gpuEnabled: false,
openshellDriver: "docker",
openshellDriver: "kubernetes",
policies: [],
},
"nvidia-prod",
Expand Down Expand Up @@ -531,6 +531,59 @@ describe("sandbox connect inference route swap (#1248)", () => {
},
);

it(
"recovers the route via inference set for docker sandboxes without the legacy cluster repair (#3403)",
testTimeoutOptions(20_000),
() => {
const { tmpDir, stateFile, sandboxName } = setupFixture(
{
name: "docker-route-sandbox",
model: "nvidia/nemotron-3-super-120b-a12b",
provider: "nvidia-prod",
gpuEnabled: false,
openshellDriver: "docker",
policies: [],
},
"nvidia-prod",
"nvidia/nemotron-3-super-120b-a12b",
{
inferenceProbeResponses: [
'BROKEN 503 {"error":"inference service unavailable"}',
"OK 200",
],
},
);

const result = runConnect(tmpDir, sandboxName);
expect(result.status).toBe(0);

const state = JSON.parse(fs.readFileSync(stateFile, "utf-8"));
const dockerCalls = state.dockerCalls as string[][];
// The docker driver has no openshell-cluster container (the gateway runs
// as nemoclaw-openshell-gateway with host networking), so it must NOT take
// the legacy CoreDNS cluster repair; it recovers via `inference set`. (#3403)
expect(state.inferenceSetCalls).toEqual([
[
"--provider",
"nvidia-prod",
"--model",
"nvidia/nemotron-3-super-120b-a12b",
"--no-verify",
],
]);
expect(
dockerCalls.some((call) =>
call.join(" ").includes("get service kube-dns"),
),
).toBe(false);

const combined = (result.stdout || "") + (result.stderr || "");
expect(combined).toContain("Reapplying OpenShell inference route");
expect(combined).toContain("inference.local route repaired");
expect(combined).not.toContain("Could not find gateway container");
},
);

it(
"does not run legacy DNS proxy repair for VM sandboxes",
testTimeoutOptions(20_000),
Expand Down Expand Up @@ -933,7 +986,7 @@ describe("sandbox connect inference route swap (#1248)", () => {
model: "nvidia/nemotron-3-super-120b-a12b",
provider: "nvidia-prod",
gpuEnabled: false,
openshellDriver: "docker",
openshellDriver: "kubernetes",
policies: [],
},
"nvidia-prod",
Expand Down
Loading