sandbox-operator

Lifecycle verbs

Beyond create/delete, a delivered sandbox supports four action verbs, served as subresources so the standard agents.x-k8s.io schema stays untouched — an unmodified upstream client keeps working.

subresource body effect
sandboxes/pause SandboxPauseOptions snapshots guest memory and stops the VM
sandboxes/resume SandboxResumeOptions restores it via cocoon’s mmap fast path
sandboxes/fork SandboxForkOptions{count,ttlSeconds} branches N children; the source keeps running
sandboxes/snapshot SandboxSnapshotOptions{name} captures a checkpoint later sandboxes branch from
kubectl create --raw \
  /apis/agents.x-k8s.io/v1beta1/namespaces/default/sandboxes/my-sandbox/snapshot \
  -f - <<<'{"apiVersion":"agents.x-k8s.io/v1beta1","kind":"SandboxSnapshotOptions","name":"before-migration"}'

These verbs are not uniformly fast. resume takes cocoon’s mmap restore path and a fork’s children clone node-locally, but pause and snapshot write the guest’s memory out, so they cost time proportional to its size. Where a checkpoint lives, and what happens when its node cannot serve a branch, is in snapshot-placement.md.

Runnable walk-through

examples/lifecycle/example.go exercises every operation on both surfaces against a live cluster — create, get, list, snapshot, fork, pause, resume, delete over the Kubernetes API, then the same lifecycle plus templates, metrics, snapshot listing, timeout and keepalive over the e2b REST API:

go run ./examples/lifecycle \
  -kubeconfig ~/.kube/config -namespace default \
  -e2b-url http://localhost:8080 -e2b-key "$E2B_API_KEY"

It discovers a template from the fleet’s advertised warm pools, so no image argument is needed. Omit -e2b-url to run only the Kubernetes half. Each step prints what it did, so the output doubles as acceptance evidence:

=== Kubernetes API ===
  create     Sandbox default/example-219526000
  get        node=cocoon-bd25-sandboxd claimID=sb_77ace349e7cc1db6
  snapshot   snapshotID=ck_92799687f14e8fea on node=cocoon-bd25-sandboxd
  fork       child[0] sandboxID=sb_06d1b2438dcc1d1b node=cocoon-bd25-sandboxd
  pause      took 315ms (proportional to guest memory)
  resume     took 109ms (mmap restore fast path)

=== e2b-compatible REST API ===
  create     sandboxID=sb-175124667cfa1281 envdVersion=0.4.0
  metrics    cpuCount=1 memTotal=5.36870912e+08
  pause      409 on repeat — the already-paused contract holds
  connect    201 — restored via the mmap fast path

Two behaviors callers must handle