Repository navigation
Add the openshell provider: sandboxes on an NVIDIA OpenShell gateway - #1293
Merged
Merged
Conversation
onctl create/ls/ssh/pause/resume/destroy -p openshell now manage sandboxes on an OpenShell gateway (https://github.com/NVIDIA/OpenShell) through its Go SDK (sdk/go v0.1.6), with the gateway's policy enforced: outbound connections are denied by default. - No gateway settings of onctl's own: it uses the gateways the openshell CLI registered (openshell.gateway in onctl.yaml, or the CLI's active one). The SDK's loader doesn't do mTLS, the default for a self-hosted gateway, so that mode is built here from the CLI's client bundle. - A sandbox has no address, so ssh goes through the gateway's ssh relay: DialVM opens SSH().Tunnel (other ports: TCP().Forward) and presents it as a net.Conn through a net.Pipe, so ssh handshake deadlines work. The stream outlives the dial's context, which tools.Remote cancels as soon as the dial returns. onctl ssh's ProxyCommand passes the gateway and workspace to ssh-proxy (hidden flags), so it reaches the same gateway. - Pause/resume are the sandbox's stop/start (files kept); ssh and DialVM start a stopped sandbox first. - Sandboxes run unprivileged and the relay has no sftp, so create and ssh refuse apply files, uploads, downloads and cloud-init up front with an explanation, and onctl claude says it doesn't run there yet. - Like boxes, it works without an onctl.yaml (configOptional). Tested against a gateway from the onctl-templates openshell template (Hetzner, Ubuntu 24.04, OpenShell 0.1.6): create in ~2s, ls, ssh with a command, system ssh via ssh-proxy, pause -> paused, ssh auto-starts it, a file kept across pause/resume, destroy, -a refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ba6Vc6jJ1yfnNCkExeDWHh
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1293 +/- ##
==========================================
+ Coverage 50.97% 51.28% +0.31%
==========================================
Files 83 86 +3
Lines 9943 10165 +222
==========================================
+ Hits 5068 5213 +145
- Misses 4875 4952 +77 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
-p openshell: onctl manages sandboxes on an NVIDIA OpenShell gateway through its Go SDK (sdk/gov0.1.6). The gateway enforces its policy: outbound connections are denied by default, and credentials stay out of the sandbox.How it works
openshellCLI registered (openshell.gatewayin onctl.yaml, or the CLI's active gateway). The SDK's loader (gateway.NewClient) doesn't support mTLS, which a self-hosted gateway uses by default, sointernal/provideropenshellbuilds that client from the CLI'smtls/bundle.DialVMopensSSH().Tunnel(other ports useTCP().Forward) and wraps it in anet.Connvianet.Pipe, so the ssh handshake deadline works.tools.Remotecancels that context as soon as the dial returns, and the SDK would otherwise close the stream with it.onctl ssh's ProxyCommand passes the gateway and workspace tossh-proxy(hidden flags), so the proxy reaches the same gateway as the command that started it.sshandDialVMstart a stopped sandbox first.configOptional).What doesn't apply, and is refused up front with an explanation
-a,--upload/--downloadand cloud-init. Sandboxes run unprivileged (no root, no sudo), and the relay has no SFTP. Software comes from--image.--domain. A sandbox has no address.onctl claude. It needs root, file transfer, and a policy that lets Claude reach its API. That's a follow-up.Tested
Against a gateway from the onctl-templates
openshelltemplate (Hetznerccx13, Ubuntu 24.04, OpenShell 0.1.6):createin about 2 s, including the SSH readiness check through the relayls, andssh <name> -- cmdsshwithssh-proxyas ProxyCommandpause -f: the sandbox shows aspaused, andsshstarts it againdestroy-arefused before anything is createdUnit tests use in-memory fakes: deploy image fallback, list order and status mapping, pause/resume calls, DialVM routing (22 → SSH relay, others → TCP forward), the stream outliving a cancelled dial context, auto-start of a stopped sandbox, ProxyCommand quoting, gateway-loading errors and the create/ssh checks.
go test ./...passes.🤖 Generated with Claude Code
https://claude.ai/code/session_01Ba6Vc6jJ1yfnNCkExeDWHh