Skip to content

fix(onboard): route portable gateway reachability probe - #8732

Merged
cv merged 13 commits into
mainfrom
fix/e2e-portable-gateway-reachability
Aug 10, 2026
Merged

fix(onboard): route portable gateway reachability probe#8732
cv merged 13 commits into
mainfrom
fix/e2e-portable-gateway-reachability

Conversation

@cv

@cv cv commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Portable-profile gateway reachability probes now map host.openshell.internal to the OpenShell Podman host gateway instead of the inspected Podman network gateway. Onboarding uses route-specific recovery guidance and preserves the portable profile in the rerun command.

E2E root cause: portable profile / sandbox bridge reachability / probe maps host.openshell.internal to the Podman network gateway instead of the OpenShell host gateway
Source run: https://github.com/NVIDIA/NemoClaw/actions/runs/31382319323 (run 31382319323, attempt 1)
Failed jobs: portable-launch (93435056045, https://github.com/NVIDIA/NemoClaw/actions/runs/31382319323/job/93435056045)
Signature: sandbox containers cannot reach host.openshell.internal:8080 through 10.89.0.1; the portable contract uses 169.254.1.2
Scope: one root cause

Changes

  • Add regression coverage for the portable probe route, returned route metadata, TCP retries, daemon inspection failures, and recovery output.
  • Route portable-profile probes through the existing OpenShell Podman host-gateway constant and preserve daemon failures before route metadata exists.
  • Keep portable, Docker host-gateway, and Docker bridge diagnostics distinct while sharing route-neutral retry output.
  • Move portable-profile constants into a leaf module because a direct platform-module import creates a runtime dependency cycle. The repository architecture check protects the cycle-free contract.
  • Document the Podman recovery procedure in docs/reference/commands.mdx and docs/reference/troubleshooting.mdx.

Type of Change

  • 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

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • 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: All nine security-rubric categories pass. The route uses a fixed compile-time address and does not change credentials, authentication, TLS, gateway binding, dependencies, or policy. Recovery commands are printed for the operator and are not executed by NemoClaw.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: docs-updated
  • Evidence: Reviewed docs/reference/commands.mdx and docs/reference/troubleshooting.mdx against the implementation, tests, writing rules, and all generated agent variants. The pages distinguish portable Podman recovery from Docker UFW remediation and describe the user-scoped service and socket effects.
  • Agent: Pi CLI

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit: Not applicable; scripts/prepare-dgx-station-host.sh did not change.
  • Station profile/scenario: Not applicable.
  • Result: Not applicable.
  • Supporting evidence: Not applicable.

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run validate:pr passed after refreshing origin/main when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — npx vitest run --project cli src/lib/onboard/gateway-sandbox-reachability.test.ts src/lib/onboard/gateway-sandbox-reachability-severity.test.ts — 53 tests passed; npm run checks:repository — passed with 0 source dependency cycles.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result:
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only) — npm run docs passed with 0 errors and 2 existing warnings.
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Carlos Villela cvillela@nvidia.com

Summary by CodeRabbit

  • New Features

    • Added support for an experimental portable onboarding profile.
    • Portable environments now use the appropriate host gateway and local registry configuration.
    • Improved sandbox connectivity by mapping the internal host address to the portable environment gateway.
  • Bug Fixes

    • Improved reachability checks, retries, and error handling for portable environments.
    • Added clearer recovery guidance for unreachable Podman gateways and excluded unnecessary Docker firewall remediation.
  • Documentation

    • Added portable onboarding connectivity details and troubleshooting steps, including service and socket verification.

@cv cv self-assigned this Aug 10, 2026
@copy-pr-bot

copy-pr-bot Bot commented Aug 10, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The change moves portable profile APIs into a dedicated module and re-exports them through the platform module. Reachability probes use 169.254.1.2 and map host.openshell.internal to that address when the portable profile is active. Portable failures provide Podman recovery guidance.

Changes

Portable profile gateway routing

Layer / File(s) Summary
Portable profile API
src/lib/onboard/experimental/portable-profile.ts, src/lib/onboard/docker-driver-platform.ts
The portable profile constants, type, resolver, and detection helper now live in a dedicated module. The platform module re-exports the public names.
Portable gateway reachability
src/lib/onboard/gateway-sandbox-reachability.ts
Portable probes use 169.254.1.2 as the host gateway and map host.openshell.internal to it. Runtime probe failures can classify the Podman daemon as unavailable. Portable TCP failures use host-gateway retry handling.
Recovery guidance and validation
src/lib/onboard/gateway-sandbox-reachability.ts, src/lib/onboard/gateway-sandbox-reachability.test.ts, src/lib/onboard/gateway-sandbox-reachability-severity.test.ts, docs/reference/commands.mdx, docs/reference/troubleshooting.mdx
Portable failures provide user-scoped Podman service and socket recovery commands. Tests and documentation cover portable routing, remediation, retry behavior, and revised gateway errors.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ReachabilityProbe
  participant PortableProfile
  participant DockerRouteConstruction
  participant PodmanGateway
  ReachabilityProbe->>PortableProfile: Check portable profile
  PortableProfile-->>ReachabilityProbe: Return profile status
  ReachabilityProbe->>DockerRouteConstruction: Pass 169.254.1.2 when portable
  DockerRouteConstruction->>PodmanGateway: Map host.openshell.internal to 169.254.1.2
  PodmanGateway-->>ReachabilityProbe: Return TCP reachability
  ReachabilityProbe-->>ReachabilityProbe: Retry or print Podman recovery guidance
Loading

Possibly related PRs

Suggested labels: bug-fix, area: onboarding, platform: container

Suggested reviewers: apurvvkumaria

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: fixing portable gateway reachability probes during onboarding.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/e2e-portable-gateway-reachability

Comment @coderabbitai help to get the list of available commands.

@github-code-quality

github-code-quality Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 036f2c0 in the fix/e2e-portable-gat... branch remains at 96%, unchanged from commit acf810d in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 036f2c0 in the fix/e2e-portable-gat... branch remains at 82%, unchanged from commit acf810d in the main branch.

Show a code coverage summary of the most impacted files.
File main acf810d fix/e2e-portable-gat... 036f2c0 +/-
src/lib/inferen...time-context.ts 93% 84% -9%
src/lib/inferen...er-lifecycle.ts 77% 70% -7%
src/lib/inferen...del-registry.ts 100% 93% -7%
src/lib/inferen...talog-loader.ts 86% 82% -4%
src/lib/policy/...y-validation.ts 100% 97% -3%
src/lib/inferen...-ssh-binding.ts 89% 87% -2%
src/lib/inferen...ter-registry.ts 96% 95% -1%
src/lib/policy/index.ts 67% 67% 0%
src/lib/inferen...ter-topology.ts 89% 89% 0%
src/lib/onboard...able-profile.ts 0% 100% +100%

Updated August 10, 2026 13:16 UTC

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · medium confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 1 warning · 1 suggestion
  • Model comparison: normalized findings differ; normalized terminology decisions differ; normalized E2E selections differ; Nemotron reported the same number of blockers, 1 more warning, 1 more suggestion.
3 terminology differences from the second opinion

Advisory only. These are normalized differences from the primary terminology receipt.

  • OpenShell Podman host gateway at docs/reference/commands.mdx:775: primary classified it as justified; the second opinion classified it as define.
  • user-scoped at docs/reference/commands.mdx:777: selected only by the second-opinion lane as established.
  • portable_host_gateway at src/lib/onboard/gateway-sandbox-reachability.ts:51: selected only by the second-opinion lane as define.
2 additional E2E selections from the second opinion

Advisory only. The primary lane did not select these E2E jobs or targets.

  • onboard-managed-image-buildless-e2e: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • full-e2e: The completed second-opinion lane identified E2E coverage that the primary lane omitted.

Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests.

3 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • established — portable experimental profile at docs/reference/commands.mdx:775: Keep `portable experimental profile` for this existing profile.
  • justified — OpenShell Podman host gateway at docs/reference/commands.mdx:775: Keep the modifier because it identifies the route used by portable sandbox containers.
  • justified — user-scoped Podman service at docs/reference/commands.mdx:777: Keep `user-scoped` because the recovery commands target only the current user's Podman units.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite against this exact revision.

Recommended E2E: onboard-repair, onboard-resume, cloud-onboard

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

@cv
cv marked this pull request as ready for review August 10, 2026 11:45
@github-actions

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@src/lib/onboard/gateway-sandbox-reachability.ts`:
- Around line 470-481: Update the reachability result handling before the
generic docker_daemon_unreachable branch so an active portable profile routes
that failure through the Podman recovery guidance, including the service and
socket commands. Use the existing portable-profile context or add an explicit
marker to SandboxBridgeReachabilityResult, and add a regression test covering
portable docker_daemon_unreachable results.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c1155d08-0612-421d-ad37-a1e4727004c5

📥 Commits

Reviewing files that changed from the base of the PR and between 25c7e39 and 5c33dae.

📒 Files selected for processing (4)
  • docs/reference/commands.mdx
  • docs/reference/troubleshooting.mdx
  • src/lib/onboard/gateway-sandbox-reachability.test.ts
  • src/lib/onboard/gateway-sandbox-reachability.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/onboard/gateway-sandbox-reachability.test.ts

Comment thread src/lib/onboard/gateway-sandbox-reachability.ts
@wscurran wscurran added area: networking DNS, proxy, TLS, ports, host aliases, or connectivity area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression labels Aug 10, 2026
@cv
cv merged commit 5e93467 into main Aug 10, 2026
76 of 78 checks passed
@cv
cv deleted the fix/e2e-portable-gateway-reachability branch August 10, 2026 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: networking DNS, proxy, TLS, ports, host aliases, or connectivity area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants