From 4248b42edda27fb2a1c4aa344203d9d82f75bab3 Mon Sep 17 00:00:00 2001 From: Yimo Jiang Date: Tue, 26 May 2026 06:24:26 +0000 Subject: [PATCH] fix(onboard): record Docker driver for macOS docker-driver sandboxes (#3728) The metadata helper mapped `process.platform === "darwin"` to `openshellDriver: "vm"` even when the Docker-driver gateway path was enabled. OpenShell's Docker-driver gateway always starts with `OPENSHELL_DRIVERS=docker`, including on macOS arm64 (#3454), so a fresh macOS sandbox onboarded today is a Docker sandbox, not a VM sandbox. Recording `"vm"` made the post-create flow run the VM-only DNS monkeypatch and surface its warning text for Docker-driver sandboxes, which is what #3728 reports. Drop the platform branch so the docker- driver path records `"docker"` on every supported host; legacy opt-in/already-registered VM sandboxes still match the `"vm"` checks they already wrote to disk. Adds a unit test for the metadata helper and an onboard wrapper regression test asserting macOS Docker-driver sandboxes emit no VM DNS monkeypatch log/warn output. Host can't run macOS directly, so the regression is covered via mocked `process.platform`. Signed-off-by: Yimo Jiang --- .../onboard/sandbox-registry-metadata.test.ts | 69 +++++++++++++++++++ src/lib/onboard/sandbox-registry-metadata.ts | 10 +-- src/lib/onboard/vm-dns-monkeypatch.test.ts | 28 ++++++++ 3 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 src/lib/onboard/sandbox-registry-metadata.test.ts diff --git a/src/lib/onboard/sandbox-registry-metadata.test.ts b/src/lib/onboard/sandbox-registry-metadata.test.ts new file mode 100644 index 00000000000..1935956f36c --- /dev/null +++ b/src/lib/onboard/sandbox-registry-metadata.test.ts @@ -0,0 +1,69 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { afterEach, describe, expect, it } from "vitest"; +// Import the compiled module: sandbox-registry-metadata.ts pulls in state/registry, +// which transitively requires the JS-only `./platform` helper that vitest cannot +// resolve from TS source. Same pattern as `vm-dns-monkeypatch.test.ts`. +import { createSandboxRegistryMetadataHelpers } from "../../../dist/lib/onboard/sandbox-registry-metadata"; +import type { SandboxGpuConfig } from "./sandbox-gpu-mode"; + +const ORIGINAL_PLATFORM = Object.getOwnPropertyDescriptor(process, "platform"); + +function setPlatform(platform: NodeJS.Platform): void { + Object.defineProperty(process, "platform", { value: platform, configurable: true }); +} + +function restorePlatform(): void { + if (ORIGINAL_PLATFORM) { + Object.defineProperty(process, "platform", ORIGINAL_PLATFORM); + } +} + +function makeHelpers(opts: { dockerDriverEnabled: boolean }) { + return createSandboxRegistryMetadataHelpers({ + isLinuxDockerDriverGatewayEnabled: () => opts.dockerDriverEnabled, + getInstalledOpenshellVersion: () => "0.0.42", + runCaptureOpenshell: () => null, + }); +} + +const GPU_OFF: SandboxGpuConfig = { + hostGpuDetected: false, + hostGpuPlatform: null, + sandboxGpuEnabled: false, + mode: "auto", + sandboxGpuDevice: null, + errors: [], +}; + +describe("getSandboxRuntimeRegistryFields openshellDriver", () => { + afterEach(restorePlatform); + + it("records Docker for macOS sandboxes on the Docker-driver gateway path", () => { + setPlatform("darwin"); + const helpers = makeHelpers({ dockerDriverEnabled: true }); + + const fields = helpers.getSandboxRuntimeRegistryFields(GPU_OFF); + + expect(fields.openshellDriver).toBe("docker"); + }); + + it("records Docker for Linux sandboxes on the Docker-driver gateway path", () => { + setPlatform("linux"); + const helpers = makeHelpers({ dockerDriverEnabled: true }); + + const fields = helpers.getSandboxRuntimeRegistryFields(GPU_OFF); + + expect(fields.openshellDriver).toBe("docker"); + }); + + it("records Kubernetes for legacy Linux sandboxes when the Docker-driver gateway is disabled", () => { + setPlatform("linux"); + const helpers = makeHelpers({ dockerDriverEnabled: false }); + + const fields = helpers.getSandboxRuntimeRegistryFields(GPU_OFF); + + expect(fields.openshellDriver).toBe("kubernetes"); + }); +}); diff --git a/src/lib/onboard/sandbox-registry-metadata.ts b/src/lib/onboard/sandbox-registry-metadata.ts index bbd84db74ed..c6a69ba7103 100644 --- a/src/lib/onboard/sandbox-registry-metadata.ts +++ b/src/lib/onboard/sandbox-registry-metadata.ts @@ -49,17 +49,17 @@ export function createSandboxRegistryMetadataHelpers( | "openshellDriver" | "openshellVersion" > { + // OpenShell's Docker-driver gateway always starts with OPENSHELL_DRIVERS=docker, + // including on macOS arm64 (#3454). Recording "vm" for darwin here makes later + // setup misclassify the sandbox and run VM-only DNS monkeypatch / warning paths + // (#3728). return { gpuEnabled: config.sandboxGpuEnabled, hostGpuDetected: config.hostGpuDetected, sandboxGpuEnabled: config.sandboxGpuEnabled, sandboxGpuMode: config.mode, sandboxGpuDevice: config.sandboxGpuDevice, - openshellDriver: deps.isLinuxDockerDriverGatewayEnabled() - ? process.platform === "darwin" - ? "vm" - : "docker" - : "kubernetes", + openshellDriver: deps.isLinuxDockerDriverGatewayEnabled() ? "docker" : "kubernetes", openshellVersion: deps.getInstalledOpenshellVersion( deps.runCaptureOpenshell(["--version"], { ignoreError: true }), ), diff --git a/src/lib/onboard/vm-dns-monkeypatch.test.ts b/src/lib/onboard/vm-dns-monkeypatch.test.ts index 26445956a22..c6a090edd77 100644 --- a/src/lib/onboard/vm-dns-monkeypatch.test.ts +++ b/src/lib/onboard/vm-dns-monkeypatch.test.ts @@ -3,6 +3,7 @@ import { describe, expect, it } from "vitest"; +import { applyOpenShellVmDnsMonkeypatch } from "../../../dist/lib/actions/sandbox/vm-dns-monkeypatch"; import { applyOnboardVmDnsMonkeypatch } from "../../../dist/lib/onboard/vm-dns-monkeypatch"; describe("applyOnboardVmDnsMonkeypatch", () => { @@ -93,4 +94,31 @@ describe("applyOnboardVmDnsMonkeypatch", () => { " Warning: OpenShell VM DNS monkeypatch did not apply: VM rootfs not found", ]); }); + + // Regression: #3728. macOS Docker-driver sandboxes were misclassified as VM + // and ran the VM-only DNS monkeypatch path, which printed misleading warnings. + // The Docker runtime path should be silent — no "skipped", no "Warning". + it("emits no output for macOS Docker-driver sandboxes", () => { + const logs: string[] = []; + const warns: string[] = []; + + applyOnboardVmDnsMonkeypatch( + "mac-docker", + { openshellDriver: "docker" }, + { + apply: (sandboxName, entry) => + applyOpenShellVmDnsMonkeypatch(sandboxName, entry, { + capture: () => ({ status: 0, output: "" }), + env: {}, + platform: "darwin", + stateDir: "/tmp/nemoclaw-test-state-3728", + }), + log: (message) => logs.push(message), + warn: (message) => warns.push(message), + }, + ); + + expect(logs).toEqual([]); + expect(warns).toEqual([]); + }); });