Skip to content

fix(installer): select portable Podman override before preflight - #8408

Merged
ericksoa merged 4 commits into
mainfrom
fix/portable-podman-runtime-override-signed
Aug 6, 2026
Merged

fix(installer): select portable Podman override before preflight#8408
ericksoa merged 4 commits into
mainfrom
fix/portable-podman-runtime-override-signed

Conversation

@ericksoa

@ericksoa ericksoa commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Portable installer runs were reaching ordinary Docker bootstrap and host preflight before the hidden profile could select rootless Podman. This change applies the same Podman socket override used by the working GFN setup before those gates, then forwards the hidden profile into onboarding without disabling GPU.

Related Issue

Follow-up to #8376.

Changes

  • Accept the existing hidden portable profile at the installer boundary and forward it to the actual onboard command.
  • Start the rootless Podman user socket and derive DOCKER_HOST from podman info before Docker bootstrap and installer host preflight.
  • Make CLI host preparation use the Podman-reported socket instead of assuming a UID-derived path.
  • Exercise the installer selector in the rootless portable E2E and trigger that workflow for installer changes.

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: Repairs installer forwarding and rootless Podman socket selection for an existing hidden experimental profile; no supported public workflow changed.
  • 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: Maintainer-directed urgent corrective follow-up to merged feat(onboard): add portable experimental profile #8376.
  • 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: no-docs-needed
  • Evidence: The profile remains hidden; no docs paths changed. Reviewer-requested help text and historical wording were removed before commit; the follow-up edge-case fix, final GPU regression assertion, and required current-main merge were re-reviewed.
  • Agent: Codex Desktop

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit:
  • Station profile/scenario:
  • Result:
  • Supporting evidence:

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 — 76 CLI tests and 21 installer integration tests passed; npm run typecheck and semantic E2E phase validation passed.
  • 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)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Aaron Erickson aerickson@nvidia.com

Summary by CodeRabbit

  • New Features

    • Added an experimental portable profile for Linux environments using rootless Podman.
    • Automatically detects and uses Podman’s runtime socket.
    • Added validation for required tools, services, socket paths, and profile values.
    • The portable profile is forwarded during onboarding and runtime preparation.
  • Bug Fixes

    • Installation now stops when runtime socket discovery returns an invalid path.
  • Tests

    • Expanded coverage for portable profile setup, socket selection, onboarding, and failure scenarios.

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa ericksoa self-assigned this Aug 5, 2026
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The installer adds a portable experimental profile that starts rootless Podman, resolves its API socket, exports DOCKER_HOST, and forwards the profile to onboarding. Host preparation and tests validate socket handling, CLI parsing, onboarding propagation, and E2E coverage.

Changes

Portable profile runtime

Layer / File(s) Summary
Installer profile and runtime preparation
scripts/install.sh, test/install-portable-profile.test.ts, test/install-onboard-yes.test.ts, src/lib/onboard/command.test.ts
The installer parses and validates --experimental-profile, prepares the Podman runtime before Docker setup, exports DOCKER_HOST, and forwards portable to onboarding. Tests cover profile selection, propagation, and deterministic GPU defaults.
Dynamic Podman socket resolution
src/lib/onboard/experimental/portable-host-preparation.ts, src/lib/onboard/experimental/portable-host-preparation.test.ts
Host preparation resolves the Podman-reported socket, normalizes valid paths, rejects invalid output, and supports injectable Podman execution.
Portable profile integration validation
test/e2e/live/portable-profile-rootless-linux.test.ts, .github/workflows/portable-profile-e2e.yaml
The live Linux test verifies installer-selected socket discovery. The workflow runs for installer changes on pull requests and pushes.

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

Sequence Diagram(s)

sequenceDiagram
  participant Installer
  participant systemctl
  participant Podman
  participant DockerCLI
  participant Onboarding
  Installer->>systemctl: Start podman.socket
  Installer->>Podman: Query Host.RemoteSocket.Path
  Podman-->>Installer: Return rootless socket
  Installer->>DockerCLI: Set DOCKER_HOST
  Installer->>Onboarding: Pass --experimental-profile portable
Loading

Possibly related PRs

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

Suggested reviewers: apurvvkumaria, yanyunl1991

🚥 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 summarizes the main change: selecting the portable Podman override before installer preflight.
✨ 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/portable-podman-runtime-override-signed

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

@github-code-quality

github-code-quality Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit f7a2644 in the fix/portable-podman-... branch remains at 96%, unchanged from commit e7b50a0 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit f7a2644 in the fix/portable-podman-... branch remains at 82%, unchanged from commit e7b50a0 in the main branch.

Show a code coverage summary of the most impacted files.
File main e7b50a0 fix/portable-podman-... f7a2644 +/-
src/lib/inferen...er-discovery.ts 88% 87% -1%
src/lib/onboard...-preparation.ts 89% 89% 0%
src/lib/sandbox...rce-identity.ts 87% 87% 0%

Updated August 05, 2026 23:51 UTC

@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: 2

🧹 Nitpick comments (1)
src/lib/onboard/experimental/portable-host-preparation.ts (1)

189-200: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Guard portable onboarding from the fixed socket fallback.

src/lib/runner.ts calls detectDockerHost() at module load and can set DOCKER_HOST to a fixed Podman socket before preparePortableExperimentalHost runs. Skip fixed-candidate detection for NEMOCLAW_EXPERIMENTAL_PROFILE=portable or defer it until after preparation. Add a public portable-entrypoint test.

🤖 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/experimental/portable-host-preparation.ts` around lines 189 -
200, Update detectDockerHost in src/lib/runner.ts to skip fixed-candidate
detection when NEMOCLAW_EXPERIMENTAL_PROFILE is portable, allowing
preparePortableExperimentalHost to resolve the socket via Podman. Preserve
existing detection behavior for other profiles, and add a test through the
public portable entrypoint verifying preparation is not overridden by the fixed
fallback.

Source: Path instructions

🤖 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 `@scripts/install.sh`:
- Around line 5011-5014: Update the empty branch of the EXPERIMENTAL_PROFILE
case to unset NEMOCLAW_EXPERIMENTAL_PROFILE, ensuring an explicitly empty
--experimental-profile value clears any inherited portable profile; preserve the
existing export and error behavior for portable and unknown values.

In `@test/install-portable-profile.test.ts`:
- Around line 29-32: Update runPortableOverride to pass a fixed sentinel
DOCKER_HOST value in the child environment instead of inheriting the parent
value, then assert that the no-profile path runPortableOverride("") preserves
that sentinel when no override is applied.

---

Nitpick comments:
In `@src/lib/onboard/experimental/portable-host-preparation.ts`:
- Around line 189-200: Update detectDockerHost in src/lib/runner.ts to skip
fixed-candidate detection when NEMOCLAW_EXPERIMENTAL_PROFILE is portable,
allowing preparePortableExperimentalHost to resolve the socket via Podman.
Preserve existing detection behavior for other profiles, and add a test through
the public portable entrypoint verifying preparation is not overridden by the
fixed fallback.
🪄 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: 4b2540ee-f798-4707-8981-ce85384835d0

📥 Commits

Reviewing files that changed from the base of the PR and between db31c28 and d3caa33.

📒 Files selected for processing (7)
  • .github/workflows/portable-profile-e2e.yaml
  • scripts/install.sh
  • src/lib/onboard/experimental/portable-host-preparation.test.ts
  • src/lib/onboard/experimental/portable-host-preparation.ts
  • test/e2e/live/portable-profile-rootless-linux.test.ts
  • test/install-onboard-yes.test.ts
  • test/install-portable-profile.test.ts

Comment thread scripts/install.sh
Comment thread test/install-portable-profile.test.ts
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: Review the warnings below.
Findings: 0 blockers · 1 warning · 0 suggestions

Model lanes

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

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

  • Podman-reported at scripts/install.sh:3460: selected only by the second-opinion lane as define.

Second-opinion terminology and E2E selections are advisory. They do not change the primary assessment or E2E / PR Gate.

2 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 scripts/install.sh:3443: Retain the established term for this existing hidden profile.
  • define — rootless Podman API socket at scripts/install.sh:3435: Retain the term; the adjacent comment and error context define its selected local-socket meaning.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: cloud-inference, cloud-onboard, managed-image-multiarch-startup, security-posture, onboard-repair, onboard-resume

1 optional E2E recommendation
  • bootstrap-install-smoke
1 warning · 0 suggestions

Warnings

Warnings do not block.

PRA-1 Warning — Cover retry after an owned registry replacement fails

  • Location: src/lib/onboard/experimental/portable-host-preparation.ts:105
  • Category: tests
  • Problem: The registry lifecycle removes an owned registry before it starts the replacement, but no test covers a failed start followed by a second preparation attempt.
  • Impact: A failed replacement leaves no managed registry. A later onboarding attempt can regress its recovery behavior without a test that verifies it recreates only the owned registry.
  • Recommendation: Add a focused preparePortableExperimentalHost test that simulates owned inspect, removal, failed docker run, then a second invocation with absent inspect and successful docker run.
  • Verification: Read portable-host-preparation.test.ts and confirm a test drives a labeled inspect result, a nonzero replacement run, then a second preparation that creates the labeled registry.
  • Test coverage: A unit test for preparePortableExperimentalHost that simulates an existing owned registry, failed replacement startup, and a successful retry with the expected inspect, remove, and run calls.
  • Evidence: src/lib/onboard/experimental/portable-host-preparation.ts:105-131 removes an owned registry and then starts a replacement. src/lib/onboard/experimental/portable-host-preparation.test.ts covers normal replacement, unmanaged ownership, inspection failure, and invalid socket paths, but not replacement startup failure followed by retry.

Workflow run details

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

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa

ericksoa commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Exact-head review note for f7a264477d95c2b622c5a9089a56cd1f65c282c9: the Nemotron second-opinion blocker is a false positive. prepare_portable_experimental_runtime_override already validates the Podman-reported socket before exporting DOCKER_HOST: unix:///* is accepted as-is, /* is converted to unix://..., and the default case rejects every other value (including tcp://127.0.0.1:1234) via error. The primary advisor reports zero blockers, both advisor checks pass, and all required checks are green.

@ericksoa
ericksoa merged commit 8227087 into main Aug 6, 2026
82 of 85 checks passed
@ericksoa
ericksoa deleted the fix/portable-podman-runtime-override-signed branch August 6, 2026 00:22
@github-actions github-actions Bot added the v0.0.104 Release target label Aug 6, 2026
ericksoa added a commit that referenced this pull request Aug 6, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 plain sentences: what changes and why. Describe
before-and-after behavior when it applies. Follow the NemoClaw Writing
Guide: https://github.com/NVIDIA/NemoClaw/blob/main/WRITING.md. Do not
add unrelated prose cleanup. -->

Portable onboarding selected the Podman driver but wrote the Docker-only
`supervisor_bin` field into `[openshell.drivers.podman]`. OpenShell
0.0.85 rejected that table before the gateway could start.

This change omits `supervisor_bin` for Podman and preserves the existing
Docker configuration. It follows the portable runtime override restored
by #8408.

## Changes
<!-- List concrete changes. If this adds an abstraction, configuration,
fallback, migration, or compatibility path, name its current requirement
and consumer, explain why a direct change is insufficient, and identify
the test that protects it. -->

- Omit `supervisor_bin` from the generated Podman driver table.
- Preserve `supervisor_bin` in the generated Docker driver table.
- Install pinned OpenShell 0.0.85 in the portable-profile E2E workflow.
- Start the real rootless Podman gateway and fail if OpenShell rejects
the generated configuration or exits.
- Trigger the portable-profile workflow when its gateway-proof or
pinned-runtime helpers change.

## 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
<!-- Check one tests line and one docs line. Check other lines when
applicable. Add every requested justification or approval reference. -->
- [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: The change repairs generated
configuration for an existing hidden experimental profile. No supported
public command, default, or workflow changed.
- [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: Aaron Erickson reviewed
the driver-schema boundary. The [exact-head rootless
runner](https://github.com/NVIDIA/NemoClaw/actions/runs/31062172724)
installs pinned OpenShell 0.0.85 and starts the real Podman gateway.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Documentation Writer Review
<!-- Required for code and documentation changes after the changes and
applicable validation are complete. Keep one review checkbox and one
instance of each visible or hidden field. For Evidence, list changed
documentation paths. For documentation-only changes, also state that the
writing rules and documentation style were reviewed. For other results,
explain why no documentation change is needed or why the review is
blocked. For Agent, use a consistent product and surface name, such as
Codex Desktop, Codex CLI, Claude Code, or Cursor. After committing all
review changes, put `git rev-parse --short HEAD` and `git rev-parse
--short HEAD:AGENTS.md` in the hidden metadata below. Rerun the review
and refresh that metadata after any new commit. This receipt is advisory
during the data-collection pilot. -->
- [x] Documentation writer subagent reviewed the completed changes
- Result: `no-docs-needed`
- Evidence: Omits a Docker-only field from the generated configuration
for an existing hidden experimental profile and adds pinned OpenShell
E2E evidence. No supported public command, default, or workflow changed.
- Agent: Codex Desktop
<!-- docs-review-head-sha: 9403b99 -->
<!-- docs-review-agents-blob-sha: 3dd7c24 -->

## DGX Station Hardware Evidence
<!-- Required only when scripts/prepare-dgx-station-host.sh changes.
Maintainers must review the linked evidence before approving or merging.
This is human-reviewed evidence, not authenticated hardware provenance.
Exceptional bypasses use existing repository governance and must be
documented on the PR. -->
- [ ] Tested on DGX Station
- Tested commit:
- Station profile/scenario:
- Result:
- Supporting evidence:

## Verification
<!-- Check each applicable item only when supported by the requested
evidence. Run targeted tests once per relevant change set and rerun
after later edits or hook autofixes that can affect the tested behavior.
Do not rerun hook-covered checks. -->
- [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 validate:pr` passed after refreshing `origin/main` when hooks
were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: [E2E
/ Portable
Profile](https://github.com/NVIDIA/NemoClaw/actions/runs/31062172724)
passed on `91daf0836`; `npm run typecheck` and `npm run
test:e2e-phases:check` passed locally.
- [x] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: [CI / Pull
Request](https://github.com/NVIDIA/NemoClaw/actions/runs/31062172715)
passed on `91daf0836`.
- [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)

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

---------

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v0.0.104 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant