-
Notifications
You must be signed in to change notification settings - Fork 655
(feat) early snap support #1238
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
zyga
wants to merge
3
commits into
NVIDIA:main
Choose a base branch
from
zyga:feature/upstream-snap
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+616
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,183 @@ | ||
| # Building a snap package | ||
|
|
||
| OpenShell snap packages are defined by the root `snapcraft.yaml` and built with | ||
| Snapcraft from source. | ||
|
|
||
| The helper task under `tasks/` still stages the same payload from pre-built | ||
| binaries when you want to inspect the snap root or produce local artifacts. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - Linux on `amd64` or `arm64` | ||
| - `snap` from `snapd` | ||
| - `snapcraft` | ||
| - Docker from the Docker snap (`sudo snap install docker`) | ||
|
|
||
| ## Build with Snapcraft | ||
|
|
||
| Build the snap from source with the root manifest: | ||
|
|
||
| ```shell | ||
| snapcraft pack | ||
| ``` | ||
|
|
||
| The manifest builds the Rust binaries inside Snapcraft, installs the CLI, | ||
| gateway, and sandbox supervisor into the snap, and keeps the same runtime | ||
| environment as the current deployment logic. | ||
|
|
||
| ## Staged helper flow | ||
|
|
||
| The helper task under `tasks/` still stages the same payload from pre-built | ||
| binaries when you want to inspect the snap root or produce local artifacts. | ||
|
|
||
| For that flow, install `mise` and build: | ||
|
|
||
| - `openshell` | ||
| - `openshell-gateway` | ||
| - `openshell-sandbox` | ||
|
|
||
| ## Build helper binaries | ||
|
|
||
| Build the release binaries used by the staged helper flow: | ||
|
|
||
| ```shell | ||
| mise run build:rust:snap | ||
| ``` | ||
|
|
||
| This convenience target builds the CLI with `bundled-z3`, the gateway, and | ||
| `openshell-sandbox` for the Docker driver to bind-mount into sandbox containers. | ||
|
|
||
| ## Pack the snap | ||
|
|
||
| Run the packaging hook through mise: | ||
|
|
||
| ```shell | ||
| VERSION="$(uv run python tasks/scripts/release.py get-version --snap)" | ||
|
|
||
| OPENSHELL_CLI_BINARY="$PWD/target/release/openshell" \ | ||
| OPENSHELL_GATEWAY_BINARY="$PWD/target/release/openshell-gateway" \ | ||
| OPENSHELL_DOCKER_SUPERVISOR_BINARY="$PWD/target/release/openshell-sandbox" \ | ||
| OPENSHELL_SNAP_VERSION="$VERSION" \ | ||
| OPENSHELL_OUTPUT_DIR=artifacts \ | ||
| mise run package:snap | ||
| ``` | ||
|
|
||
| The artifact is written to `artifacts/openshell_${VERSION}_${ARCH}.snap`. The | ||
| packaging hook fails before `snap pack` if `openshell-sandbox` is missing or not | ||
| executable. | ||
|
|
||
| ## Stage without packing | ||
|
|
||
| To inspect the snap root without running `snap pack`: | ||
|
|
||
| ```shell | ||
| VERSION="$(uv run python tasks/scripts/release.py get-version --snap)" | ||
|
|
||
| OPENSHELL_CLI_BINARY="$PWD/target/release/openshell" \ | ||
| OPENSHELL_GATEWAY_BINARY="$PWD/target/release/openshell-gateway" \ | ||
| OPENSHELL_DOCKER_SUPERVISOR_BINARY="$PWD/target/release/openshell-sandbox" \ | ||
| OPENSHELL_SNAP_VERSION="$VERSION" \ | ||
| mise run package:snap:stage | ||
| ``` | ||
|
|
||
| The staged root is written to `artifacts/snap-root`. | ||
|
|
||
| ## Commands in the snap | ||
|
|
||
| The snap exposes the CLI: | ||
|
|
||
| - `openshell` | ||
|
|
||
| It also defines a system service running the gateway with the Docker driver. | ||
|
|
||
| - `openshell.gateway` | ||
|
|
||
| The gateway service uses `refresh-mode: endure` so snap refreshes do not restart | ||
| it while sandboxes are active. Restart the service manually when you are ready | ||
| to move the gateway to the refreshed snap revision. | ||
|
|
||
| `openshell-sandbox` is staged next to `openshell-gateway` as the Docker | ||
| supervisor binary. The gateway app passes it to the in-process Docker driver | ||
| through `OPENSHELL_DOCKER_SUPERVISOR_BIN=$SNAP/bin/openshell-sandbox`. The | ||
| service stores its gateway database under `$SNAP_COMMON`. | ||
|
|
||
| ## Interfaces | ||
|
|
||
| The `openshell` CLI app plugs: | ||
|
|
||
| - `home` | ||
| - `network` | ||
| - `ssh-keys` | ||
| - `system-observe` | ||
|
|
||
| The `openshell.gateway` service plugs: | ||
|
|
||
| - `docker` | ||
| - `log-observe` | ||
| - `network` | ||
| - `network-bind` | ||
| - `ssh-keys` | ||
| - `system-observe` | ||
|
|
||
| ## Start a Docker gateway from the snap | ||
|
|
||
| The snapped gateway talks to Docker through the Docker snap's | ||
| `docker:docker-daemon` slot. The snap declares `default-provider: docker` on | ||
| its Docker plug so snapd can install the Docker snap when OpenShell is | ||
| installed. Connect the interface before using the Docker driver: | ||
|
|
||
| ```shell | ||
| sudo snap connect openshell:docker docker:docker-daemon | ||
| sudo snap connect openshell:log-observe | ||
| sudo snap connect openshell:system-observe | ||
| sudo snap connect openshell:ssh-keys | ||
| ``` | ||
|
|
||
| The gateway uses Docker's default Unix socket location. The Docker snap exposes | ||
| that socket through the connected `docker` interface, so no `DOCKER_HOST` | ||
| override is required. The OpenShell snap still requires the Docker snap because | ||
| it relies on the `docker:docker-daemon` slot; it does not work with Docker | ||
| installed from a Debian package or Docker's upstream packages. | ||
|
|
||
| The service runs the gateway with the Docker driver enabled: | ||
|
|
||
| ```shell | ||
| openshell.gateway \ | ||
| --drivers docker \ | ||
| --disable-tls \ | ||
| --port 17670 \ | ||
| --db-url "sqlite:$SNAP_COMMON/gateway.db?mode=rwc" \ | ||
| --docker-supervisor-bin "$SNAP/bin/openshell-sandbox" \ | ||
| --docker-network-name openshell-snap \ | ||
| --sandbox-namespace docker-snap \ | ||
| --sandbox-image ghcr.io/nvidia/openshell-community/sandboxes/base:latest \ | ||
| --sandbox-image-pull-policy IfNotPresent \ | ||
| --grpc-endpoint http://host.openshell.internal:17670 | ||
| ``` | ||
|
|
||
| This stores the gateway SQLite database at | ||
| `/var/snap/openshell/common/gateway.db`. | ||
|
|
||
| ## Connect with the OpenShell CLI | ||
|
|
||
| Register the snap-run gateway as a local plaintext gateway: | ||
|
|
||
| ```shell | ||
| openshell gateway add http://127.0.0.1:17670 --local --name snap-docker | ||
| openshell gateway select snap-docker | ||
| openshell status | ||
| ``` | ||
|
|
||
| Then use normal sandbox commands: | ||
|
|
||
| ```shell | ||
| openshell sandbox create --name demo | ||
| openshell sandbox connect demo | ||
| ``` | ||
|
|
||
| To avoid changing the default gateway, pass the gateway name per command: | ||
|
|
||
| ```shell | ||
| openshell --gateway snap-docker status | ||
| openshell --gateway snap-docker sandbox create --name demo | ||
| ``` | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| name: openshell | ||
| title: OpenShell | ||
| version: "@VERSION@" | ||
| summary: Safe, sandboxed runtimes for autonomous AI agents | ||
| description: | | ||
| OpenShell provides safe, sandboxed runtimes for autonomous AI agents. | ||
| It offers a CLI for managing gateways, sandboxes, and providers with | ||
| policy-enforced egress routing, credential proxying, and privacy-aware | ||
| LLM inference routing. | ||
|
|
||
| base: "@BASE@" | ||
| grade: "@GRADE@" | ||
| confinement: strict | ||
| license: Apache-2.0 | ||
| website: https://docs.nvidia.com/openshell/latest/index.html | ||
| source-code: https://github.com/NVIDIA/OpenShell | ||
| issues: https://github.com/NVIDIA/OpenShell/issues | ||
| contact: https://github.com/NVIDIA/OpenShell/security/policy | ||
| architectures: | ||
| - "@ARCH@" | ||
|
|
||
| apps: | ||
| openshell: | ||
| command: bin/openshell | ||
| plugs: | ||
| - home | ||
| - network | ||
| - ssh-keys | ||
| - system-observe | ||
| gateway: | ||
| command: bin/openshell-gateway | ||
| daemon: simple | ||
| refresh-mode: endure | ||
| environment: | ||
| OPENSHELL_BIND_ADDRESS: 127.0.0.1 | ||
| OPENSHELL_SERVER_PORT: 17670 | ||
| OPENSHELL_DB_URL: "sqlite:$SNAP_COMMON/gateway.db?mode=rwc" | ||
| OPENSHELL_GRPC_ENDPOINT: http://host.openshell.internal:17670 | ||
| OPENSHELL_DISABLE_TLS: true | ||
| OPENSHELL_DRIVERS: docker | ||
| OPENSHELL_DOCKER_SUPERVISOR_BIN: "$SNAP/bin/openshell-sandbox" | ||
| OPENSHELL_DOCKER_NETWORK_NAME: openshell-snap | ||
| OPENSHELL_SANDBOX_IMAGE: ghcr.io/nvidia/openshell-community/sandboxes/base:latest | ||
| OPENSHELL_SANDBOX_IMAGE_PULL_POLICY: IfNotPresent | ||
| OPENSHELL_SANDBOX_SSH_PORT: 2222 | ||
| OPENSHELL_SSH_GATEWAY_HOST: 127.0.0.1 | ||
| OPENSHELL_SSH_GATEWAY_PORT: 8080 | ||
| XDG_DATA_HOME: "$SNAP_COMMON" | ||
| # Used for creating and locating certain sockets. | ||
| XDG_RUNTIME_DIR: "$SNAP_COMMON" | ||
|
|
||
| plugs: | ||
| - docker | ||
| - log-observe | ||
| - network | ||
| - network-bind | ||
| - ssh-keys | ||
| - system-observe | ||
|
|
||
| plugs: | ||
| docker: | ||
| interface: docker | ||
| default-provider: docker |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| name: openshell | ||
| title: OpenShell | ||
| adopt-info: openshell | ||
| summary: Safe, sandboxed runtimes for autonomous AI agents | ||
| description: | | ||
| OpenShell provides safe, sandboxed runtimes for autonomous AI agents. | ||
| It offers a CLI for managing gateways, sandboxes, and providers with | ||
| policy-enforced egress routing, credential proxying, and privacy-aware | ||
| LLM inference routing. | ||
|
|
||
| base: core24 | ||
| # TODO: this prevents publishing a snap to latest/stable. | ||
| grade: devel | ||
| confinement: strict | ||
| license: Apache-2.0 | ||
| website: https://docs.nvidia.com/openshell/latest/index.html | ||
| source-code: https://github.com/NVIDIA/OpenShell | ||
| issues: https://github.com/NVIDIA/OpenShell/issues | ||
| contact: https://github.com/NVIDIA/OpenShell/security/policy | ||
| platforms: | ||
| amd64: | ||
| build-on: [amd64] | ||
| build-for: [amd64] | ||
| arm64: | ||
| build-on: [arm64] | ||
| build-for: [arm64] | ||
|
|
||
| apps: | ||
| openshell: | ||
| command: bin/openshell | ||
| plugs: | ||
| - home | ||
| - network | ||
| - ssh-keys | ||
| - system-observe | ||
| gateway: | ||
| command: bin/openshell-gateway | ||
| daemon: simple | ||
| refresh-mode: endure | ||
| environment: | ||
| OPENSHELL_BIND_ADDRESS: 127.0.0.1 | ||
| OPENSHELL_SERVER_PORT: 17670 | ||
| OPENSHELL_DB_URL: "sqlite:$SNAP_COMMON/gateway.db?mode=rwc" | ||
| OPENSHELL_GRPC_ENDPOINT: http://host.openshell.internal:17670 | ||
| OPENSHELL_DISABLE_TLS: "true" | ||
| OPENSHELL_DRIVERS: docker | ||
| OPENSHELL_DOCKER_SUPERVISOR_BIN: "$SNAP/bin/openshell-sandbox" | ||
| OPENSHELL_DOCKER_NETWORK_NAME: openshell-snap | ||
| OPENSHELL_SANDBOX_IMAGE: ghcr.io/nvidia/openshell-community/sandboxes/base:latest | ||
| OPENSHELL_SANDBOX_IMAGE_PULL_POLICY: IfNotPresent | ||
| OPENSHELL_SANDBOX_SSH_PORT: 2222 | ||
| OPENSHELL_SSH_GATEWAY_HOST: 127.0.0.1 | ||
| OPENSHELL_SSH_GATEWAY_PORT: 8080 | ||
| XDG_DATA_HOME: "$SNAP_COMMON" | ||
| XDG_RUNTIME_DIR: "$SNAP_COMMON" | ||
| plugs: | ||
| - docker | ||
| - log-observe | ||
| - network | ||
| - network-bind | ||
| - ssh-keys | ||
| - system-observe | ||
|
|
||
| parts: | ||
| openshell: | ||
| plugin: rust | ||
| rust-channel: "1.95.0" | ||
| source: . | ||
| build-packages: | ||
| - build-essential | ||
| - ca-certificates | ||
| - clang | ||
| - cmake | ||
| - git | ||
| - libclang-dev | ||
| - libssl-dev | ||
| - libz3-dev | ||
| - pkg-config | ||
| - python3 | ||
| override-pull: | | ||
| craftctl default | ||
| craftctl set version="$(python3 "$CRAFT_PROJECT_DIR/tasks/scripts/release.py" get-version --snap)" | ||
| override-build: | | ||
| set -euo pipefail | ||
|
|
||
| cargo build --release --locked -p openshell-cli --features bundled-z3 | ||
| cargo build --release --locked -p openshell-server --bin openshell-gateway | ||
| cargo build --release --locked -p openshell-sandbox --bin openshell-sandbox | ||
|
|
||
| install -D -m 0755 "$CRAFT_PROJECT_DIR/target/release/openshell" \ | ||
| "$CRAFT_PART_INSTALL/bin/openshell" | ||
| install -D -m 0755 "$CRAFT_PROJECT_DIR/target/release/openshell-gateway" \ | ||
| "$CRAFT_PART_INSTALL/bin/openshell-gateway" | ||
| install -D -m 0755 "$CRAFT_PROJECT_DIR/target/release/openshell-sandbox" \ | ||
| "$CRAFT_PART_INSTALL/bin/openshell-sandbox" | ||
| install -D -m 0644 "$CRAFT_PROJECT_DIR/LICENSE" \ | ||
| "$CRAFT_PART_INSTALL/usr/share/doc/openshell/LICENSE" | ||
| install -D -m 0644 "$CRAFT_PROJECT_DIR/README.md" \ | ||
| "$CRAFT_PART_INSTALL/usr/share/doc/openshell/README.md" |
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
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the description.