Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .agents/skills/test-release-canary/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,6 +89,8 @@ The `kubernetes` job can be reproduced on any machine with Docker and `mise inst
```shell
kind create cluster --name release-canary-local

bash e2e/support/install-agent-sandbox.sh

helm install openshell oci://ghcr.io/nvidia/openshell/helm-chart \
--version 0.0.0-dev \
--namespace openshell --create-namespace \
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/release-canary.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -214,7 +214,16 @@ jobs:
RELEASE_NAME: openshell
RELEASE_NAMESPACE: openshell
KIND_GATEWAY_NAME: kind
AGENT_SANDBOX_VERSION: v0.5.0
steps:
- name: Checkout Agent Sandbox helper
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
sparse-checkout: |
e2e/support/install-agent-sandbox.sh
sparse-checkout-cone-mode: false
persist-credentials: false

- name: Install Helm
uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # v5.0.1

Expand All@@ -224,6 +233,9 @@ jobs:
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
wait: 120s

- name: Install Agent Sandbox controller
run: bash e2e/support/install-agent-sandbox.sh

- name: Install OpenShell Helm chart from GHCR OCI
run: |
set -euo pipefail
Expand Down
4 changes: 3 additions & 1 deletion architecture/compute-runtimes.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -336,7 +336,9 @@ chart deploys the gateway and sandbox runtime integration. The default gateway
workload is a StatefulSet for SQLite-backed single-replica installs. External
database-backed installs can render a Deployment with `workload.kind=deployment`;
HA deployments must point `server.externalDbSecret` at an operator-managed
PostgreSQL database.
PostgreSQL database. Agent Sandbox CRDs and controller lifecycle remain
operator-owned; the chart can optionally preflight for a served supported API
but does not install the cluster-scoped dependency.
Standalone local deployments start the gateway with a selected runtime such as
Docker, Podman, or VM. The CLI can register multiple gateways and switch between
them without changing the sandbox architecture.
Expand Down
8 changes: 8 additions & 0 deletions deploy/helm/openshell/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,6 +17,13 @@ The Kubernetes Agent Sandbox CRDs and controller must be installed on the cluste
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/latest/download/manifest.yaml
```

The chart does not install this cluster-scoped dependency. By default, it
fails before creating gateway resources when the cluster serves neither
supported Sandbox API (`agents.x-k8s.io/v1beta1` or
`agents.x-k8s.io/v1alpha1`). Disable the check with
`agentSandbox.preflight.enabled=false` for offline `helm template` rendering,
where Helm cannot discover cluster APIs.

## Install on Kubernetes

```shell
Expand DownExpand Up@@ -153,6 +160,7 @@ add `ci/values-spire.yaml` to the OpenShell release values files.
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| affinity | object | `{}` | Affinity rules for the gateway pod. |
| agentSandbox.preflight.enabled | bool | `true` | Check the live cluster for a supported Agent Sandbox API before rendering gateway resources. Disable only for offline rendering and linting. |
| certManager.caSecretName | string | `"openshell-ca-tls"` | Secret created for the intermediate CA (Certificate with isCA: true). |
| certManager.certificateDuration | string | `"8760h"` | Duration for cert-manager-issued certificates. |
| certManager.certificateRenewBefore | string | `"720h"` | Renewal window for cert-manager-issued certificates. |
Expand Down
7 changes: 7 additions & 0 deletions deploy/helm/openshell/README.md.gotmpl
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,6 +17,13 @@ The Kubernetes Agent Sandbox CRDs and controller must be installed on the cluste
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/latest/download/manifest.yaml
```

The chart does not install this cluster-scoped dependency. By default, it
fails before creating gateway resources when the cluster serves neither
supported Sandbox API (`agents.x-k8s.io/v1beta1` or
`agents.x-k8s.io/v1alpha1`). Disable the check with
`agentSandbox.preflight.enabled=false` for offline `helm template` rendering,
where Helm cannot discover cluster APIs.

## Install on Kubernetes

```shell
Expand Down
11 changes: 11 additions & 0 deletions deploy/helm/openshell/templates/agent-sandbox-preflight.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
{{/*
SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0
*/}}
{{- if .Values.agentSandbox.preflight.enabled }}
{{- $v1beta1 := or (.Capabilities.APIVersions.Has "agents.x-k8s.io/v1beta1") (.Capabilities.APIVersions.Has "agents.x-k8s.io/v1beta1/Sandbox") }}
{{- $v1alpha1 := or (.Capabilities.APIVersions.Has "agents.x-k8s.io/v1alpha1") (.Capabilities.APIVersions.Has "agents.x-k8s.io/v1alpha1/Sandbox") }}
{{- if not (or $v1beta1 $v1alpha1) }}
{{- fail "Agent Sandbox is required but neither agents.x-k8s.io/v1beta1 nor agents.x-k8s.io/v1alpha1 is served by this cluster. Install the Agent Sandbox CRDs and controller before deploying OpenShell; see deploy/helm/openshell/README.md. Set agentSandbox.preflight.enabled=false only for offline rendering." }}
{{- end }}
{{- end }}
12 changes: 12 additions & 0 deletions deploy/helm/openshell/tests/agent_sandbox_preflight_test.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

suite: Agent Sandbox preflight
templates:
- templates/agent-sandbox-preflight.yaml

tests:
- it: fails clearly by default without a supported Agent Sandbox API
asserts:
- failedTemplate:
errorPattern: "Agent Sandbox is required but neither agents.x-k8s.io/v1beta1 nor agents.x-k8s.io/v1alpha1 is served"
10 changes: 10 additions & 0 deletions deploy/helm/openshell/values.yaml
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,6 +133,16 @@ service:
# -- Gateway metrics service port.
metricsPort: 9090

# Agent Sandbox is a cluster-scoped prerequisite for the Kubernetes compute
# driver. OpenShell deliberately does not install its CRDs or controller.
# Enable this check for live Helm installs to fail before creating gateway
# resources when neither supported Sandbox API is served. Disable it for
# offline `helm template` and lint workflows, which cannot discover APIs.
agentSandbox:
preflight:
# -- Check the live cluster for a supported Agent Sandbox API before rendering gateway resources. Disable only for offline rendering and linting.
enabled: true

# Pod restart behavior and health probe tuning.
podLifecycle:
# -- Grace period, in seconds, before Kubernetes terminates the gateway pod.
Expand Down
13 changes: 13 additions & 0 deletions docs/kubernetes/setup.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -38,6 +38,19 @@ kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/lates

This creates the `agent-sandbox-system` namespace, installs the `sandboxes.agents.x-k8s.io` CRD, and starts the controller.

The Helm chart checks for a supported Agent Sandbox API before it creates
gateway resources. This preflight is enabled by default. Disable it only for
offline `helm template` rendering, where Helm cannot discover cluster APIs:

```shell
helm template openshell oci://ghcr.io/nvidia/openshell/helm-chart \
--version <version> \
--set agentSandbox.preflight.enabled=false
```

The chart does not install or upgrade the cluster-scoped Agent Sandbox CRDs or
controller.

<Note>
**Air-gapped clusters:** mirror the manifest above and the `registry.k8s.io/agent-sandbox/agent-sandbox-controller` image referenced inside it to your internal registry, then point the manifest's image reference at your mirror before applying. You will also need to mirror the OpenShell gateway and sandbox images — see the chart's `image.repository` value for the gateway and `server.sandboxImage` / `server.supervisorImage` for the sandbox runtime.
</Note>
Expand Down
38 changes: 38 additions & 0 deletions e2e/support/install-agent-sandbox.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# Install the upstream Agent Sandbox CRDs and controller. Pass any kubectl
# context arguments (for example, --context kind-e2e) as script arguments.
set -euo pipefail

agent_sandbox_version="${AGENT_SANDBOX_VERSION:-v0.5.0}"

wait_for_agent_sandbox_crd() {
local deadline
local established

deadline=$(( $(date +%s) + 120 ))
while [ "$(date +%s)" -lt "${deadline}" ]; do
if kubectl "$@" get crd/sandboxes.agents.x-k8s.io >/dev/null 2>&1; then
established="$(kubectl "$@" get crd/sandboxes.agents.x-k8s.io \
-o 'jsonpath={.status.conditions[?(@.type=="Established")].status}' \
2>/dev/null || true)"
if [ "${established}" = "True" ]; then
return 0
fi
fi
sleep 2
done

echo "Timed out waiting for agent-sandbox Sandbox CRD to become Established" >&2
kubectl "$@" get crd/sandboxes.agents.x-k8s.io -o yaml >&2 || true
return 1
}

echo "Installing agent-sandbox CRDs and controller (${agent_sandbox_version})..."
agent_sandbox_base="https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${agent_sandbox_version}"
kubectl "$@" apply -f "${agent_sandbox_base}/manifest.yaml"
wait_for_agent_sandbox_crd "$@"
kubectl "$@" -n agent-sandbox-system rollout status \
deployment/agent-sandbox-controller --timeout=300s
29 changes: 2 additions & 27 deletions e2e/with-kube-gateway.sh
Original file line numberDiff line numberDiff line change
Expand Up@@ -103,28 +103,6 @@ kctl() {
kubectl --context "${KUBE_CONTEXT}" "$@"
}

wait_for_agent_sandbox_crd() {
local deadline
local established

deadline=$(( $(date +%s) + 120 ))
while [ "$(date +%s)" -lt "${deadline}" ]; do
if kctl get crd/sandboxes.agents.x-k8s.io >/dev/null 2>&1; then
established="$(kctl get crd/sandboxes.agents.x-k8s.io \
-o 'jsonpath={.status.conditions[?(@.type=="Established")].status}' \
2>/dev/null || true)"
if [ "${established}" = "True" ]; then
return 0
fi
fi
sleep 2
done

echo "Timed out waiting for agent-sandbox Sandbox CRD to become Established" >&2
kctl get crd/sandboxes.agents.x-k8s.io -o yaml >&2 || true
return 1
}

helmctl() {
helm --kube-context "${KUBE_CONTEXT}" "$@"
}
Expand DownExpand Up@@ -676,11 +654,8 @@ fi
# The Kubernetes compute driver creates and watches Sandbox CRs reconciled
# by the upstream agent-sandbox-controller. Without the CRD + controller,
# every gateway K8s call 404s and CreateSandbox never produces a Pod.
echo "Installing agent-sandbox CRDs and controller (${AGENT_SANDBOX_VERSION})..."
_agent_sandbox_base="https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}"
kctl apply -f "${_agent_sandbox_base}/manifest.yaml"
wait_for_agent_sandbox_crd
kctl -n agent-sandbox-system rollout status deployment/agent-sandbox-controller --timeout=300s
AGENT_SANDBOX_VERSION="${AGENT_SANDBOX_VERSION}" \
bash "${ROOT}/e2e/support/install-agent-sandbox.sh" --context "${KUBE_CONTEXT}"

ACTIVE_CREDENTIAL_DRIVER="${OPENSHELL_E2E_CREDENTIAL_DRIVER:-kubernetes-secrets}"
if [ "${OPENSHELL_E2E_CREDENTIAL_DRIVERS:-0}" = "1" ] \
Expand Down
4 changes: 2 additions & 2 deletions tasks/helm.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -30,12 +30,12 @@ run = """
helm dependency build deploy/helm/openshell
echo "--- helm lint: defaults ---"
echo "values files: deploy/helm/openshell/values.yaml"
helm lint deploy/helm/openshell
helm lint deploy/helm/openshell --set agentSandbox.preflight.enabled=false
for f in deploy/helm/openshell/ci/values-*.yaml; do
variant=$(basename "$f" .yaml | sed 's/values-//')
echo "--- helm lint: $variant ---"
echo "values files: deploy/helm/openshell/values.yaml, $f"
helm lint deploy/helm/openshell -f "$f"
helm lint deploy/helm/openshell -f "$f" --set agentSandbox.preflight.enabled=false
done
echo "All variants passed."
"""
Expand Down
Loading