fix(onboard): reject macOS Podman compat socket before gateway launch (#7320) - #7353
Conversation
…#7320) Apple Silicon macOS forces the OpenShell Docker-driver gateway path. When the Docker CLI is routed to a Podman machine's docker-compat socket, Podman's /info mimics Docker (no 'podman' marker: ServerVersion '5.6.2', OperatingSystem 'fedora'), so preflight misclassified the runtime as 'docker', skipped the unsupported-runtime gate, and let onboarding force the Docker-driver gateway, which then binds Podman's VM-only bridge IP (10.89.1.1) and exits EADDRNOTAVAIL. Harden assessHost() to reclassify a Docker CLI fronting Podman's compatibility socket as 'podman' using observed docker-compat signals: the explicit 'docker version' 'Podman Engine' component (primary) and the /info ProductLicense 'Apache-2.0' (backstop). This makes the existing preflight rejection fire before any gateway launch. Podman stays unsupported per ci/platform-matrix.json; the recovery message now names Docker Engine, Docker Desktop, and Colima. Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
…7320) The codebase-growth-guardrails check forbids adding if statements to changed test files. Replace the platform guard with it.runIf(isLinuxDockerDriverGateway Enabled()) so the test body stays linear. Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
Align with CodeRabbit's requested API: it.skipIf(!isLinuxDockerDriverGateway Enabled()) is equivalent to the prior it.runIf and keeps the test body linear for the codebase-growth-guardrails check. Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughPodman Docker-compatibility detection was added to onboarding preflight. The runtime is reclassified before gateway setup, unsupported-runtime rejection is covered by tests, and error guidance now includes Docker Engine, Docker Desktop, and Colima. ChangesPodman preflight handling
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Onboarding
participant assessHost
participant DockerCLI
participant RuntimeGate
Onboarding->>assessHost: assess container runtime
assessHost->>DockerCLI: query docker version and info
DockerCLI-->>assessHost: compatibility metadata
assessHost->>RuntimeGate: classify runtime as podman or docker
RuntimeGate-->>Onboarding: reject unsupported Podman or continue Docker flow
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage in commit 67cf46d in the TypeScript / code-coverage/cliThe overall coverage in commit 67cf46d in the Show a code coverage summary of the most impacted files.
Updated |
PR Review Advisor — InformationalAdvisor assessment: Informational / medium confidence Model lanes
Nemotron output stays in workflow artifacts and does not change the assessment above. Since last review: 0 prior items resolved · 0 still apply · 0 new items found E2E guidanceAdvisory only. E2E / PR Gate selects and runs jobs independently. Recommended E2E: 1 optional E2E recommendation
This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/lib/onboard/fatal-runtime-preflight.test.ts (1)
9-30: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
hostWithRuntimeusesas HostAssessmentto paper over missing fields.The literal omits several
HostAssessmentfields (packageManager,systemctlAvailable,dockerServiceActive/dockerServiceEnabled,dockerInfoSummary,dockerCgroupVersion,dockerDefaultCgroupnsMode,dockerStorageDriver,dockerUsesContainerdSnapshotter,dockerCpus,dockerMemTotalBytes) and relies onas HostAssessmentto suppress the resulting type error. This defeats the compiler's missing-required-property check, so a future required field added toHostAssessmentwon't be caught here.♻️ Proposed fix: fill in the remaining fields (or type as Partial and merge)
function hostWithRuntime(runtime: HostAssessment["runtime"]): HostAssessment { return { platform: process.platform, isWsl: false, runtime, + packageManager: "unknown", + systemctlAvailable: false, + dockerServiceActive: null, + dockerServiceEnabled: null, dockerInstalled: true, dockerRunning: true, dockerReachable: true, nodeInstalled: true, openshellInstalled: true, + dockerInfoSummary: undefined, + dockerCgroupVersion: "unknown", + dockerDefaultCgroupnsMode: undefined, + dockerStorageDriver: undefined, + dockerUsesContainerdSnapshotter: false, + dockerCpus: undefined, + dockerMemTotalBytes: undefined, isContainerRuntimeUnderProvisioned: false, hasNestedOverlayConflict: false, requiresHostCgroupnsFix: false, isUnsupportedRuntime: runtime === "podman", isHeadlessLikely: false, hasNvidiaGpu: false, dockerCdiSpecDirs: [], cdiNvidiaGpuSpecMissing: false, nvidiaContainerToolkitInstalled: false, notes: [], - } as HostAssessment; + }; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lib/onboard/fatal-runtime-preflight.test.ts` around lines 9 - 30, Update hostWithRuntime to provide values for every required HostAssessment field, including packageManager, systemctlAvailable, Docker service/status details, resource metadata, and containerd snapshotter state. Remove the as HostAssessment assertion so the object literal is checked directly and future required fields remain compiler-enforced.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/lib/onboard/fatal-runtime-preflight.test.ts`:
- Around line 9-30: Update hostWithRuntime to provide values for every required
HostAssessment field, including packageManager, systemctlAvailable, Docker
service/status details, resource metadata, and containerd snapshotter state.
Remove the as HostAssessment assertion so the object literal is checked directly
and future required fields remain compiler-enforced.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: cd628443-7be2-41f1-b899-415c3134b320
📒 Files selected for processing (5)
src/lib/onboard/fatal-runtime-preflight.test.tssrc/lib/onboard/preflight-messages.test.tssrc/lib/onboard/preflight-messages.tssrc/lib/onboard/preflight-podman-compat.test.tssrc/lib/onboard/preflight.ts
…7320) Address CodeRabbit nitpick: the hostWithRuntime literal already provides every required HostAssessment field, so the `as HostAssessment` cast only suppressed the compiler's missing-property check. Removing it restores that check so a future required field is caught here. Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary Fixes a Docker Engine false positive discovered after #7353 merged. Positive `docker version` identity now overrides the ambiguous `ProductLicense: "Apache-2.0"` signal. Ambiguous version output retains the conservative Podman-compatible runtime rejection. ## Related Issue Follow-up to #7353 and #7320. ## Changes - Classify `docker version` output as Docker, Podman, or unknown. - Treat positive Docker identity as authoritative over the ambiguous info response. - Use the `ProductLicense` backstop when version output does not identify Docker or Podman. - Add regressions for Docker Engine reporting `Apache-2.0` and Podman-compatible info paired with ambiguous version output. - Use a behavior-oriented regression-test title with the required issue suffix. ## Type of Change - [x] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [x] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [ ] Tests not applicable — justification: - [ ] Docs updated for user-facing behavior changes - [x] Docs not applicable — justification: Existing commands, platform-support, and troubleshooting docs already state that Docker is supported and Podman is unsupported. This correction changes no supported surface or procedure. - [x] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [x] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: The correction accepts only positive Docker identity and retains the conservative rejection when version identity is unknown. - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Documentation Writer Review - [x] Documentation writer subagent reviewed the completed changes - Result: `no-docs-needed` - Evidence: Reviewed `src/lib/onboard/preflight.ts`, `src/lib/onboard/preflight-podman-compat.test.ts`, `docs/reference/commands.mdx`, `docs/reference/platform-support.mdx`, and `docs/reference/troubleshooting.mdx`. Existing docs already state that Docker is supported and Podman is unsupported; this correction changes no supported surface or procedure. - Agent: Codex Desktop <!-- docs-review-head-sha: 60f8b09 --> <!-- docs-review-agents-blob-sha: be20a09 --> ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: - Station profile/scenario: - Result: - Supporting evidence: ## Verification - [x] PR description includes a `Signed-off-by:` line and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run check:diff` passed when hooks were skipped or unavailable — normal pre-commit and commit-msg hooks passed; `npm run check:diff` passed at `60f8b094a`. - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — `npx vitest run --project cli src/lib/onboard/preflight-podman-compat.test.ts src/lib/onboard/preflight.test.ts` passed 136 tests; `npm run test:titles:check` passed. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: Not applicable; the correction changes one preflight identity predicate and its regression fixture. - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) - [ ] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) --- Signed-off-by: Carlos Villela <cvillela@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved onboarding runtime detection by more reliably classifying Docker vs Podman from version identity. * When Docker compatibility sockets are present but the version probe is empty or unexpected, Podman is still correctly detected and flagged as unsupported. * Real Docker installations are now correctly recognized as supported, including when the product license reports Apache-2.0. * **Tests** * Expanded compatibility preflight coverage for Podman masquerading scenarios and refined the Docker “supported” regression assertions. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Carlos Villela <cvillela@nvidia.com> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com> Co-authored-by: Apurv Kumaria <akumaria@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary Add the canonical `docs/changelog/2026-07-25.mdx` release entry with the exact `## v0.0.96` heading. The entry reconciles all 90 first-parent commits since v0.0.95 with all 92 merged PRs in the live `v0.0.96` label ledger and groups the user-visible changes by operator journey. ## Changes - Add the parser-safe dated MDX changelog entry for v0.0.96 with root-absolute links to the focused user guides. - Source summary: - [#7194](#7194) -> `docs/changelog/2026-07-25.mdx`: Document persistent baseline network policy exclusions and their inspection, rebuild, and snapshot behavior. - [#7188](#7188), [#7427](#7427), and [#7546](#7546) -> `docs/changelog/2026-07-25.mdx`: Document DNS-backed HTTPS inference routing, keyless loopback endpoints, and provider-marker isolation. - [#7238](#7238) -> `docs/changelog/2026-07-25.mdx`: Document blueprint sandbox and provider identifier validation before state writes or OpenShell calls, with bounded terminal-safe rejection previews. - [#7319](#7319), [#7274](#7274), [#7528](#7528), [#7353](#7353), and [#7560](#7560) -> `docs/changelog/2026-07-25.mdx`: Document the managed default gateway service, onboarding readiness, and container-runtime identity safeguards. - [#7349](#7349), [#7498](#7498), [#7406](#7406), [#7196](#7196), [#7559](#7559), [#7421](#7421), [#7510](#7510), [#7295](#7295), and [#7565](#7565) -> `docs/changelog/2026-07-25.mdx`: Document gateway-scoped status, lifecycle diagnostics, managed MCP recovery, delete-edge safeguards, and fail-closed CLI prompt and command output. - [#7591](#7591) -> `docs/changelog/2026-07-25.mdx`: Document opt-in authenticated MCP tool-name discovery, its bounded and names-only contract, probe interaction, and rebuild requirement. - [#7305](#7305), [#7480](#7480), [#7471](#7471), [#7365](#7365), and [#7541](#7541) -> `docs/changelog/2026-07-25.mdx`: Document installer version checks, version-tag reporting, license guidance, WSL Ollama selection, and DGX Station vLLM detection. - [#7482](#7482), [#7466](#7466), [#7208](#7208), [#7434](#7434), and [#7586](#7586) -> `docs/changelog/2026-07-25.mdx`: Document Ollama resource details, reasoning precedence, Hermes onboarding behavior, and preserved managed Hermes BuildKit failures. - [#6830](#6830), [#7492](#7492), [#7563](#7563), and [#7582](#7582) -> `docs/changelog/2026-07-25.mdx`: Document the authoritative OpenClaw production lock, fixed managed-image dependencies, immutable Hermes base adoption, and Hermes image-size reduction. - [#7505](#7505), [#7530](#7530), [#7547](#7547), [#7508](#7508), [#7548](#7548), [#7549](#7549), [#7537](#7537), [#7534](#7534), [#7515](#7515), [#7511](#7511), [#7551](#7551), [#7562](#7562), [#7575](#7575), [#7496](#7496), [#7594](#7594), [#7595](#7595), and [#7599](#7599) -> `docs/changelog/2026-07-25.mdx`: Summarize release validation, transient and bounded dispatch reconciliation, exact pre-tag qualification, identity revalidation, npm-audit retry, sharding, image reuse, timeout, telemetry, and workflow-hardening changes. - Reconciled without separate changelog prose: - [#7539](#7539), [#7526](#7526), [#7507](#7507), [#7506](#7506), [#7519](#7519), [#7516](#7516), [#7396](#7396), [#7254](#7254), [#7583](#7583), [#7596](#7596), and [#7598](#7598): Test-harness or fixture-only changes. - [#7403](#7403), [#7161](#7161), [#6877](#6877), [#7531](#7531), [#7525](#7525), [#7522](#7522), [#7536](#7536), [#7552](#7552), [#7566](#7566), [#7553](#7553), [#7561](#7561), [#7577](#7577), [#7569](#7569), [#7585](#7585), [#7584](#7584), [#7592](#7592), [#7580](#7580), [#7571](#7571), [#7517](#7517), [#7589](#7589), [#7402](#7402), [#7558](#7558), [#7544](#7544), and [#7601](#7601): Dependency, internal recovery, validation, contributor-workflow, E2E optimization, telemetry, or CI trust changes with no separate user-facing release claim. - [#7556](#7556), [#7573](#7573), [#7576](#7576), and [#7578](#7578): Experimental repository-maintainer conflict automation with no canonical user documentation surface. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [ ] Tests added or updated for changed behavior - [x] Existing tests cover changed behavior — justification: `test/changelog-docs.test.ts` validates dated changelog structure, version headings, and published links. - [ ] Tests not applicable — justification: - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [ ] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Documentation Writer Review - [x] Documentation writer subagent reviewed the completed changes - Result: `docs-updated` - Evidence: Reviewed `docs/changelog/2026-07-25.mdx` at exact head `0f5dedb47` against 90 first-parent release commits and 92 merged PRs labeled `v0.0.96`. Verified parser-safe MDX SPDX, the exact version heading, literal CLI names, writing style, skip terms, all 20 root-absolute published links, and the accepted #7591 opt-in authenticated discovery bounds. #7544, #7599, and #7601 remain internal or CI-only release-ledger entries. Changelog tests passed 6/6, the docs build passed with 0 errors and two pre-existing Fern warnings, and `npm run check:diff` plus the final diff check passed. - Agent: Codex Desktop documentation-writer subagent <!-- docs-review-head-sha: 0f5dedb --> <!-- docs-review-agents-blob-sha: be20a09 --> ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: - Station profile/scenario: - Result: - Supporting evidence: ## Verification - [x] PR description includes a `Signed-off-by:` line and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run check:diff` passed when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — `npx vitest run test/changelog-docs.test.ts`: 6/6 passed. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: Not applicable to this prose-only changelog entry. - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) — the build passed with 0 errors and 2 existing Fern warnings; the published-route check passed. - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) — native changelog files use the required parser-safe MDX SPDX comment and no frontmatter. --- Signed-off-by: Carlos Villela <cvillela@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Persistent network policy exclusions with consistent restore/exclusion reporting across rebuilds/snapshots. * Opt-in MCP tool discovery via `mcp status --tools` with bounded, redacted authenticated traffic. * Improved HTTPS inference switching for custom endpoints and refreshed onboarding/model menu details. * Refined OpenShell gateway defaults for port `8080`, including more reliable readiness checks. * **Bug Fixes** * Prevent incorrect provider/model restoration after compatible-provider update failures. * Preserve managed MCP state after exec loss and tighten gateway/doctor status scoping. * **Tests** * Stronger, fail-closed release validation with hardened evidence/artifact handoff and bounded timeouts/retries. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com> Co-authored-by: Prekshi Vyas <prekshiv@nvidia.com>
Summary
On Apple Silicon macOS, onboarding forces the OpenShell Docker-driver gateway path. When the Docker CLI is routed to a Podman machine's Docker compatibility socket, preflight failed to recognize Podman and let onboarding start the Docker-driver gateway, which then bound Podman's VM-only bridge address (
10.89.1.1:8080) and exitedEADDRNOTAVAIL. This change detects Podman behind the compatibility socket in preflight and fails closed early with the existing unsupported-runtime guidance, before any gateway launch. Podman remains unsupported perci/platform-matrix.json; no Podman support is added.Related Issue
Fixes #7320
Changes
src/lib/onboard/preflight.ts:assessHost()now reclassifies a Docker CLI fronting Podman's docker-compat socket asruntime: "podman". Podman's/infomimics Docker and carries no"podman"marker (observed:ServerVersion "5.6.2",OperatingSystem "fedora"), so detection uses two observed docker-compat signals: the explicitdocker version --format '{{json .}}'"Podman Engine"server component (primary), and the/infoProductLicense: "Apache-2.0"(backstop when the version probe is unavailable). Thedocker versionprobe runs only when the daemon is reachable. No false positives on Docker Engine, Docker Desktop, or Colima.src/lib/onboard/preflight-messages.ts: the unsupported-runtime recovery message now names Docker Engine, Docker Desktop, and Colima (macOS reporters use Docker Desktop/Colima, not native Docker Engine).preflight-podman-compat.test.ts(real docker-compatinfo+versionmetadata drivesruntime: "podman"; real Docker stays supported) andfatal-runtime-preflight.test.ts(the rejection path); message-guidance assertions inpreflight-messages.test.ts.The existing preflight gate (
rejectUnsupportedContainerRuntime) already runs on both the fresh and resume paths before the gateway state; correcting runtime detection is what makes it fire. No new abstraction, config, or fallback path is introduced.Type of Change
Quality Gates
docs/reference/platform-support.mdxandtroubleshooting.mdxalready document Podman as unsupported and direct users to Docker Engine/Docker Desktop/Colima; this fix makes that already-documented rejection actually fire for the macOS docker-compat case.code-review(high) surfaced only two low-severity, non-blocking design notes (ProductLicense backstop scope; one extradocker versionsubprocess per reachable-DockerassessHost), both acceptable; awaiting maintainer sensitive-path review.Verification
Signed-off-by:line and every commit appears asVerifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run check:diffpassed when hooks were skipped or unavailablenpx vitest run src/lib/onboard/preflight-podman-compat.test.ts src/lib/onboard/fatal-runtime-preflight.test.ts src/lib/onboard/preflight-messages.test.ts src/lib/onboard/preflight.test.ts→ 143 passed; full--project cli→ 9593 passed / 1 skipped.Real-CLI E2E (Apple Silicon macOS, Podman docker-compat socket)
Reproduced the exact reporter command
./bin/nemoclaw.js onboard --freshon an Apple Silicon macOS host (macOS 26.5.2, arm64) with a runningpodman machinewhose Docker compatibility socket forwards to/var/run/docker.sock, Docker CLI 29.3.1 routed to it (ServerVersion 5.6.2,ProductLicense Apache-2.0,DefaultRuntime crun).✓ Container runtime: docker) and advanced to[2/8] Starting OpenShell gateway → Starting OpenShell Docker-driver gateway— the forced Docker-driver path the reporter hits.[1/8] Preflight checkswith✗ … Podman is not supported for this NemoClaw integration path. Switch to Docker Engine, Docker Desktop, or Colima, then rerun onboarding.and exits non-zero (1), before any gateway launch.assessHost()against the live socket now reportsruntime: "podman",isUnsupportedRuntime: true.Signed-off-by: Yimo Jiang yimoj@nvidia.com
Summary by CodeRabbit