Files
OpenShell/sdk/go/docs/src/api/sandbox-templates.md
Mrunal Patel c502be9fd7 feat(api): return typed deletion outcomes with explicit missing-target semantics (#3317)
* feat(api): return typed deletion outcomes with explicit missing-target semantics

Implement phase 2 of #3051 across the public gateway API and first-party SDKs. Preserve asynchronous sandbox deletion and observed resource identities, reserve legacy wire fields, and document the coordinated migration.

Signed-off-by: Mrunal Patel <mrunalp@gmail.com>

* fix(sdk): bind deletion waits to sandbox identity

Track accepted deletions by original sandbox identity in Rust and TypeScript. Preserve name-only waits and cover replacement races and lookup failures.

Merge the phase-one cleanup fix and adapt its interceptor regressions to typed deletion outcomes.

Refs #3051.

Signed-off-by: Mrunal Patel <mrunalp@gmail.com>

* test(e2e): accept asynchronous stopped sandbox deletion

Allow either completed or accepted deletion output, then continue polling for actual sandbox absence. This preserves the lifecycle assertion under the phase-two deletion contract.

Refs #3051.

Signed-off-by: Mrunal Patel <mrunalp@gmail.com>

---------

Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
2026-09-16 22:11:19 +00:00

3.4 KiB

Sandbox Templates

Accessor: client.SandboxTemplates()

Manage reusable, workspace-scoped sandbox workload templates. Templates own the portable workload shape and optional driver-specific config. Sandbox creation can reference a template by name while supplying only governance fields such as providers or policy.

The Go SDK names the reusable resource SandboxWorkloadTemplate because SandboxTemplate already represents the legacy inline compute template inside SandboxSpec.

Create

Creates a reusable template in a workspace.

gpuCount := uint32(1)

template, err := client.SandboxTemplates().Create(ctx, "default", &v1.SandboxWorkloadTemplate{
    Name: "gpu-kata",
    Labels: map[string]string{
        "team": "platform",
    },
    Spec: v1.SandboxWorkloadTemplateSpec{
        Workload: &v1.SandboxWorkloadConfig{
            Image: "nvcr.io/nvidia/openshell:latest",
            Environment: map[string]string{
                "NVIDIA_VISIBLE_DEVICES": "all",
            },
            Resources: &v1.SandboxResources{
                CPU:    "2",
                Memory: "8Gi",
                GPU:    &v1.SandboxGPURequirements{Count: &gpuCount},
            },
        },
        DriverConfig: map[string]any{
            "kubernetes": map[string]any{
                "pod": map[string]any{
                    "runtime_class_name": "kata",
                },
            },
        },
        DesiredServiceLevel: &v1.SandboxServiceLevel{
            Startup: &v1.SandboxStartup{
                ReadyWithin: 45 * time.Second,
                MaxBurst:    2,
            },
        },
    },
})

Set GPU: &v1.SandboxGPURequirements{} to request the active driver's default GPU assignment without specifying a count.

Create a Sandbox From a Template

Use CreateSandboxFromTemplate to create a sandbox from a named reusable template without changing the legacy Sandboxes() interface.

sb, err := client.CreateSandboxFromTemplate(
    ctx,
    "default",
    "training-run",
    "gpu-kata",
    &v1.SandboxSpec{
        Providers: []string{"openai"},
        Policy:    policy,
    },
    map[string]string{"job": "training"},
)

When creating from a template, the spec should only include governance fields: Providers, Policy, Command, and TTY. Workload fields such as image, environment, CPU, memory, GPU, and driver config come from the template.

Get

Retrieves a template by name.

template, err := client.SandboxTemplates().Get(ctx, "default", "gpu-kata")
fmt.Println(template.Spec.Workload.Image)

List

List returns a lazy pager over matching templates in one workspace or across all workspaces. Use ListAll to follow every continuation token automatically.

templates, err := client.SandboxTemplates().ListAll(ctx, "default", v1.ListOptions{
    PageSize: 50,
})

allTemplates, err := client.SandboxTemplates().ListAll(ctx, "", v1.ListOptions{
    AllWorkspaces: true,
})

Delete

Deletes a template by name. Existing sandboxes created from the template are not deleted.

deletion, err := client.SandboxTemplates().Delete(ctx, "default", "gpu-kata")

Fake Client

The fake client includes the same template sub-client and can be pre-populated for tests.

client := fake.NewClient()
client.AddSandboxTemplate("default", &types.SandboxWorkloadTemplate{
    Name: "gpu-kata",
    Spec: types.SandboxWorkloadTemplateSpec{
        Workload: &types.SandboxWorkloadConfig{Image: "python:3.12"},
    },
})