Skip to content

feat: add non-interactive mode for CI/CD onboarding - #318

Merged
kjw3 merged 11 commits into
mainfrom
fix/issue-250-non-interactive
Mar 18, 2026
Merged

feat: add non-interactive mode for CI/CD onboarding#318
kjw3 merged 11 commits into
mainfrom
fix/issue-250-non-interactive

Conversation

@ericksoa

@ericksoa ericksoa commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

Closes #250.

Summary

  • Add --non-interactive flag and NEMOCLAW_NON_INTERACTIVE=1 env var to nemoclaw onboard and install.sh
  • All interactive prompts use environment variable overrides or sensible defaults when active
  • Fail-fast with clear errors when required values are missing (e.g. NVIDIA_API_KEY for cloud provider)

Environment variables

Variable Purpose Default
NEMOCLAW_NON_INTERACTIVE=1 Enable non-interactive mode off
NEMOCLAW_SANDBOX_NAME Sandbox name my-assistant
NEMOCLAW_PROVIDER Inference provider (cloud, ollama, vllm, nim) cloud
NEMOCLAW_MODEL Model override nvidia/nemotron-3-super-120b-a12b
NVIDIA_API_KEY API key (required for cloud/nim, not needed for ollama/vllm)

Usage

# Via install.sh
NEMOCLAW_NON_INTERACTIVE=1 NVIDIA_API_KEY=nvapi-... ./install.sh

# Via CLI
nemoclaw onboard --non-interactive

# With Ollama (no API key needed)
NEMOCLAW_NON_INTERACTIVE=1 NEMOCLAW_PROVIDER=ollama nemoclaw onboard --non-interactive

Test plan

  • Unit tests: 43/43 pass (no regressions)
  • Non-interactive cloud provider (default): no prompts, sandbox created, inference configured, policies applied
  • Non-interactive custom sandbox name via NEMOCLAW_SANDBOX_NAME
  • Non-interactive fail-fast: missing NVIDIA_API_KEY exits with clear error, no hang
  • Non-interactive with Ollama: NEMOCLAW_PROVIDER=ollama skips API key
  • Interactive mode unchanged: all prompts still appear when flags/env vars not set

Summary by CodeRabbit

  • New Features
    • Non-interactive onboarding via a CLI flag or environment variables for fully automated runs; deterministic provider/model and policy preset selection with validation and retries.
  • Installer
    • Improved platform/arch detection, colored messages, temporary workspace handling, and user-local install fallback when system install isn't writable.
  • Behavior Changes
    • Non-interactive runs abort on invalid configs or missing credentials and skip privileged removals in headless uninstall with a warning.
  • Tests
    • CLI test added to validate unknown onboard option handling.

Closes #250.

Adds --non-interactive flag and NEMOCLAW_NON_INTERACTIVE=1 env var
to nemoclaw onboard and install.sh. When active, all interactive
prompts use environment variable overrides or sensible defaults:

  NEMOCLAW_SANDBOX_NAME  — sandbox name (default: my-assistant)
  NEMOCLAW_PROVIDER      — inference provider: cloud, ollama, vllm, nim
  NEMOCLAW_MODEL         — model override
  NVIDIA_API_KEY         — required for cloud/nim, not needed for ollama/vllm

Non-interactive mode auto-recreates existing sandboxes and applies
suggested policy presets without prompting.

Usage:
  NEMOCLAW_NON_INTERACTIVE=1 NVIDIA_API_KEY=nvapi-... ./install.sh
  nemoclaw onboard --non-interactive
  ./install.sh --non-interactive
…mode

When only cloud was in the options list (no GPU, not experimental),
the options.length > 1 branch was skipped entirely, so the
NEMOCLAW_PROVIDER env var was never checked. Ollama/vLLM provider
selection now happens before the interactive options are built.

Copilot AI 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.

Pull request overview

This PR adds a non-interactive onboarding flow intended for CI/CD usage by introducing a --non-interactive flag and NEMOCLAW_NON_INTERACTIVE=1 environment variable, and wiring those through the installer and nemoclaw onboard command.

Changes:

  • Add --non-interactive support to install.sh and propagate NEMOCLAW_NON_INTERACTIVE.
  • Extend nemoclaw onboard CLI dispatch to pass a nonInteractive option into the onboarding library.
  • Update the onboarding wizard to avoid prompts in non-interactive mode by using env var overrides/defaults and fail-fast behavior.

Reviewed changes

Copilot reviewed 1 out of 3 changed files in this pull request and generated no comments.

File Description
install.sh Parses --non-interactive, sets NEMOCLAW_NON_INTERACTIVE, and calls nemoclaw onboard --non-interactive when enabled.
bin/nemoclaw.js Detects --non-interactive in args for onboard and forwards it into bin/lib/onboard.
bin/lib/onboard.js Adds non-interactive plumbing, prompt bypasses, provider/model selection via env vars, and API key fail-fast logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kjw3 kjw3 self-assigned this Mar 18, 2026
@kjw3

kjw3 commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

One issue I found is that the cgroups v2 check that we had removed yesterday from main had been reintroduced. I committed the removal in 71ef852

@wscurran wscurran added the enhancement New capability or improvement request label Mar 18, 2026
@wscurran wscurran added CI/CD and removed CI/CD labels Mar 18, 2026
@coderabbitai

coderabbitai Bot commented Mar 18, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds a non-interactive onboarding/install mode driven by --non-interactive or NEMOCLAW_NON_INTERACTIVE=1, with env-var-driven configuration, deterministic provider/model selection, validation and retry logic, CLI/installer wiring, OpenShell install/uninstall path adjustments, and updated onboarding call signatures.

Changes

Cohort / File(s) Summary
Core Onboarding Logic
bin/lib/onboard.js
Implements non-interactive mode (GLOBAL NON_INTERACTIVE, onboard(opts = {})), promptOrDefault, env-var driven prompts (sandbox, provider, model, policy presets), validation helpers (isSafeModelId, parsePolicyPresetEnv), polling (waitForSandboxReady), sleep, retry/apply logic for policy presets, and abort-on-invalid-config behavior.
CLI Entrypoint
bin/nemoclaw.js
Updates onboard(args) signature, validates/accepts --non-interactive, rejects unknown args with exit code 1, and forwards { nonInteractive } to onboard.
Installer Wrapper
install.sh
Parses --non-interactive / NEMOCLAW_NON_INTERACTIVE, exports it for subprocesses, and invokes nemoclaw onboard --non-interactive when set.
OpenShell Installer
scripts/install-openshell.sh
Reworks platform detection (OS_LABEL/ARCH_LABEL), adds colored logging helpers (info, warn, fail), temporary workspace cleanup, dynamic asset selection and download fallback, and user-local installation fallback when /usr/local/bin is not writable.
Uninstall Utility
uninstall.sh
Adds user-local OpenShell path to OPEN_SHELL_INSTALL_PATHS and changes remove_file_with_optional_sudo to skip privileged removal (with warning) in non-interactive or non-TTY contexts.
Tests
test/cli.test.js
Adds test asserting CLI exits with code 1 and prints an error for unknown onboard option.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Installer as install.sh
    participant CLI as nemoclaw.js
    participant Onboard as bin/lib/onboard.js
    participant Sandbox

    User->>Installer: ./install.sh --non-interactive
    Installer->>Installer: export NEMOCLAW_NON_INTERACTIVE=1
    Installer->>CLI: nemoclaw onboard --non-interactive
    CLI->>CLI: validate args, set opts.nonInteractive
    CLI->>Onboard: onboard({ nonInteractive: true })
    Onboard->>Onboard: read env vars (PROVIDER, MODEL, POLICY_PRESETS, ...)
    Onboard->>Onboard: validate provider/model/creds
    Onboard->>Sandbox: create or poll sandbox readiness
    Sandbox-->>Onboard: ready
    Onboard->>Onboard: apply policy presets (with retries)
    Onboard-->>CLI: return status
    CLI-->>Installer: exit status
    Installer-->>User: finish
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through scripts with nimble paws,

No prompts to ask, just env-var laws.
Flags set true, the pipeline sings,
Sandboxes ready, presets bring wings.
Hooray — installs that skip the pause! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add non-interactive mode for CI/CD onboarding' accurately and concisely describes the main change across all modified files.
Linked Issues check ✅ Passed Changes fully implement objectives from #250: non-interactive flag/env var support, env-var driven configuration, fail-fast errors for missing values, and preserved interactive behavior.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing non-interactive mode across onboarding and installation; no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/issue-250-non-interactive
📝 Coding Plan
  • Generate coding plan for human review comments

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

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@bin/lib/onboard.js`:
- Around line 305-315: The code is currently taking process.env.NEMOCLAW_MODEL
and passing it through (and into registry.updateSandbox and later run(...))
without validation; change this so any NEMOCLAW_MODEL is checked against the
allowed models list (the existing models array) and only accepted if it exactly
matches an entry; if it does not match, set model = models[0] (or another
explicit safe default), log a clear warning/error, and never write the raw env
value into registry.updateSandbox or interpolate it into run(...); apply this
validation/sanitization wherever model is set for non-interactive providers
(e.g., the providerKey === "vllm" branch, and the similar Ollama/cloud branches
mentioned) and ensure any use passed to run(...) is the validated model
variable.
- Around line 199-206: Currently in isNonInteractive() mode the code silently
proceeds to recreate the sandbox; change this to refuse to delete by default:
when isNonInteractive() is true, check a dedicated opt-in env var (e.g.
NEMOCLAW_RECREATE_SANDBOX) and only proceed with recreation if that var is set
to a truthy value; otherwise print a clear error mentioning sandboxName and
exit/non-zero (or return) without deleting. Update the logic around
isNonInteractive(), the prompt handling branch, and any console messages so
non-interactive runs fail fast unless NEMOCLAW_RECREATE_SANDBOX is explicitly
enabled.
- Around line 295-319: In the non-interactive branch that reads
process.env.NEMOCLAW_PROVIDER (see isNonInteractive, providerKey, ollamaRunning,
vllmRunning), add explicit validation so unknown values do not fall through to
"cloud": if providerKey is not one of the supported tokens (e.g., "ollama",
"vllm", "nim", "cloud") then log a clear error and process.exit(1); for
supported local providers ("ollama", "vllm", and any "nim" local variant) also
fail fast when the corresponding runtime check (ollamaRunning, vllmRunning, or
your nim availability check) is false by logging the specific failure and
exiting instead of falling through; continue to call
registry.updateSandbox(sandboxName, { model, provider, nimContainer }) only
after a validated provider and available runtime.

In `@bin/nemoclaw.js`:
- Around line 31-35: The onboard function currently only recognizes
"--non-interactive" and silently ignores typos; update onboard to validate args
and fail fast on unknown options by parsing args array, allowing only
"--non-interactive" (and no other tokens), and throwing or exiting with a clear
error when any unknown option is present; adjust the logic around the
nonInteractive variable and the call to runOnboard in async function onboard to
perform this validation before invoking require("./lib/onboard").

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: dc7b691b-eb96-4c23-8b09-f4b694b92747

📥 Commits

Reviewing files that changed from the base of the PR and between 1e23347 and e6fc933.

📒 Files selected for processing (5)
  • bin/lib/onboard.js
  • bin/nemoclaw.js
  • install.sh
  • scripts/install-openshell.sh
  • uninstall.sh

Comment thread bin/lib/onboard.js
Comment thread bin/lib/onboard.js
Comment thread bin/lib/onboard.js Outdated
Comment on lines +305 to +315
model = process.env.NEMOCLAW_MODEL || "nemotron-3-nano";
registry.updateSandbox(sandboxName, { model, provider, nimContainer });
return { model, provider };
} else if (providerKey === "vllm") {
if (!vllmRunning) {
console.error(" vLLM is not running on localhost:8000. Start it first.");
process.exit(1);
}
provider = "vllm-local";
model = process.env.NEMOCLAW_MODEL || "vllm-local";
registry.updateSandbox(sandboxName, { model, provider, nimContainer });

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.

⚠️ Potential issue | 🔴 Critical

Validate NEMOCLAW_MODEL instead of silently defaulting or passing it through.

The non-interactive paths treat bad model values inconsistently: local NIM quietly swaps to models[0], while cloud/Ollama/vLLM carry the raw env string into later shell commands. That both hides CI misconfiguration and creates a command-injection/broken-command risk once model is interpolated into run(...).

Suggested fix
+function assertSafeModelName(value) {
+  if (!/^[A-Za-z0-9._/:+-]+$/.test(value)) {
+    console.error(`  Invalid NEMOCLAW_MODEL: ${value}`);
+    process.exit(1);
+  }
+  return value;
+}
+
 ...
-      model = process.env.NEMOCLAW_MODEL || "nemotron-3-nano";
+      model = assertSafeModelName(process.env.NEMOCLAW_MODEL || "nemotron-3-nano");
 ...
-      model = process.env.NEMOCLAW_MODEL || "vllm-local";
+      model = assertSafeModelName(process.env.NEMOCLAW_MODEL || "vllm-local");
 ...
-          sel = envModel ? models.find((m) => m.name === envModel) || models[0] : models[0];
+          if (envModel) {
+            sel = models.find((m) => m.name === assertSafeModelName(envModel));
+            if (!sel) {
+              console.error(`  Unsupported NEMOCLAW_MODEL for local NIM: ${envModel}`);
+              process.exit(1);
+            }
+          } else {
+            sel = models[0];
+          }
 ...
-    model = model || process.env.NEMOCLAW_MODEL || "nvidia/nemotron-3-super-120b-a12b";
+    model = model || assertSafeModelName(process.env.NEMOCLAW_MODEL || "nvidia/nemotron-3-super-120b-a12b");

Also applies to: 369-371, 438-439

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/onboard.js` around lines 305 - 315, The code is currently taking
process.env.NEMOCLAW_MODEL and passing it through (and into
registry.updateSandbox and later run(...)) without validation; change this so
any NEMOCLAW_MODEL is checked against the allowed models list (the existing
models array) and only accepted if it exactly matches an entry; if it does not
match, set model = models[0] (or another explicit safe default), log a clear
warning/error, and never write the raw env value into registry.updateSandbox or
interpolate it into run(...); apply this validation/sanitization wherever model
is set for non-interactive providers (e.g., the providerKey === "vllm" branch,
and the similar Ollama/cloud branches mentioned) and ensure any use passed to
run(...) is the validated model variable.

Comment thread bin/nemoclaw.js

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

🧹 Nitpick comments (2)
bin/lib/onboard.js (2)

636-654: Dead code in retry logic.

The if (!appliedOk) block (lines 650-653) is unreachable: the loop either sets appliedOk = true and breaks, or throws on the final attempt. The check can never be false after normal loop completion.

Simplification
       for (let attempt = 0; attempt < 3; attempt += 1) {
         try {
           policies.applyPreset(sandboxName, name);
-          appliedOk = true;
           break;
         } catch (err) {
           const message = err && err.message ? err.message : String(err);
           if (!message.includes("sandbox not found") || attempt === 2) {
-            throw err;
+            console.error(`  Failed to apply policy preset '${name}' to sandbox '${sandboxName}'.`);
+            process.exit(1);
           }
           sleep(2);
         }
       }
-      if (!appliedOk) {
-        console.error(`  Failed to apply policy preset '${name}' to sandbox '${sandboxName}'.`);
-        process.exit(1);
-      }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/onboard.js` around lines 636 - 654, The retry loop around
policies.applyPreset(sandboxName, name) uses an appliedOk flag and a final if
(!appliedOk) block that is unreachable because the loop either breaks with
appliedOk=true or throws on the last attempt; remove the appliedOk variable and
the final if-block, and simplify to: attempt up to 3 times calling
policies.applyPreset(...) inside the try, on success break/return, on failure
inspect err.message and only rethrow on the last attempt, sleeping between
retries as already done (retain sleep(2)); update references to appliedOk
accordingly so no dead branch remains.

469-471: Minor indentation inconsistency.

Line 470 has 8-space indentation while the surrounding block uses 6 spaces.

Fix indentation
       run("OLLAMA_HOST=0.0.0.0:11434 ollama serve > /dev/null 2>&1 &", { ignoreError: true });
-        sleep(2);
+      sleep(2);
       console.log("  ✓ Using Ollama on localhost:11434");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/onboard.js` around lines 469 - 471, Indentation of the sleep call is
inconsistent with the surrounding block; change the indentation of the line
containing sleep(2); so it uses the same 6-space indentation level as the
adjacent run("OLLAMA_HOST=0.0.0.0:11434 ollama serve > /dev/null 2>&1 &", {
ignoreError: true }); and console.log("  ✓ Using Ollama on localhost:11434");
lines (i.e., align sleep(2); with those statements) to fix the minor formatting
issue.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@bin/lib/onboard.js`:
- Around line 636-654: The retry loop around policies.applyPreset(sandboxName,
name) uses an appliedOk flag and a final if (!appliedOk) block that is
unreachable because the loop either breaks with appliedOk=true or throws on the
last attempt; remove the appliedOk variable and the final if-block, and simplify
to: attempt up to 3 times calling policies.applyPreset(...) inside the try, on
success break/return, on failure inspect err.message and only rethrow on the
last attempt, sleeping between retries as already done (retain sleep(2)); update
references to appliedOk accordingly so no dead branch remains.
- Around line 469-471: Indentation of the sleep call is inconsistent with the
surrounding block; change the indentation of the line containing sleep(2); so it
uses the same 6-space indentation level as the adjacent
run("OLLAMA_HOST=0.0.0.0:11434 ollama serve > /dev/null 2>&1 &", { ignoreError:
true }); and console.log("  ✓ Using Ollama on localhost:11434"); lines (i.e.,
align sleep(2); with those statements) to fix the minor formatting issue.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f5fdd5b2-dada-4be1-ae75-cb570ac7b35a

📥 Commits

Reviewing files that changed from the base of the PR and between e6fc933 and e832c03.

📒 Files selected for processing (3)
  • bin/lib/onboard.js
  • bin/nemoclaw.js
  • test/cli.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • bin/nemoclaw.js

@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

🧹 Nitpick comments (1)
bin/lib/onboard.js (1)

650-668: Align interactive policy application with the non-interactive safety checks.

The interactive path applies presets without the readiness wait/retry and preset validation used above, so behavior is less reliable and less consistent for the same operation.

Refactor direction
-    if (answer.toLowerCase() === "list") {
+    if (answer.toLowerCase() === "list") {
       // Let user pick
       const picks = await prompt("  Enter preset names (comma-separated): ");
       const selected = picks.split(",").map((s) => s.trim()).filter(Boolean);
-      for (const name of selected) {
-        policies.applyPreset(sandboxName, name);
-      }
+      const knownPresets = new Set(allPresets.map((p) => p.name));
+      const invalid = selected.filter((name) => !knownPresets.has(name));
+      if (invalid.length > 0) {
+        console.error(`  Unknown policy preset(s): ${invalid.join(", ")}`);
+        process.exit(1);
+      }
+      if (!waitForSandboxReady(sandboxName)) {
+        console.error(`  Sandbox '${sandboxName}' was not ready for policy application.`);
+        process.exit(1);
+      }
+      for (const name of selected) {
+        policies.applyPreset(sandboxName, name);
+      }
     } else {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/onboard.js` around lines 650 - 668, The interactive branch calls
policies.applyPreset(sandboxName, name) directly for both "list" and default
suggested flows, skipping the readiness wait/retry and preset validation used
earlier; update the interactive flow to reuse the same validated-and-retried
apply logic (the helper used above for non-interactive safety checks) so each
selected preset goes through the same readiness wait/retry and validation steps
before calling policies.applyPreset; reference prompt, suggestions, sandboxName,
and policies.applyPreset and ensure you validate preset names and apply the same
retry/backoff logic for each selected name as in the non-interactive path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@bin/lib/onboard.js`:
- Around line 67-70: The PATH guard in installOpenshell() is unsafe because
process.env.PATH may be undefined; update the check that uses
process.env.PATH.split(...) to first coerce or default PATH (e.g., use
(process.env.PATH || "") or a typeof check) before calling split so it won't
throw in minimal CI shells; change the condition around localBin and
process.env.PATH to safely handle a missing PATH while preserving the existing
behavior (refer to localBin and the code that currently does
process.env.PATH.split(path.delimiter).includes(localBin)).

---

Nitpick comments:
In `@bin/lib/onboard.js`:
- Around line 650-668: The interactive branch calls
policies.applyPreset(sandboxName, name) directly for both "list" and default
suggested flows, skipping the readiness wait/retry and preset validation used
earlier; update the interactive flow to reuse the same validated-and-retried
apply logic (the helper used above for non-interactive safety checks) so each
selected preset goes through the same readiness wait/retry and validation steps
before calling policies.applyPreset; reference prompt, suggestions, sandboxName,
and policies.applyPreset and ensure you validate preset names and apply the same
retry/backoff logic for each selected name as in the non-interactive path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f1bb2af4-5605-4410-893c-eb2a8cc3d5bd

📥 Commits

Reviewing files that changed from the base of the PR and between e832c03 and b51ea34.

📒 Files selected for processing (1)
  • bin/lib/onboard.js

Comment thread bin/lib/onboard.js
Comment on lines +67 to +70
const localBin = process.env.XDG_BIN_HOME || path.join(process.env.HOME || "", ".local", "bin");
if (fs.existsSync(path.join(localBin, "openshell")) && !process.env.PATH.split(path.delimiter).includes(localBin)) {
process.env.PATH = `${localBin}${path.delimiter}${process.env.PATH}`;
}

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.

⚠️ Potential issue | 🟠 Major

Guard PATH handling before splitting it in installOpenshell().

At Line 68, process.env.PATH.split(...) can throw if PATH is undefined (common in minimal CI shells), which would crash onboarding right after install.

Suggested fix
   const localBin = process.env.XDG_BIN_HOME || path.join(process.env.HOME || "", ".local", "bin");
-  if (fs.existsSync(path.join(localBin, "openshell")) && !process.env.PATH.split(path.delimiter).includes(localBin)) {
-    process.env.PATH = `${localBin}${path.delimiter}${process.env.PATH}`;
+  const currentPath = process.env.PATH || "";
+  if (fs.existsSync(path.join(localBin, "openshell")) && !currentPath.split(path.delimiter).includes(localBin)) {
+    process.env.PATH = currentPath ? `${localBin}${path.delimiter}${currentPath}` : localBin;
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/onboard.js` around lines 67 - 70, The PATH guard in
installOpenshell() is unsafe because process.env.PATH may be undefined; update
the check that uses process.env.PATH.split(...) to first coerce or default PATH
(e.g., use (process.env.PATH || "") or a typeof check) before calling split so
it won't throw in minimal CI shells; change the condition around localBin and
process.env.PATH to safely handle a missing PATH while preserving the existing
behavior (refer to localBin and the code that currently does
process.env.PATH.split(path.delimiter).includes(localBin)).

@kjw3
kjw3 merged commit 054b921 into main Mar 18, 2026
3 checks passed
rwipfelnv added a commit to rwipfelnv/NemoClaw that referenced this pull request Mar 19, 2026
OpenShell's nested k3s cluster cannot resolve Kubernetes DNS names,
so inference requests fail with 502 Bad Gateway. This adds:

- socat TCP proxy setup in setup.sh to forward localhost:8000 to the
  K8s vLLM service endpoint
- Provider configuration using host.openshell.internal:8000 which
  resolves to the workspace container from inside k3s
- Documentation explaining the network architecture and workaround
- Updated env var names to match PR NVIDIA#318 (NEMOCLAW_NON_INTERACTIVE)
- cgroup v2 compatibility fix for Docker daemon
- Removed memory limits that caused OOM

Tested: Inference requests from sandboxes now route correctly through
the socat proxy to the Dynamo vLLM endpoint.

Depends on: NVIDIA#318 (non-interactive mode), NVIDIA#365 (Dynamo provider)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Ryuketsukami pushed a commit to Ryuketsukami/NemoClaw that referenced this pull request Mar 24, 2026
* feat: add non-interactive mode for CI/CD onboarding

Closes NVIDIA#250.

Adds --non-interactive flag and NEMOCLAW_NON_INTERACTIVE=1 env var
to nemoclaw onboard and install.sh. When active, all interactive
prompts use environment variable overrides or sensible defaults:

  NEMOCLAW_SANDBOX_NAME  — sandbox name (default: my-assistant)
  NEMOCLAW_PROVIDER      — inference provider: cloud, ollama, vllm, nim
  NEMOCLAW_MODEL         — model override
  NVIDIA_API_KEY         — required for cloud/nim, not needed for ollama/vllm

Non-interactive mode auto-recreates existing sandboxes and applies
suggested policy presets without prompting.

Usage:
  NEMOCLAW_NON_INTERACTIVE=1 NVIDIA_API_KEY=nvapi-... ./install.sh
  nemoclaw onboard --non-interactive
  ./install.sh --non-interactive

* fix: handle NEMOCLAW_PROVIDER before options list in non-interactive mode

When only cloud was in the options list (no GPU, not experimental),
the options.length > 1 branch was skipped entirely, so the
NEMOCLAW_PROVIDER env var was never checked. Ollama/vLLM provider
selection now happens before the interactive options are built.

* remove stale cgroup preflight regression

* fix non-interactive onboarding regressions

* add standalone openshell installer script

* add env-controlled non-interactive policy selection

* avoid sudo prompt for non-interactive openshell install

* avoid sudo prompt during non-interactive uninstall

* harden non-interactive onboard validation

* simplify policy retry loop

---------

Co-authored-by: Kevin Jones <kejones@nvidia.com>
jessesanford pushed a commit to jessesanford/NemoClaw that referenced this pull request Mar 24, 2026
* feat: add non-interactive mode for CI/CD onboarding

Closes NVIDIA#250.

Adds --non-interactive flag and NEMOCLAW_NON_INTERACTIVE=1 env var
to nemoclaw onboard and install.sh. When active, all interactive
prompts use environment variable overrides or sensible defaults:

  NEMOCLAW_SANDBOX_NAME  — sandbox name (default: my-assistant)
  NEMOCLAW_PROVIDER      — inference provider: cloud, ollama, vllm, nim
  NEMOCLAW_MODEL         — model override
  NVIDIA_API_KEY         — required for cloud/nim, not needed for ollama/vllm

Non-interactive mode auto-recreates existing sandboxes and applies
suggested policy presets without prompting.

Usage:
  NEMOCLAW_NON_INTERACTIVE=1 NVIDIA_API_KEY=nvapi-... ./install.sh
  nemoclaw onboard --non-interactive
  ./install.sh --non-interactive

* fix: handle NEMOCLAW_PROVIDER before options list in non-interactive mode

When only cloud was in the options list (no GPU, not experimental),
the options.length > 1 branch was skipped entirely, so the
NEMOCLAW_PROVIDER env var was never checked. Ollama/vLLM provider
selection now happens before the interactive options are built.

* remove stale cgroup preflight regression

* fix non-interactive onboarding regressions

* add standalone openshell installer script

* add env-controlled non-interactive policy selection

* avoid sudo prompt for non-interactive openshell install

* avoid sudo prompt during non-interactive uninstall

* harden non-interactive onboard validation

* simplify policy retry loop

---------

Co-authored-by: Kevin Jones <kejones@nvidia.com>
mafueee pushed a commit to mafueee/NemoClaw that referenced this pull request Mar 28, 2026
kjw3 added a commit that referenced this pull request Mar 30, 2026
* feat: add Kubernetes testing infrastructure

Add k8s-testing/ directory with scripts and manifests for testing NemoClaw
on Kubernetes with Dynamo vLLM inference.

Includes:
- test-installer.sh: Public installer test (requires unattended install support)
- setup.sh: Manual setup from source for development
- Pod manifests for Docker-in-Docker execution

Architecture: OpenShell runs k3s inside Docker, so we use DinD pods
to provide the Docker daemon on Kubernetes.

Signed-off-by: rwipfelnv

* fix: add socat proxy for K8s DNS isolation workaround

OpenShell's nested k3s cluster cannot resolve Kubernetes DNS names,
so inference requests fail with 502 Bad Gateway. This adds:

- socat TCP proxy setup in setup.sh to forward localhost:8000 to the
  K8s vLLM service endpoint
- Provider configuration using host.openshell.internal:8000 which
  resolves to the workspace container from inside k3s
- Documentation explaining the network architecture and workaround
- Updated env var names to match PR #318 (NEMOCLAW_NON_INTERACTIVE)
- cgroup v2 compatibility fix for Docker daemon
- Removed memory limits that caused OOM

Tested: Inference requests from sandboxes now route correctly through
the socat proxy to the Dynamo vLLM endpoint.

Depends on: #318 (non-interactive mode), #365 (Dynamo provider)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: NemoKlaw - NemoClaw on Kubernetes with Dynamo support

Complete K8s deployment solution for NemoClaw:
- nemoklaw.yaml: Pod manifest with DinD, init containers, hostPath storage
- install.sh: Interactive installer with preflight checks
- Rename k8s-testing -> k8s, move old files to dev/

Key learnings:
- hostPath storage (/mnt/k8s-disks) avoids ephemeral storage eviction
- Init containers for docker config, openshell CLI, NemoClaw build
- Workspace container installs apt packages at runtime (can't share via volumes)
- socat proxy bridges K8s DNS to nested k3s (host.openshell.internal)

Tested successfully with Dynamo vLLM backend on EKS.

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* fix: rename NemoKlaw to NemoClaw and document known limitations

Address PR feedback:
- Rename NemoKlaw -> NemoClaw (avoid confusing naming)
- Rename nemoklaw.yaml -> nemoclaw-k8s.yaml
- Fix hardcoded endpoint to use generic example
- Remove log file from repo
- Document known limitations (HTTPS proxy issue)
- Update README with accurate status of what works/doesn't work

Signed-off-by: rwipfelnv
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: update DYNAMO_HOST to vllm-agg-frontend

The aggregated frontend service is the correct endpoint for
Dynamo vLLM inference.

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* docs: add Using NemoClaw section with CLI commands

- Add workspace shell access command
- Add sandbox status/logs/list commands
- Add chat completion test example
- Rename section from "What Can You Do?" to "Using NemoClaw"

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* refactor(k8s): simplify deployment to use official installer

- Use official NemoClaw installer (`curl | bash`) instead of git clone/build
- Switch to `custom` provider from PR #648 (supersedes dynamo-specific provider)
- Remove k8s/dev/ directory (no longer needed for testing)
- Use emptyDir volumes for portability across clusters
- Add /etc/hosts workaround for endpoint validation during onboarding
- Update README with verification steps for local inference

Tested end-to-end with Dynamo vLLM backend.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(k8s): resolve lint errors in yaml and markdown

- Remove multi-document YAML (move namespace creation to README)
- Add language specifier to fenced code block (```text)
- Add blank lines before lists per markdownlint rules

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* docs(k8s): add experimental warning and clarify requirements

- Add explicit experimental warning at top of README
- Clarify this is for trying NemoClaw on k8s, not production
- Document privileged pod and DinD requirements upfront
- Add resource requirements to prerequisites

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

---------

Signed-off-by: rwipfelnv
Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: KJ <kejones@nvidia.com>
realkim93 pushed a commit to realkim93/NemoClaw that referenced this pull request Mar 30, 2026
* feat: add Kubernetes testing infrastructure

Add k8s-testing/ directory with scripts and manifests for testing NemoClaw
on Kubernetes with Dynamo vLLM inference.

Includes:
- test-installer.sh: Public installer test (requires unattended install support)
- setup.sh: Manual setup from source for development
- Pod manifests for Docker-in-Docker execution

Architecture: OpenShell runs k3s inside Docker, so we use DinD pods
to provide the Docker daemon on Kubernetes.

Signed-off-by: rwipfelnv

* fix: add socat proxy for K8s DNS isolation workaround

OpenShell's nested k3s cluster cannot resolve Kubernetes DNS names,
so inference requests fail with 502 Bad Gateway. This adds:

- socat TCP proxy setup in setup.sh to forward localhost:8000 to the
  K8s vLLM service endpoint
- Provider configuration using host.openshell.internal:8000 which
  resolves to the workspace container from inside k3s
- Documentation explaining the network architecture and workaround
- Updated env var names to match PR NVIDIA#318 (NEMOCLAW_NON_INTERACTIVE)
- cgroup v2 compatibility fix for Docker daemon
- Removed memory limits that caused OOM

Tested: Inference requests from sandboxes now route correctly through
the socat proxy to the Dynamo vLLM endpoint.

Depends on: NVIDIA#318 (non-interactive mode), NVIDIA#365 (Dynamo provider)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: NemoKlaw - NemoClaw on Kubernetes with Dynamo support

Complete K8s deployment solution for NemoClaw:
- nemoklaw.yaml: Pod manifest with DinD, init containers, hostPath storage
- install.sh: Interactive installer with preflight checks
- Rename k8s-testing -> k8s, move old files to dev/

Key learnings:
- hostPath storage (/mnt/k8s-disks) avoids ephemeral storage eviction
- Init containers for docker config, openshell CLI, NemoClaw build
- Workspace container installs apt packages at runtime (can't share via volumes)
- socat proxy bridges K8s DNS to nested k3s (host.openshell.internal)

Tested successfully with Dynamo vLLM backend on EKS.

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* fix: rename NemoKlaw to NemoClaw and document known limitations

Address PR feedback:
- Rename NemoKlaw -> NemoClaw (avoid confusing naming)
- Rename nemoklaw.yaml -> nemoclaw-k8s.yaml
- Fix hardcoded endpoint to use generic example
- Remove log file from repo
- Document known limitations (HTTPS proxy issue)
- Update README with accurate status of what works/doesn't work

Signed-off-by: rwipfelnv
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: update DYNAMO_HOST to vllm-agg-frontend

The aggregated frontend service is the correct endpoint for
Dynamo vLLM inference.

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* docs: add Using NemoClaw section with CLI commands

- Add workspace shell access command
- Add sandbox status/logs/list commands
- Add chat completion test example
- Rename section from "What Can You Do?" to "Using NemoClaw"

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* refactor(k8s): simplify deployment to use official installer

- Use official NemoClaw installer (`curl | bash`) instead of git clone/build
- Switch to `custom` provider from PR NVIDIA#648 (supersedes dynamo-specific provider)
- Remove k8s/dev/ directory (no longer needed for testing)
- Use emptyDir volumes for portability across clusters
- Add /etc/hosts workaround for endpoint validation during onboarding
- Update README with verification steps for local inference

Tested end-to-end with Dynamo vLLM backend.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(k8s): resolve lint errors in yaml and markdown

- Remove multi-document YAML (move namespace creation to README)
- Add language specifier to fenced code block (```text)
- Add blank lines before lists per markdownlint rules

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* docs(k8s): add experimental warning and clarify requirements

- Add explicit experimental warning at top of README
- Clarify this is for trying NemoClaw on k8s, not production
- Document privileged pod and DinD requirements upfront
- Add resource requirements to prerequisites

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

---------

Signed-off-by: rwipfelnv
Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: KJ <kejones@nvidia.com>
laitingsheng pushed a commit that referenced this pull request Apr 2, 2026
* feat: add Kubernetes testing infrastructure

Add k8s-testing/ directory with scripts and manifests for testing NemoClaw
on Kubernetes with Dynamo vLLM inference.

Includes:
- test-installer.sh: Public installer test (requires unattended install support)
- setup.sh: Manual setup from source for development
- Pod manifests for Docker-in-Docker execution

Architecture: OpenShell runs k3s inside Docker, so we use DinD pods
to provide the Docker daemon on Kubernetes.

Signed-off-by: rwipfelnv

* fix: add socat proxy for K8s DNS isolation workaround

OpenShell's nested k3s cluster cannot resolve Kubernetes DNS names,
so inference requests fail with 502 Bad Gateway. This adds:

- socat TCP proxy setup in setup.sh to forward localhost:8000 to the
  K8s vLLM service endpoint
- Provider configuration using host.openshell.internal:8000 which
  resolves to the workspace container from inside k3s
- Documentation explaining the network architecture and workaround
- Updated env var names to match PR #318 (NEMOCLAW_NON_INTERACTIVE)
- cgroup v2 compatibility fix for Docker daemon
- Removed memory limits that caused OOM

Tested: Inference requests from sandboxes now route correctly through
the socat proxy to the Dynamo vLLM endpoint.

Depends on: #318 (non-interactive mode), #365 (Dynamo provider)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: NemoKlaw - NemoClaw on Kubernetes with Dynamo support

Complete K8s deployment solution for NemoClaw:
- nemoklaw.yaml: Pod manifest with DinD, init containers, hostPath storage
- install.sh: Interactive installer with preflight checks
- Rename k8s-testing -> k8s, move old files to dev/

Key learnings:
- hostPath storage (/mnt/k8s-disks) avoids ephemeral storage eviction
- Init containers for docker config, openshell CLI, NemoClaw build
- Workspace container installs apt packages at runtime (can't share via volumes)
- socat proxy bridges K8s DNS to nested k3s (host.openshell.internal)

Tested successfully with Dynamo vLLM backend on EKS.

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* fix: rename NemoKlaw to NemoClaw and document known limitations

Address PR feedback:
- Rename NemoKlaw -> NemoClaw (avoid confusing naming)
- Rename nemoklaw.yaml -> nemoclaw-k8s.yaml
- Fix hardcoded endpoint to use generic example
- Remove log file from repo
- Document known limitations (HTTPS proxy issue)
- Update README with accurate status of what works/doesn't work

Signed-off-by: rwipfelnv
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: update DYNAMO_HOST to vllm-agg-frontend

The aggregated frontend service is the correct endpoint for
Dynamo vLLM inference.

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* docs: add Using NemoClaw section with CLI commands

- Add workspace shell access command
- Add sandbox status/logs/list commands
- Add chat completion test example
- Rename section from "What Can You Do?" to "Using NemoClaw"

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* refactor(k8s): simplify deployment to use official installer

- Use official NemoClaw installer (`curl | bash`) instead of git clone/build
- Switch to `custom` provider from PR #648 (supersedes dynamo-specific provider)
- Remove k8s/dev/ directory (no longer needed for testing)
- Use emptyDir volumes for portability across clusters
- Add /etc/hosts workaround for endpoint validation during onboarding
- Update README with verification steps for local inference

Tested end-to-end with Dynamo vLLM backend.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(k8s): resolve lint errors in yaml and markdown

- Remove multi-document YAML (move namespace creation to README)
- Add language specifier to fenced code block (```text)
- Add blank lines before lists per markdownlint rules

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* docs(k8s): add experimental warning and clarify requirements

- Add explicit experimental warning at top of README
- Clarify this is for trying NemoClaw on k8s, not production
- Document privileged pod and DinD requirements upfront
- Add resource requirements to prerequisites

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

---------

Signed-off-by: rwipfelnv
Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: KJ <kejones@nvidia.com>
lakamsani pushed a commit to lakamsani/NemoClaw that referenced this pull request Apr 4, 2026
* feat: add Kubernetes testing infrastructure

Add k8s-testing/ directory with scripts and manifests for testing NemoClaw
on Kubernetes with Dynamo vLLM inference.

Includes:
- test-installer.sh: Public installer test (requires unattended install support)
- setup.sh: Manual setup from source for development
- Pod manifests for Docker-in-Docker execution

Architecture: OpenShell runs k3s inside Docker, so we use DinD pods
to provide the Docker daemon on Kubernetes.

Signed-off-by: rwipfelnv

* fix: add socat proxy for K8s DNS isolation workaround

OpenShell's nested k3s cluster cannot resolve Kubernetes DNS names,
so inference requests fail with 502 Bad Gateway. This adds:

- socat TCP proxy setup in setup.sh to forward localhost:8000 to the
  K8s vLLM service endpoint
- Provider configuration using host.openshell.internal:8000 which
  resolves to the workspace container from inside k3s
- Documentation explaining the network architecture and workaround
- Updated env var names to match PR NVIDIA#318 (NEMOCLAW_NON_INTERACTIVE)
- cgroup v2 compatibility fix for Docker daemon
- Removed memory limits that caused OOM

Tested: Inference requests from sandboxes now route correctly through
the socat proxy to the Dynamo vLLM endpoint.

Depends on: NVIDIA#318 (non-interactive mode), NVIDIA#365 (Dynamo provider)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: NemoKlaw - NemoClaw on Kubernetes with Dynamo support

Complete K8s deployment solution for NemoClaw:
- nemoklaw.yaml: Pod manifest with DinD, init containers, hostPath storage
- install.sh: Interactive installer with preflight checks
- Rename k8s-testing -> k8s, move old files to dev/

Key learnings:
- hostPath storage (/mnt/k8s-disks) avoids ephemeral storage eviction
- Init containers for docker config, openshell CLI, NemoClaw build
- Workspace container installs apt packages at runtime (can't share via volumes)
- socat proxy bridges K8s DNS to nested k3s (host.openshell.internal)

Tested successfully with Dynamo vLLM backend on EKS.

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* fix: rename NemoKlaw to NemoClaw and document known limitations

Address PR feedback:
- Rename NemoKlaw -> NemoClaw (avoid confusing naming)
- Rename nemoklaw.yaml -> nemoclaw-k8s.yaml
- Fix hardcoded endpoint to use generic example
- Remove log file from repo
- Document known limitations (HTTPS proxy issue)
- Update README with accurate status of what works/doesn't work

Signed-off-by: rwipfelnv
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: update DYNAMO_HOST to vllm-agg-frontend

The aggregated frontend service is the correct endpoint for
Dynamo vLLM inference.

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* docs: add Using NemoClaw section with CLI commands

- Add workspace shell access command
- Add sandbox status/logs/list commands
- Add chat completion test example
- Rename section from "What Can You Do?" to "Using NemoClaw"

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* refactor(k8s): simplify deployment to use official installer

- Use official NemoClaw installer (`curl | bash`) instead of git clone/build
- Switch to `custom` provider from PR NVIDIA#648 (supersedes dynamo-specific provider)
- Remove k8s/dev/ directory (no longer needed for testing)
- Use emptyDir volumes for portability across clusters
- Add /etc/hosts workaround for endpoint validation during onboarding
- Update README with verification steps for local inference

Tested end-to-end with Dynamo vLLM backend.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(k8s): resolve lint errors in yaml and markdown

- Remove multi-document YAML (move namespace creation to README)
- Add language specifier to fenced code block (```text)
- Add blank lines before lists per markdownlint rules

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* docs(k8s): add experimental warning and clarify requirements

- Add explicit experimental warning at top of README
- Clarify this is for trying NemoClaw on k8s, not production
- Document privileged pod and DinD requirements upfront
- Add resource requirements to prerequisites

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

---------

Signed-off-by: rwipfelnv
Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: KJ <kejones@nvidia.com>
gemini2026 pushed a commit to gemini2026/NemoClaw that referenced this pull request Apr 14, 2026
* feat: add Kubernetes testing infrastructure

Add k8s-testing/ directory with scripts and manifests for testing NemoClaw
on Kubernetes with Dynamo vLLM inference.

Includes:
- test-installer.sh: Public installer test (requires unattended install support)
- setup.sh: Manual setup from source for development
- Pod manifests for Docker-in-Docker execution

Architecture: OpenShell runs k3s inside Docker, so we use DinD pods
to provide the Docker daemon on Kubernetes.

Signed-off-by: rwipfelnv

* fix: add socat proxy for K8s DNS isolation workaround

OpenShell's nested k3s cluster cannot resolve Kubernetes DNS names,
so inference requests fail with 502 Bad Gateway. This adds:

- socat TCP proxy setup in setup.sh to forward localhost:8000 to the
  K8s vLLM service endpoint
- Provider configuration using host.openshell.internal:8000 which
  resolves to the workspace container from inside k3s
- Documentation explaining the network architecture and workaround
- Updated env var names to match PR NVIDIA#318 (NEMOCLAW_NON_INTERACTIVE)
- cgroup v2 compatibility fix for Docker daemon
- Removed memory limits that caused OOM

Tested: Inference requests from sandboxes now route correctly through
the socat proxy to the Dynamo vLLM endpoint.

Depends on: NVIDIA#318 (non-interactive mode), NVIDIA#365 (Dynamo provider)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: NemoKlaw - NemoClaw on Kubernetes with Dynamo support

Complete K8s deployment solution for NemoClaw:
- nemoklaw.yaml: Pod manifest with DinD, init containers, hostPath storage
- install.sh: Interactive installer with preflight checks
- Rename k8s-testing -> k8s, move old files to dev/

Key learnings:
- hostPath storage (/mnt/k8s-disks) avoids ephemeral storage eviction
- Init containers for docker config, openshell CLI, NemoClaw build
- Workspace container installs apt packages at runtime (can't share via volumes)
- socat proxy bridges K8s DNS to nested k3s (host.openshell.internal)

Tested successfully with Dynamo vLLM backend on EKS.

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* fix: rename NemoKlaw to NemoClaw and document known limitations

Address PR feedback:
- Rename NemoKlaw -> NemoClaw (avoid confusing naming)
- Rename nemoklaw.yaml -> nemoclaw-k8s.yaml
- Fix hardcoded endpoint to use generic example
- Remove log file from repo
- Document known limitations (HTTPS proxy issue)
- Update README with accurate status of what works/doesn't work

Signed-off-by: rwipfelnv
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: update DYNAMO_HOST to vllm-agg-frontend

The aggregated frontend service is the correct endpoint for
Dynamo vLLM inference.

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* docs: add Using NemoClaw section with CLI commands

- Add workspace shell access command
- Add sandbox status/logs/list commands
- Add chat completion test example
- Rename section from "What Can You Do?" to "Using NemoClaw"

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>

* refactor(k8s): simplify deployment to use official installer

- Use official NemoClaw installer (`curl | bash`) instead of git clone/build
- Switch to `custom` provider from PR NVIDIA#648 (supersedes dynamo-specific provider)
- Remove k8s/dev/ directory (no longer needed for testing)
- Use emptyDir volumes for portability across clusters
- Add /etc/hosts workaround for endpoint validation during onboarding
- Update README with verification steps for local inference

Tested end-to-end with Dynamo vLLM backend.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(k8s): resolve lint errors in yaml and markdown

- Remove multi-document YAML (move namespace creation to README)
- Add language specifier to fenced code block (```text)
- Add blank lines before lists per markdownlint rules

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* docs(k8s): add experimental warning and clarify requirements

- Add explicit experimental warning at top of README
- Clarify this is for trying NemoClaw on k8s, not production
- Document privileged pod and DinD requirements upfront
- Add resource requirements to prerequisites

Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

---------

Signed-off-by: rwipfelnv
Signed-off-by: Robert Wipfel <rwipfel@nvidia.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: KJ <kejones@nvidia.com>
@wscurran wscurran added area: ci CI workflows, checks, release automation, or GitHub Actions area: install Install, setup, prerequisites, or uninstall flow area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow chore Build, CI, dependency, or tooling maintenance feature PR adds or expands user-visible functionality and removed Getting Started enhancement New capability or improvement request chore Build, CI, dependency, or tooling maintenance labels Jun 3, 2026
@cv
cv deleted the fix/issue-250-non-interactive branch June 28, 2026 00:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ci CI workflows, checks, release automation, or GitHub Actions area: install Install, setup, prerequisites, or uninstall flow area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow feature PR adds or expands user-visible functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal: Non-Interactive Installation Mode

4 participants