Skip to content
Open
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
1 change: 1 addition & 0 deletions cmd/ate-setup/internal/demos/all/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ import (
_ "github.com/agent-substrate/substrate/cmd/ate-setup/internal/demos/multitemplate"
_ "github.com/agent-substrate/substrate/cmd/ate-setup/internal/demos/parking"
_ "github.com/agent-substrate/substrate/cmd/ate-setup/internal/demos/sandbox"
_ "github.com/agent-substrate/substrate/cmd/ate-setup/internal/demos/sandboxmicrovm"
)
43 changes: 43 additions & 0 deletions cmd/ate-setup/internal/demos/sandboxmicrovm/sandboxmicrovm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package sandboxmicrovm installs the micro-VM variant of the sandbox demo.
//
// It needs the cluster-wide `microvm` SandboxConfig that
// hack/install-microvm-deps.sh --install creates.
package sandboxmicrovm

import (
"github.com/agent-substrate/substrate/cmd/ate-setup/internal/demos"
"github.com/agent-substrate/substrate/cmd/ate-setup/internal/steps"
"github.com/agent-substrate/substrate/internal/resources"
)

// namespace is the pool's k8s namespace; it doubles as the atespace holding
// the demo's ActorTemplate.
const namespace = "ate-demo-sandbox-microvm"

func init() {
demos.Register(&demos.Substrate{
DemoName: "demo-sandbox-microvm",
Short: "The sandbox demo on micro-VM workers (needs hack/install-microvm-deps.sh --install)",
WorkerPoolManifest: "demos/sandbox/sandbox-microvm.yaml.tmpl",
Deployments: []steps.TemplateRef{{Atespace: namespace, Name: "sandbox-microvm"}},
Templates: []demos.SubstrateTemplate{{
Manifest: "demos/sandbox/sandbox-microvm-template.yaml.tmpl",
Ref: resources.ActorTemplateRef{Atespace: namespace, Name: "sandbox-microvm"},
}},
GoldenTimeout: demos.MicroVMGoldenTimeout,
})
}
25 changes: 25 additions & 0 deletions demos/sandbox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,25 @@ Inspect the template with:
kubectl ate get actor-template sandbox-template -a ate-demo-sandbox
```

#### Micro-VM variant

The default template runs on gVisor. Where gVisor cannot start a sandbox on the
host kernel, deploy the micro-VM variant instead:

```bash
./hack/install-ate.sh --deploy-demo-sandbox-microvm
```

It installs the same server into the `ate-demo-sandbox-microvm` namespace and
atespace, with the pool's workers on micro-VM (`ateom-microvm`) and the template
naming the cluster-wide `microvm` SandboxConfig. That config comes from
`hack/install-microvm-deps.sh --install`, which has to have run first. The
sandbox class is the only difference: the client, the commands, and the
suspend/resume behavior are the same, so substitute

- `--atespace=ate-demo-sandbox-microvm` in the client invocation below,
- `-a ate-demo-sandbox-microvm` where the actor commands name the atespace.

### 2. Create a Sandbox Actor

Create the sandbox actor in the demo's atespace with a chosen name (e.g., `my-sandbox-1`) — `--template` names the template, resolved in the actor's atespace:
Expand Down Expand Up @@ -111,3 +130,9 @@ To remove the sandbox demo resources (actors, template, atespace, workerpool, an
```bash
./hack/install-ate.sh --delete-demo-sandbox
```

The micro-VM variant is removed the same way:

```bash
./hack/install-ate.sh --delete-demo-sandbox-microvm
```
47 changes: 47 additions & 0 deletions demos/sandbox/sandbox-microvm-template.yaml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# ActorTemplate (protojson-shaped ateapipb.ActorTemplate) for the micro-VM
# sandbox demo. Applied with `kubectl ate create actor-template -f -` after
# `ko resolve` replaces the ko:// image reference; the
# ate-demo-sandbox-microvm atespace must exist.
metadata:
atespace: ate-demo-sandbox-microvm
name: sandbox-microvm
workerSelector:
matchLabels:
workload: sandbox-microvm
containers:
- name: sandbox
image: ko://github.com/agent-substrate/substrate/demos/sandbox
env:
- name: PORT
value: "80"
# Sandbox size: vCPUs + guest RAM at (or below) the pool's per-worker capacity,
# leaving VMM-reserve headroom under the worker memory limit (see
# internal/sizing). Quantities are strings in the proto.
resources:
limits:
- name: cpu
quantity: "1"
- name: memory
quantity: 512Mi
snapshotConfig:
# MEMORY, matching the gVisor variant: the sandbox preserves live process
# state across a suspend, so a resume continues the same shell session.
preferredFidelity: SNAPSHOT_FIDELITY_MEMORY
storageLocation: gs://${BUCKET_NAME}/ate-demo-sandbox-microvm/
sandboxConfig:
sandboxClass: SANDBOX_CLASS_MICROVM
configName: microvm
64 changes: 64 additions & 0 deletions demos/sandbox/sandbox-microvm.yaml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Worker pool for the micro-VM (kata + cloud-hypervisor) variant of the sandbox
# demo. The ActorTemplate is not a CRD: it lives in
# sandbox-microvm-template.yaml.tmpl and is created through the ate API with
# `kubectl ate create actor-template`. The cluster-wide `microvm`
# SandboxConfig referenced by the pool is installed by
# hack/install-microvm-deps.sh

apiVersion: v1
kind: Namespace
metadata:
name: ate-demo-sandbox-microvm

---

apiVersion: ate.dev/v1alpha1
kind: WorkerPool
metadata:
name: sandbox-microvm
namespace: ate-demo-sandbox-microvm
labels:
workload: sandbox-microvm
spec:
# Two workers: one for the sandbox actor, one spare for the golden actor the
# template reconciler runs while building the golden snapshot.
replicas: 2
sandboxClasses:
- name: microvm
configRef:
name: microvm
workerImage: ko://github.com/agent-substrate/substrate/cmd/ateom-microvm
template:
# Per-worker resources: these size the worker POD and advertise its
# scheduling capacity (the per-actor ceiling). The micro-VM sandbox itself is
# sized by the ActorTemplate's resources in
# sandbox-microvm-template.yaml.tmpl, not by these; keep the actor memory
# below this limit so the VMM reserve fits (see internal/sizing).
#
# Capacity comes from the limits (workerCapacity reads limits only), while the
# kube-scheduler packs nodes by the requests — so the CPU request is set well
# below the limit to keep the pool placeable on a small node (a single kind
# node in CI, shared with the other demo pools) without changing what an actor
# is allowed to use. Memory is not compressible, so its request matches the
# limit: the guest RAM plus the VMM reserve has to be really there.
resources:
limits:
cpu: "1"
memory: 1Gi
requests:
cpu: 250m
memory: 1Gi
3 changes: 2 additions & 1 deletion hack/install-ate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ ATE_DEMOS=(
demo-egress-microvm
demo-jupyter
demo-sandbox
demo-sandbox-microvm
demo-claude-code-multiplex
demo-multi-template
demo-parking
Expand All @@ -60,7 +61,7 @@ demo_usage() {
echo " --deploy-demo-counter-with-external-volume Deploy demo-counter with external volume validation"
echo " (STORAGE_CLASS names the class; it otherwise follows --setup-csi)"
;;
demo-counter-microvm|demo-egress-microvm)
demo-counter-microvm|demo-egress-microvm|demo-sandbox-microvm)
echo " Needs hack/install-microvm-deps.sh --install to have run (cluster-wide microvm SandboxConfig)."
;;
demo-claude-code-multiplex)
Expand Down
Loading