fix(share): clear error when local mount path is read-only (#3192)#3646
Conversation
Closes NVIDIA#3192. `nemoclaw <sandbox> share mount` calls `fs.mkdirSync(localMount, { recursive: true })` unconditionally before invoking `sshfs`. When the default `~/.nemoclaw/mounts/<sandbox>` parent lives on a read-only filesystem (immutable home, restricted VM, etc.) the call throws `EROFS` from inside the bare mkdir and the user sees a raw Node stack trace with no actionable guidance. Add a `checkLocalMountWritable()` helper that probes the target directory for both `mkdirSync` and `accessSync(W_OK)` failures and returns a structured `{ writable, reason }` result. `runShareMount` calls it after the SSH config has been staged and exits with a clear three-line message ("Local mount path is not usable", explanation, and a "Pick a writable directory" command suggestion) when the target is unwritable, cleaning up the staged SSH config first. Docs: add a one-sentence prerequisite to `docs/reference/commands.md` and the mirrored skill reference pointing users to pass an explicit writable path as the second positional argument when the default lives on a read-only filesystem. Tests: `test/share-command-writable.test.ts` covers the 6 paths: success, EROFS-on-mkdir, EACCES-on-mkdir, unknown-error-on-mkdir, EROFS-on-access (pre-existing dir on read-only fs), and EACCES-on-access. 6/6 pass; existing 9/9 share-command.test.ts pass unchanged. Signed-off-by: latenighthackathon <support@latenighthackathon.com> Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughAdds a preflight check to verify the local mount path is writable before performing SSHFS mounts via ChangesWritable Mount Validation
🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Comment |
## Summary Updates the NemoClaw documentation for the v0.0.45 release by summarizing the user-facing changes merged since v0.0.44 and bumping the docs version metadata. Refreshes generated user skills so agent-facing references match the source docs. ## Changes - Added v0.0.45 release notes covering onboarding recovery, local inference, channel cleanup, share mount diagnostics, uninstall cleanup, and security redaction updates. - Updated command and troubleshooting docs for sandbox name limits, GPU gateway reuse, DNS preflight behavior, channel removal cleanup, and share mount path validation. - Bumped docs version metadata to 0.0.45 and regenerated NemoClaw user skills from the docs. - Source summary: #3672 -> `docs/reference/commands.md`: documented channel removal detaching bridge providers and un-applying channel policy presets. - Source summary: #3678 -> `docs/about/release-notes.md`: documented Ollama streamed usage accounting in the release notes. - Source summary: #3670 -> `docs/reference/commands.md`, `docs/reference/troubleshooting.md`: documented safe GPU gateway replacement behavior. - Source summary: #3664 -> `docs/about/release-notes.md`: documented blueprint permission normalization in the release notes. - Source summary: #3181 -> `docs/reference/troubleshooting.md`: documented GPU toolkit guidance when host drivers work but passthrough is disabled. - Source summary: #3554 -> `docs/about/release-notes.md`: documented host `openshell-gateway` cleanup during uninstall. - Source summary: #3651 -> `docs/reference/troubleshooting.md`: documented the uncached `.invalid` DNS preflight probe. - Source summary: #3643 -> `docs/reference/commands.md`: included existing `NEMOCLAW_PROVIDER` interactive-mode behavior in generated docs. - Source summary: #3647 -> `docs/reference/commands.md`: documented remote sandbox path verification for `share mount`. - Source summary: #3646 -> `docs/reference/commands.md`: included existing local writable mount target guidance in generated docs. - Source summary: #3642 -> `docs/inference/use-local-inference.md`, `docs/reference/commands.md`: documented managed-vLLM model override and gated-model token checks. - Source summary: #3639 -> `docs/reference/commands.md`: documented the 63-character sandbox name limit. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [x] Doc only (includes code sample changes) ## Verification - [ ] `npx prek run --all-files` passes - [ ] `npm test` passes - [ ] Tests added or updated for new or changed behavior - [x] No secrets, API keys, or credentials committed - [x] Docs updated for user-facing behavior changes - [x] `make docs` builds without warnings (doc changes only) - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) Commit hooks passed for the staged files. A standalone `npx prek run --all-files` attempt was blocked by sandbox access to `/Users/miyoungc/.cache/prek/prek.log`, so that checkbox is left unchecked. --- <!-- DCO sign-off required by CI. Run: git config user.name && git config user.email --> Signed-off-by: Miyoung Choi <miyoungc@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Enhanced CLI command reference documentation with clearer guidance on onboarding, GPU passthrough, inference configuration, channel removal, and shared mounts. * Improved troubleshooting sections with better DNS resolution and GPU passthrough remediation steps. * Added documentation for overriding managed vLLM model selection. * Updated release notes for v0.0.45 reflecting infrastructure and workflow improvements. * **Version Bump** * Released v0.0.45. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/NVIDIA/NemoClaw/pull/3755?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary
nemoclaw <name> share mountnow fails fast with a structured, actionable error when the local mount path is on a read-only filesystem, instead of leaking the low-levelfusermount3: user has no write access to mountpointline that #3192 reported on AlmaLinux 9.7.Related Issue
Closes #3192
Changes
checkLocalMountWritable(localMount)helper insrc/lib/share-command.tsrecursively creates the mount directory and verifies the resulting path is writable, distinguishing EROFS (parent on read-only fs), EACCES (permission denied), and other failures and returning a structured{ writable, reason }result.runShareMountconsults this helper after writing the temporary SSH config and before invokingsshfs. A non-writable target now exits with the offending path, the underlying reason, and a suggested writable-path invocation; the temporary SSH config file is cleaned up before the early exit so we don't leave an orphan in/tmp. Sample output for a read-only target:Local mount path '/ro/mounts/my-assistant' is not usable: parent filesystem is read-only. share mount projects sandbox files onto a host directory via SSHFS, so the local target must be on a writable filesystem. Pick a writable directory: nemoclaw my-assistant share mount /sandbox <writable-path>.docs/reference/commands.mdand the agent-skill mirror in.agents/skills/nemoclaw-user-reference/references/commands.mdnow include the writable-mount-target requirement in theshare mountprerequisites, so users hitting the default~/.nemoclaw/mounts/<name>on a read-only filesystem know they can pass an explicit local path as the second positional argument.test/share-command-writable.test.tscovers five cases for the helper: success, EROFS frommkdirSync, EACCES frommkdirSync, an unexpectedmkdirSyncfailure (ENOSPC), and a pre-existing directory whoseaccessSyncfails.Type of Change
Verification
npx prek run --all-filespasses (commitlint, gitleaks, biome, TypeScript, source-shape, skills YAML, dist-sourcemaps)npm test(npx vitest run) passes for the new file: 5/5 intest/share-command-writable.test.ts. Full suite was 3525 passed / 4 pre-existing timing flakes (sandbox-stuck-recovery, cli timing assertion) / 13 skipped; flakes are unrelated toshare-command.tsand pass 4/4 in isolation.Signed-off-by: latenighthackathon latenighthackathon@users.noreply.github.com
Summary by CodeRabbit
Documentation
share mountprerequisites: the local mount destination must be on a writable filesystem; if the default location is read-only, provide an explicit writable path.Bug Fixes
Tests