Agent Sandbox
Go SDK Reference
import "sigs.k8s.io/agent-sandbox/clients/go/sandbox"
Index
- Constants
- Variables
- func NewTracerProvider(ctx context.Context, serviceName string) (*sdktrace.TracerProvider, error)
- type CallOption
- type Client
- func NewClient(_ context.Context, opts Options) (*Client, error)
- func (c *Client) CreateSandbox(ctx context.Context, warmPoolName, namespace string, opts …CreateOption) (*Sandbox, error)
- func (c *Client) DeleteAll(ctx context.Context)
- func (c *Client) DeleteSandbox(ctx context.Context, claimName, namespace string) error
- func (c *Client) EnableAutoCleanup() (stop func())
- func (c *Client) GetSandbox(ctx context.Context, claimName, namespace string) (*Sandbox, error)
- func (c *Client) ListActiveSandboxes() []Key
- func (c *Client) ListAllSandboxes(ctx context.Context, namespace string, opts …ListOption) ([]string, error)
- type Commands
- type ConnectionStrategy
- type Connectivity
- type CreateOption
- func WithAdoptExisting() CreateOption
- func WithClaimEnv(env []extv1beta1.EnvVar) CreateOption
- func WithClaimLabels(labels map[string]string) CreateOption
- func WithClaimName(name string) CreateOption
- func WithPodAnnotations(annotations map[string]string) CreateOption
- func WithPodLabels(labels map[string]string) CreateOption
- func WithSandboxReadyTimeout(d time.Duration) CreateOption
- func WithShutdownAfter(d time.Duration) CreateOption
- func WithVolumeClaimTemplates(templates []sandboxv1beta1.PersistentVolumeClaimTemplate) CreateOption
- type DirectStrategy
- type ExecutionResult
- type FileEntry
- type FileType
- type Files
- func (f *Files) Delete(ctx context.Context, path string, recursive bool, opts …CallOption) error
- func (f *Files) Exists(ctx context.Context, path string, opts …CallOption) (bool, error)
- func (f *Files) List(ctx context.Context, path string, opts …CallOption) ([]FileEntry, error)
- func (f *Files) Read(ctx context.Context, path string, opts …CallOption) ([]byte, error)
- func (f *Files) ReadTo(ctx context.Context, path string, destination io.Writer, opts …CallOption) (int64, error)
- func (f *Files) Write(ctx context.Context, path string, content []byte, opts …CallOption) error
- func (f *Files) WriteReader(ctx context.Context, path string, content io.Reader, opts …CallOption) error
- type HTTPError
- type Handle
- type Health
- type Info
- type K8sHelper
- type Key
- type ListOption
- type Metadata
- type Options
- type ProcessEvent
- type ProcessEventType
- type ProcessHandle
- type ProcessSignal
- type Runtime
- type Sandbox
- func New(_ context.Context, opts Options) (*Sandbox, error)
- func (s *Sandbox) Annotations() map[string]string
- func (s *Sandbox) ClaimName() string
- func (s *Sandbox) Close(ctx context.Context) error
- func (s *Sandbox) Commands() *Commands
- func (s *Sandbox) Delete(ctx context.Context, path string, recursive bool, opts …CallOption) error
- func (s *Sandbox) Disconnect(ctx context.Context) error
- func (s *Sandbox) Exists(ctx context.Context, path string, opts …CallOption) (bool, error)
- func (s *Sandbox) Files() *Files
- func (s *Sandbox) Health(ctx context.Context, opts …CallOption) (*Health, error)
- func (s *Sandbox) IsReady() bool
- func (s *Sandbox) List(ctx context.Context, path string, opts …CallOption) ([]FileEntry, error)
- func (s *Sandbox) Metadata(ctx context.Context, opts …CallOption) (*Metadata, error)
- func (s *Sandbox) Open(ctx context.Context) (retErr error)
- func (s *Sandbox) PodIP() string
- func (s *Sandbox) PodName() string
- func (s *Sandbox) Read(ctx context.Context, path string, opts …CallOption) ([]byte, error)
- func (s *Sandbox) ReadTo(ctx context.Context, path string, destination io.Writer, opts …CallOption) (int64, error)
- func (s *Sandbox) Run(ctx context.Context, command string, opts …CallOption) (*ExecutionResult, error)
- func (s *Sandbox) SandboxName() string
- func (s *Sandbox) ServiceFQDN() string
- func (s *Sandbox) Write(ctx context.Context, path string, content []byte, opts …CallOption) error
- func (s *Sandbox) WriteReader(ctx context.Context, path string, content io.Reader, opts …CallOption) error
Constants
const (
// PodNameAnnotation is the deprecated annotation key on a Sandbox resource that identifies the name of the underlying pod.
// Deprecated: New Sandboxes use their own name for the backing pod while non-empty legacy annotations may still be honored.
PodNameAnnotation = "agents.x-k8s.io/pod-name"
)
Variables
Span attribute keys in the sandbox.* namespace.
var (
AttrClaimName = attribute.Key("sandbox.claim.name")
AttrCommandExecutable = attribute.Key("sandbox.command.executable")
AttrExitCode = attribute.Key("sandbox.exit_code")
AttrFilePath = attribute.Key("sandbox.file.path")
AttrFileSize = attribute.Key("sandbox.file.size")
AttrFileCount = attribute.Key("sandbox.file.count")
AttrFileExists = attribute.Key("sandbox.file.exists")
AttrGatewayName = attribute.Key("sandbox.gateway.name")
AttrGatewayNamespace = attribute.Key("sandbox.gateway.namespace")
AttrRequestID = attribute.Key("sandbox.request_id")
)
Sentinel errors returned by the SDK.
var (
ErrNotReady = errors.New("sandbox is not ready")
ErrTimeout = errors.New("operation timed out")
ErrClaimFailed = errors.New("claim creation failed")
ErrWarmPoolNotFound = errors.New("sandbox warm pool not found")
ErrTemplateNotFound = errors.New("sandbox template not found")
ErrPortForwardDied = errors.New("port-forward connection lost")
ErrNoSandboxService = errors.New("sandbox has no headless Service")
ErrAlreadyOpen = errors.New("sandbox is already open; call Close first")
ErrOrphanedClaim = errors.New("orphaned claim; call Close() to retry deletion")
ErrRetriesExhausted = errors.New("retries exhausted")
ErrSandboxDeleted = errors.New("sandbox was deleted before becoming ready")
ErrGatewayDeleted = errors.New("gateway was deleted during address discovery")
ErrResponseTooLarge = errors.New("response exceeded 16 MB limit")
// ErrUnsupportedByRuntime is returned by operations the selected
// runtime or connection cannot perform (e.g. Delete on the legacy
// python-runtime, or Run with RuntimeSandboxd and APIURL).
ErrUnsupportedByRuntime = errors.New("operation not supported by the sandbox runtime")
// ErrProcessProtocol indicates an invalid or incomplete process event stream.
ErrProcessProtocol = errors.New("invalid process event stream")
// ErrConcurrentRecv indicates that another Recv is already in progress.
ErrConcurrentRecv = errors.New("concurrent Recv on process handle")
)
func NewTracerProvider
func NewTracerProvider(ctx context.Context, serviceName string) (*sdktrace.TracerProvider, error)
NewTracerProvider creates a TracerProvider with an OTLP/gRPC exporter. The endpoint is read from OTEL_EXPORTER_OTLP_ENDPOINT (default: localhost:4317). serviceName becomes the service.name resource attribute. The caller owns the returned provider and must call Shutdown when done.
type CallOption
CallOption configures per-call behavior for SDK operations.
type CallOption func(*callOptions)
func WithEnv
func WithEnv(env map[string]string) CallOption
WithEnv sets environment variables for a single Run or Commands.Start, merged over the sandbox’s own environment (a key given here wins). Repeated calls accumulate. Both return ErrUnsupportedByRuntime on the legacy python-runtime, which cannot carry them. Other operations ignore it.
result, err := client.Run(ctx, "echo $GREETING", sandbox.WithEnv(map[string]string{"GREETING": "hi"}))
func WithMaxAttempts
func WithMaxAttempts(n int) CallOption
WithMaxAttempts sets the maximum number of attempts for an operation. Values ≤0 are ignored and the default is used (1 for Run, 6 for file operations). Commands.Start rejects values greater than 1 because a non-idempotent process creation cannot be safely replayed.
result, err := client.Run(ctx, "cat /etc/hostname", sandbox.WithMaxAttempts(6))
func WithTimeout
func WithTimeout(d time.Duration) CallOption
WithTimeout sets the total timeout for a single operation. HTTP operations override their default RequestTimeout. For Commands.Start it covers the entire stream, including startup; Start has no default timeout.
func WithWorkingDir
func WithWorkingDir(dir string) CallOption
WithWorkingDir sets the working directory for Run or Commands.Start, relative to the sandbox root (the default). sandboxd rejects a directory that resolves outside the root. Both return ErrUnsupportedByRuntime on the legacy python-runtime. Other operations ignore it.
type Client
Client manages sandbox lifecycles and tracks active handles.
type Client struct {
// contains filtered or unexported fields
}
func NewClient
func NewClient(_ context.Context, opts Options) (*Client, error)
NewClient creates a Client with shared configuration.
func (*Client) CreateSandbox
func (c *Client) CreateSandbox(ctx context.Context, warmPoolName, namespace string, opts ...CreateOption) (*Sandbox, error)
CreateSandbox provisions a new sandbox and returns a managed handle. Optional CreateOption values override or merge onto the Client’s base Options for this call. On failure, a claim with a generated name is cleaned up; a claim named with WithClaimName is left in place.
func (*Client) DeleteAll
func (c *Client) DeleteAll(ctx context.Context)
DeleteAll closes and deletes all tracked sandboxes. Best-effort.
func (*Client) DeleteSandbox
func (c *Client) DeleteSandbox(ctx context.Context, claimName, namespace string) error
DeleteSandbox closes the handle (if tracked) and deletes the claim.
func (*Client) EnableAutoCleanup
func (c *Client) EnableAutoCleanup() (stop func())
EnableAutoCleanup deletes tracked sandboxes on SIGINT/SIGTERM. Claims created with WithClaimName are caller-owned: their handles are disconnected but the claims are kept. Call the returned function to stop the signal handler.
func (*Client) GetSandbox
func (c *Client) GetSandbox(ctx context.Context, claimName, namespace string) (*Sandbox, error)
GetSandbox retrieves an existing sandbox by claim name. Returns the cached handle if connected, otherwise re-attaches.
func (*Client) ListActiveSandboxes
func (c *Client) ListActiveSandboxes() []Key
ListActiveSandboxes returns tracked sandboxes, pruning inactive handles.
func (*Client) ListAllSandboxes
func (c *Client) ListAllSandboxes(ctx context.Context, namespace string, opts ...ListOption) ([]string, error)
ListAllSandboxes lists SandboxClaim names in the given namespace, optionally narrowed with WithLabelSelector.
type Commands
Commands provides command execution on a sandbox.
type Commands struct {
// contains filtered or unexported fields
}
func (*Commands) Run
func (c *Commands) Run(ctx context.Context, command string, opts ...CallOption) (*ExecutionResult, error)
Run executes a command in the sandbox and returns the result. The combined JSON response (stdout + stderr + metadata) is limited to 16 MB; commands producing more output will fail with ErrResponseTooLarge.
Because command execution is not idempotent, Run defaults to a single attempt (no retries). For idempotent commands that should retry on transient server errors (502, 503, etc.), use WithMaxAttempts:
result, err := client.Run(ctx, "cat /etc/hostname", sandbox.WithMaxAttempts(6))
WithMaxAttempts applies only to the legacy runtime. With RuntimeSandboxd, Run issues a single gRPC Execute regardless of the configured attempts.
WithEnv and WithWorkingDir apply only to RuntimeSandboxd; the legacy runtime returns ErrUnsupportedByRuntime rather than silently ignoring them.
func (*Commands) Start
func (c *Commands) Start(ctx context.Context, command string, opts ...CallOption) (handle *ProcessHandle, err error)
Start starts a sandboxd command and returns after receiving its process ID. It preserves Run’s shell-string, WithEnv and WithWorkingDir semantics. The caller must Recv through the exit event to io.EOF, or Close the handle. The context and an explicit WithTimeout cover the entire stream; there is no default RequestTimeout. Start never retries and rejects WithMaxAttempts > 1. The legacy runtime and REST-only connections return ErrUnsupportedByRuntime.
type ConnectionStrategy
ConnectionStrategy defines how the SDK discovers or reaches a runtime’s HTTP endpoint, either directly or through the sandbox-router.
type ConnectionStrategy interface {
Connect(ctx context.Context) (baseURL string, err error)
Close() error
}
type Connectivity
Connectivity selects the transport used to reach the in-sandbox runtime.
type Connectivity string
const (
// ConnectivityPortForward reaches the sandbox over a SPDY port-forward
// brokered by the apiserver. Works from anywhere a kubeconfig does,
// including a laptop or CI runner. Default.
//
// With RuntimeSandboxd the forward targets the sandbox pod itself, which
// does not work for Kata or gVisor pods: their workload does not listen in
// the pod's host-side network namespace. Use an in-cluster mode for those.
// RuntimeLegacyPython forwards to the sandbox-router instead and is
// unaffected.
ConnectivityPortForward Connectivity = "port-forward"
// ConnectivityInClusterService dials the Sandbox's headless Service by
// its in-cluster DNS name (Status.ServiceFQDN), taking the apiserver —
// and, for RuntimeLegacyPython, the sandbox-router, off the data path.
//
// Prefer this over ConnectivityInClusterPodIP when sandboxes cross a trust
// boundary. The Service's selector only ever matches its own Sandbox's
// pod, so a pod IP that Kubernetes has since reassigned to another
// tenant would be caught when the TTL expires. A deleted Sandbox takes
// its Service with it: connections then fail rather than landing on a stranger.
// (DNS caching still leaves a TTL-bounded window)
//
// Requires the Sandbox to have a Service — set spec.service: true on
// the template. Open fails when Status.ServiceFQDN is empty rather than
// falling back to the pod IP, so the safety property cannot be lost
// silently.
ConnectivityInClusterService Connectivity = "in-cluster-service"
// ConnectivityInClusterPodIP dials Status.PodIP. It needs no Service, so
// it works against any Sandbox without template changes.
//
// It carries the pod IP's reuse hazard: nothing detects that the sandbox
// pod was rescheduled, so requests can continue to a stale address that
// Kubernetes may have since reassigned to an unrelated pod. Use
// ConnectivityInClusterService where that matters.
ConnectivityInClusterPodIP Connectivity = "in-cluster-pod-ip"
)
type CreateOption
CreateOption configures per-sandbox options for Client.CreateSandbox, overriding or merging onto the Client’s base Options for that call.
type CreateOption func(*createOptions)
func WithAdoptExisting
func WithAdoptExisting() CreateOption
WithAdoptExisting makes a single CreateSandbox call attach to an existing SandboxClaim named by WithClaimName instead of failing when it already exists. See Options.AdoptExisting for the checks applied to the existing claim.
func WithClaimEnv
func WithClaimEnv(env []extv1beta1.EnvVar) CreateOption
WithClaimEnv sets the environment variables injected into the SandboxClaim for a single CreateSandbox call, replacing Client-level Options.Env.
func WithClaimLabels
func WithClaimLabels(labels map[string]string) CreateOption
WithClaimLabels merges labels onto the SandboxClaim metadata for a single CreateSandbox call. Per-call keys override colliding Client-level Options.Labels keys; the SDK’s created-by label always wins. Repeated calls accumulate.
func WithClaimName
func WithClaimName(name string) CreateOption
WithClaimName sets a deterministic SandboxClaim name for a single CreateSandbox call. See Options.ClaimName.
func WithPodAnnotations
func WithPodAnnotations(annotations map[string]string) CreateOption
WithPodAnnotations merges annotations onto spec.additionalPodMetadata.annotations for a single CreateSandbox call. Per-call keys override colliding Client-level Options.PodAnnotations keys. Repeated calls accumulate.
func WithPodLabels
func WithPodLabels(labels map[string]string) CreateOption
WithPodLabels merges labels onto spec.additionalPodMetadata.labels for a single CreateSandbox call. Per-call keys override colliding Client-level Options.PodLabels keys. Repeated calls accumulate.
func WithSandboxReadyTimeout
func WithSandboxReadyTimeout(d time.Duration) CreateOption
WithSandboxReadyTimeout sets how long a single CreateSandbox call waits for the sandbox to become ready, replacing Client-level Options.SandboxReadyTimeout. Zero keeps the Client-level value.
func WithShutdownAfter
func WithShutdownAfter(d time.Duration) CreateOption
WithShutdownAfter sets the claim lifetime for a single CreateSandbox call, replacing Client-level Options.ShutdownAfter. Zero means no expiry.
func WithVolumeClaimTemplates
func WithVolumeClaimTemplates(templates []sandboxv1beta1.PersistentVolumeClaimTemplate) CreateOption
WithVolumeClaimTemplates sets spec.volumeClaimTemplates on the SandboxClaim for a single CreateSandbox call, replacing Client-level Options.VolumeClaimTemplates.
type DirectStrategy
DirectStrategy connects using a pre-configured URL, bypassing all discovery.
type DirectStrategy struct {
URL string
}
func (*DirectStrategy) Close
func (s *DirectStrategy) Close() error
func (*DirectStrategy) Connect
func (s *DirectStrategy) Connect(_ context.Context) (string, error)
type ExecutionResult
ExecutionResult holds the result of a command execution in the sandbox.
type ExecutionResult struct {
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
ExitCode int `json:"exit_code"`
}
type FileEntry
FileEntry represents a file or directory entry in the sandbox. It is runtime-neutral: the SDK decodes the legacy wire format (mod_time as a float POSIX timestamp) and the sandboxd wire format (modified_at as an RFC 3339 string, plus mode) into this one shape.
type FileEntry struct {
Name string
Size int64
Type FileType
ModTime time.Time
// Mode holds octal permission bits (e.g. "0644"). Only populated by
// the sandboxd runtime; empty on legacy.
Mode string
}
type FileType
FileType represents the type of a file entry.
type FileType string
const (
FileTypeFile FileType = "file"
FileTypeDirectory FileType = "directory"
)
type Files
Files provides file operations on a sandbox.
type Files struct {
// contains filtered or unexported fields
}
func (*Files) Delete
func (f *Files) Delete(ctx context.Context, path string, recursive bool, opts ...CallOption) error
Delete removes a file or directory in the sandbox. When recursive is true, directories are removed with their contents (rm -rf semantics); otherwise deleting a non-empty directory fails with a 409 HTTPError.
Only supported by the sandboxd runtime: the legacy python-runtime has no delete endpoint, and calls return ErrUnsupportedByRuntime.
func (*Files) Exists
func (f *Files) Exists(ctx context.Context, path string, opts ...CallOption) (bool, error)
Exists checks if a file or directory exists at the given path in the sandbox.
func (*Files) List
func (f *Files) List(ctx context.Context, path string, opts ...CallOption) ([]FileEntry, error)
List returns the contents of a directory in the sandbox.
func (*Files) Read
func (f *Files) Read(ctx context.Context, path string, opts ...CallOption) ([]byte, error)
Read downloads a file from the sandbox and returns its complete contents.
func (*Files) ReadTo
func (f *Files) ReadTo(ctx context.Context, path string, destination io.Writer, opts ...CallOption) (int64, error)
ReadTo downloads a file into a caller-owned destination without buffering the complete response. It returns the number of bytes written. The destination is never closed. If the response exceeds MaxDownloadSize, ReadTo writes at most MaxDownloadSize bytes and returns an error. Data written before an error or context cancellation remains in the destination.
func (*Files) Write
func (f *Files) Write(ctx context.Context, path string, content []byte, opts ...CallOption) error
Write uploads content to the sandbox.
With the legacy runtime the path must be a plain filename without directory separators (e.g., “script.py”, not “dir/script.py”). The sandboxd runtime supports relative paths and creates parent directories automatically.
The entire content is buffered in memory to support retries on transient failures. Content exceeding MaxUploadSize (default 256 MB) is rejected before any network I/O.
func (*Files) WriteReader
func (f *Files) WriteReader(ctx context.Context, path string, content io.Reader, opts ...CallOption) error
WriteReader uploads content read from content without buffering the entire payload in memory. Streaming uploads use a single request attempt because a generic io.Reader cannot be replayed safely after a partial request. Passing WithMaxAttempts with a value greater than 1 returns an error; it is not silently reduced to a single attempt.
With the legacy runtime, path must be a plain filename. The sandboxd runtime accepts relative paths and creates parent directories automatically. For an unknown-length reader, MaxUploadSize is enforced while the request is being streamed; the server may therefore receive a prefix before an oversized upload is rejected. Legacy streaming uploads use HTTP chunked transfer encoding, so compatible runtimes and proxies must accept streaming request bodies without a Content-Length header.
type HTTPError
HTTPError represents a non-OK HTTP response from the sandbox.
type HTTPError struct {
StatusCode int
Body string
Operation string
}
func (*HTTPError) Error
func (e *HTTPError) Error() string
type Handle
Handle provides high-level interaction with a sandbox instance. Sandbox implements this interface; consumers should accept Handle in their APIs to enable testing with mocks. For sub-object access (Commands(), Files()), use the concrete *Sandbox type directly.
type Handle interface {
Open(ctx context.Context) error
Close(ctx context.Context) error
Disconnect(ctx context.Context) error
IsReady() bool
Run(ctx context.Context, command string, opts ...CallOption) (*ExecutionResult, error)
Write(ctx context.Context, path string, content []byte, opts ...CallOption) error
Read(ctx context.Context, path string, opts ...CallOption) ([]byte, error)
List(ctx context.Context, path string, opts ...CallOption) ([]FileEntry, error)
Exists(ctx context.Context, path string, opts ...CallOption) (bool, error)
}
type Health
Health is the sandboxd runtime’s report from GET /v1/health.
type Health struct {
Status string `json:"status"`
// UptimeSeconds is how long sandboxd has been running.
UptimeSeconds int64 `json:"uptime_seconds"`
}
type Info
Info provides read-only access to sandbox identity metadata.
type Info interface {
ClaimName() string
SandboxName() string
PodName() string
PodIP() string
Annotations() map[string]string
}
type K8sHelper
K8sHelper encapsulates all Kubernetes API interactions for sandbox lifecycle management. It can be shared across multiple Sandbox instances.
type K8sHelper struct {
AgentsClient agentsv1beta1.AgentsV1beta1Interface
ExtensionsClient extensionsv1beta1.ExtensionsV1beta1Interface
DynamicClient dynamic.Interface
CoreClient corev1client.CoreV1Interface
DiscoveryClient discoveryv1client.DiscoveryV1Interface
RestConfig *rest.Config
Log logr.Logger
}
func NewK8sHelper
func NewK8sHelper(restConfig *rest.Config, log logr.Logger) (*K8sHelper, error)
NewK8sHelper creates a K8sHelper by loading kubeconfig and constructing all required clientsets. If restConfig is non-nil it is used directly; otherwise in-cluster config is tried first, then ~/.kube/config.
func (*K8sHelper) WaitForSandboxReady
func (h *K8sHelper) WaitForSandboxReady(ctx context.Context, sandboxName, namespace string) error
WaitForSandboxReady waits until the named Sandbox has a true Ready condition. sandboxName is the backing Sandbox name, not the SandboxClaim name. It does not connect to the runtime. Use a context deadline to bound the wait; cancellation and deadline errors are detectable with errors.Is. A missing Sandbox is waited for, while deletion observed during the watch returns ErrSandboxDeleted. A terminal Ready=False reason such as PodFailed returns ErrClaimFailed. API list/watch failures are retried until ctx ends.
type Key
Key identifies a tracked sandbox in the registry.
type Key struct {
Namespace string
ClaimName string
}
type ListOption
ListOption configures Client.ListAllSandboxes.
type ListOption func(*listOptions)
func WithLabelSelector
func WithLabelSelector(selector string) ListOption
WithLabelSelector restricts the listing to claims matching a Kubernetes label selector, for example “app=agent,tier!=dev”. Pair it with Options.Labels, which stamps labels on the claims the client creates.
type Metadata
Metadata is the non-sensitive, workload-scoped configuration sandboxd serves from GET /v1/metadata.
type Metadata struct {
// Env holds the environment variables sandboxd exposes: only names
// matching its --metadata-env-prefix, minus anything that looks like a
// credential. It is never nil.
Env map[string]string `json:"env"`
}
type Options
Options configures a Sandbox instance.
type Options struct {
// WarmPoolName is the name of the SandboxWarmPool to use.
// Required in Options before calling Open() to provision a new sandbox.
// Optional on Client-level Options; pass the pool name per-sandbox to
// CreateSandbox instead.
// Must be a valid Kubernetes DNS subdomain (lowercase, [a-z0-9.-]).
WarmPoolName string
// ClaimName is an optional deterministic name for the SandboxClaim.
// When empty, Kubernetes generates a unique name with prefix "sandbox-claim-".
// When set and a SandboxClaim with this name already exists in Namespace,
// Open fails with ErrClaimFailed unless AdoptExisting is also set.
// A named claim is caller-owned: a failed Open and
// Client.EnableAutoCleanup leave it in place; Close still deletes it.
// Must be a valid Kubernetes DNS subdomain (lowercase, [a-z0-9.-]).
// NewClient rejects it; use WithClaimName with Client.CreateSandbox.
ClaimName string
// AdoptExisting makes Open attach to an existing SandboxClaim named
// ClaimName when creating it returns HTTP 409 Conflict, instead of
// failing. The existing claim must reference the same WarmPoolName and
// must not be terminating, and Open fails if it is replaced or starts
// terminating before its sandbox name resolves. Creation options are not
// reapplied to an adopted claim.
// Requires ClaimName. NewClient rejects it; use WithAdoptExisting with
// Client.CreateSandbox.
AdoptExisting bool
// Runtime selects the in-sandbox runtime API. Default: RuntimeLegacyPython.
// RuntimeSandboxd talks to the sandbox pod rather than the sandbox-router,
// so GatewayName is not supported with it. APIURL remains available as an
// advanced/testing escape hatch for the REST endpoint only: Run needs the
// gRPC endpoint and returns ErrUnsupportedByRuntime with it.
Runtime Runtime
// Connectivity selects the transport. Default: ConnectivityPortForward.
//
// The in-cluster values conflict with both GatewayName and APIURL, and
// require that this process runs inside the same cluster as the sandbox
// pods.
Connectivity Connectivity
// SandboxdRESTPort is the pod port of sandboxd's Filesystem & Runtime
// REST API. Only used with RuntimeSandboxd. Default: 8080.
SandboxdRESTPort int
// SandboxdGRPCPort is the pod port of sandboxd's gRPC ProcessService.
// Only used with RuntimeSandboxd. Default: 9090.
SandboxdGRPCPort int
// Namespace where the SandboxClaim will be created. Default: "default".
// Must be a valid Kubernetes DNS label (lowercase, [a-z0-9-]).
Namespace string
// GatewayName enables Gateway mode. The client watches this Gateway resource
// for an external IP, then routes through the sandbox-router.
// Must be a valid Kubernetes DNS subdomain (lowercase, [a-z0-9.-]).
GatewayName string
// GatewayNamespace is where the Gateway lives. Default: "default".
// Must be a valid Kubernetes DNS label (lowercase, [a-z0-9-]).
GatewayNamespace string
// GatewayScheme is the URL scheme used when constructing the base URL
// from the Gateway's address. Default: "http".
GatewayScheme string
// APIURL enables Direct URL mode. The client connects directly to this URL,
// bypassing gateway discovery. Takes precedence over GatewayName.
APIURL string
// ServerPort is the port the sandbox runtime listens on. Default: 8888.
ServerPort int
// Env is the list of environment variables to inject into the SandboxClaim.
// Setting Env forces a cold start from the warm pool template.
Env []extv1beta1.EnvVar
// Labels are added to every SandboxClaim this client creates, so they can
// be selected later (see WithLabelSelector). The SDK's own created-by label
// always wins over a colliding key.
Labels map[string]string
// ShutdownAfter expires every SandboxClaim this client creates that long
// after creation, so a crashed client cannot leak sandboxes. The claim
// gets spec.lifecycle.shutdownTime and the Delete shutdown policy; the
// deadline is rounded up to a whole second. Zero (the default) means no expiry.
ShutdownAfter time.Duration
// PodLabels are propagated to the backing Sandbox Pod via
// spec.additionalPodMetadata.labels (unlike Labels, which are placed on the
// SandboxClaim object itself). Label keys must carry a domain prefix from
// the controller's label-domain allowlist (default: sandbox.users.io).
PodLabels map[string]string
// PodAnnotations are propagated to the backing Sandbox Pod via
// spec.additionalPodMetadata.annotations.
PodAnnotations map[string]string
// VolumeClaimTemplates is a list of persistent volume claim templates to
// create for the sandbox via spec.volumeClaimTemplates. Setting
// VolumeClaimTemplates forces a cold start because warm pool pods do not
// have these volumes.
VolumeClaimTemplates []sandboxv1beta1.PersistentVolumeClaimTemplate
// SandboxReadyTimeout is how long to wait for the sandbox to become ready. Default: 180s.
SandboxReadyTimeout time.Duration
// GatewayReadyTimeout is how long to wait for the gateway IP. Default: 180s.
GatewayReadyTimeout time.Duration
// PortForwardReadyTimeout is how long to wait for port-forward to be established. Default: 30s.
PortForwardReadyTimeout time.Duration
// CleanupTimeout is how long to wait for claim deletion during both Open
// rollback and Close. Uses a detached context so cleanup succeeds even if
// the caller's context is already cancelled. Default: 30s.
CleanupTimeout time.Duration
// RequestTimeout is the total timeout for a single SDK method call
// (e.g., Run, Read, Write), encompassing all retry attempts and backoff
// sleeps. Applied only when the caller's context has no deadline.
// Default: 180s.
RequestTimeout time.Duration
// PerAttemptTimeout bounds the time to receive response headers per
// HTTP attempt. Stopped on success so body reads use RequestTimeout.
// Default: 60s.
PerAttemptTimeout time.Duration
// MaxDownloadSize is the maximum response body size for Read() and ReadTo().
// Run() uses a fixed 16 MB decode limit; List() and Exists() use a
// fixed 8 MB internal limit. Default: 256 MB.
MaxDownloadSize int64
// MaxUploadSize is the maximum content size for Write() and WriteReader().
// Write rejects oversized content before network I/O; WriteReader enforces
// the limit while streaming. Default: 256 MB.
MaxUploadSize int64
// Logger for structured logging. Defaults to stderr at INFO level.
// Provide a custom logr.Logger for full control, or set Quiet to
// suppress output.
Logger logr.Logger
// Quiet suppresses the default stderr logger. Has no effect when a
// custom Logger is provided (non-zero-value).
Quiet bool
// K8sHelper provides pre-constructed Kubernetes clients. If nil, a new
// K8sHelper is created from RestConfig. Use this to share clients
// across multiple Sandbox instances.
K8sHelper *K8sHelper
// RestConfig overrides the Kubernetes REST config. If nil, the client first
// tries in-cluster config (for pods), then falls back to the default
// kubeconfig (~/.kube/config or KUBECONFIG env). Ignored when K8sHelper is set.
RestConfig *rest.Config
// HTTPTransport overrides the HTTP transport for sandbox operations.
// If nil, a default transport with sensible timeouts is created.
// Use this for custom TLS, proxies, or other transport-level settings.
HTTPTransport http.RoundTripper
// TraceServiceName is the OpenTelemetry service name used for the tracer's
// instrumentation scope and the resource's service.name attribute.
// Default: "sandbox-client".
TraceServiceName string
// TracerProvider sets the OpenTelemetry TracerProvider for span creation.
// If nil, falls back to otel.GetTracerProvider (noop by default).
TracerProvider trace.TracerProvider
// DisablePodIPRouting suppresses the X-Sandbox-Pod-IP header even when a
// pod IP is available. Use in environments with strict network policies,
// service meshes, or secure overlays where direct pod-to-pod IP routing is
// restricted but service-based DNS routing works correctly.
// Note: this only affects router-based transports that send X-Sandbox-* headers.
// Default: false (header is sent when router headers are enabled and a pod IP is present).
DisablePodIPRouting bool
}
type ProcessEvent
ProcessEvent contains one raw output chunk or the command’s exit code. Output chunks need not be complete lines or valid UTF-8. Events from stdout and stderr do not have a guaranteed global ordering.
type ProcessEvent struct {
Type ProcessEventType
// Data is populated only for stdout/stderr and remains valid after Recv.
Data []byte
// ExitCode is populated only for exit events. A nonzero code is not an error.
ExitCode int
}
type ProcessEventType
ProcessEventType identifies an output or exit event from a streaming command.
type ProcessEventType string
const (
ProcessEventStdout ProcessEventType = "stdout"
ProcessEventStderr ProcessEventType = "stderr"
ProcessEventExit ProcessEventType = "exit"
)
type ProcessHandle
ProcessHandle owns one Start stream, not the Sandbox or shared connection. Consume its events through io.EOF or call Close when abandoning the stream.
type ProcessHandle struct {
// contains filtered or unexported fields
}
func (*ProcessHandle) Close
func (h *ProcessHandle) Close() error
Close cancels only this session and is idempotent. A nil error acknowledges local cleanup, not synchronous remote process termination. For graceful shutdown, send a signal before cancelling the stream instead.
func (*ProcessHandle) ProcessID
func (h *ProcessHandle) ProcessID() int32
ProcessID returns the daemon-local virtual ID, not an OS PID. It cannot identify a process across daemon restarts.
func (*ProcessHandle) Recv
func (h *ProcessHandle) Recv() (*ProcessEvent, error)
Recv returns the next stdout, stderr or exit event. An exit event must be followed by io.EOF to confirm that the RPC also completed successfully. Nonzero exit codes are results; RPC and protocol failures remain errors. Only one Recv may be active; a second returns ErrConcurrentRecv without ending the stream. SendSignal and Close may run concurrently with Recv.
func (*ProcessHandle) SendSignal
func (h *ProcessHandle) SendSignal(ctx context.Context, signal ProcessSignal) error
SendSignal sends SIGINT, SIGTERM or SIGKILL to this process group using its original connection. Success means the signal was sent, not that the process exited. Its context controls only this RPC; failure does not cancel Start. Keep receiving events to observe the exit and the final RPC status.
type ProcessSignal
ProcessSignal is a supported POSIX signal for a sandboxd process group.
type ProcessSignal string
const (
SignalSIGINT ProcessSignal = "SIGINT"
SignalSIGTERM ProcessSignal = "SIGTERM"
SignalSIGKILL ProcessSignal = "SIGKILL"
)
type Runtime
Runtime identifies the in-sandbox runtime API the SDK speaks.
type Runtime string
const (
// RuntimeLegacyPython is the python-runtime HTTP API (POST /upload,
// GET /download|list|exists/{path}, POST /execute on port 8888),
// reached through the sandbox-router unless Connectivity selects a
// direct pod dial. Default.
RuntimeLegacyPython Runtime = "legacy-python"
// RuntimeSandboxd is the sandboxd hybrid API defined by KEP-539.2:
// REST filesystem (/v1/files/...) on port 8080 plus gRPC
// ProcessService on port 9090. The SDK reaches the sandbox pod directly
// or over a port-forward (default), see Connectivity.
RuntimeSandboxd Runtime = "sandboxd"
)
type Sandbox
Sandbox manages the lifecycle of a single agent-sandbox instance. Operations are split across Commands and Files.
type Sandbox struct {
// contains filtered or unexported fields
}
func New
func New(_ context.Context, opts Options) (*Sandbox, error)
New creates a new Sandbox with the given options. Call Open() to create a sandbox and establish connectivity.
func (*Sandbox) Annotations
func (s *Sandbox) Annotations() map[string]string
func (*Sandbox) ClaimName
func (s *Sandbox) ClaimName() string
func (*Sandbox) Close
func (s *Sandbox) Close(ctx context.Context) error
Close deletes the SandboxClaim and cleans up resources.
func (*Sandbox) Commands
func (s *Sandbox) Commands() *Commands
Commands returns the command execution sub-object.
func (*Sandbox) Delete
func (s *Sandbox) Delete(ctx context.Context, path string, recursive bool, opts ...CallOption) error
Delete removes a file or directory (sandboxd runtime only; the legacy python-runtime returns ErrUnsupportedByRuntime). Not part of the Handle interface to avoid breaking existing implementers.
func (*Sandbox) Disconnect
func (s *Sandbox) Disconnect(ctx context.Context) error
Disconnect closes the transport connection without deleting the SandboxClaim. The sandbox stays alive on the server. Call Open() to reconnect. Disconnect is safe to call concurrently with Open; an in-progress Open is cancelled before the transport is torn down.
func (*Sandbox) Exists
func (s *Sandbox) Exists(ctx context.Context, path string, opts ...CallOption) (bool, error)
func (*Sandbox) Files
func (s *Sandbox) Files() *Files
Files returns the file operations sub-object.
func (*Sandbox) Health
func (s *Sandbox) Health(ctx context.Context, opts ...CallOption) (*Health, error)
Health returns sandboxd’s report from GET /v1/health. It returns an HTTPError while sandboxd is shutting down, and ErrUnsupportedByRuntime on the legacy python-runtime. It does not retry unless WithMaxAttempts is set. Not part of the Handle interface to avoid breaking existing implementers.
func (*Sandbox) IsReady
func (s *Sandbox) IsReady() bool
IsReady returns true if the sandbox is ready for communication.
func (*Sandbox) List
func (s *Sandbox) List(ctx context.Context, path string, opts ...CallOption) ([]FileEntry, error)
func (*Sandbox) Metadata
func (s *Sandbox) Metadata(ctx context.Context, opts ...CallOption) (*Metadata, error)
Metadata returns the workload-scoped configuration sandboxd serves from GET /v1/metadata (sandboxd runtime only; the legacy python-runtime returns ErrUnsupportedByRuntime). It does not retry unless WithMaxAttempts is set. Not part of the Handle interface to avoid breaking existing implementers.
func (*Sandbox) Open
func (s *Sandbox) Open(ctx context.Context) (retErr error)
Open creates a SandboxClaim and waits for the sandbox to become ready, then discovers the API URL based on the configured connection mode. On failure after claim creation, a claim with a generated name is automatically deleted; if deletion also fails, call Close() to retry. A claim named by ClaimName is caller-owned and is left in place.
func (*Sandbox) PodIP
func (s *Sandbox) PodIP() string
func (*Sandbox) PodName
func (s *Sandbox) PodName() string
func (*Sandbox) Read
func (s *Sandbox) Read(ctx context.Context, path string, opts ...CallOption) ([]byte, error)
func (*Sandbox) ReadTo
func (s *Sandbox) ReadTo(ctx context.Context, path string, destination io.Writer, opts ...CallOption) (int64, error)
ReadTo streams a file into a caller-owned io.Writer without buffering the complete response. The destination is never closed.
func (*Sandbox) Run
func (s *Sandbox) Run(ctx context.Context, command string, opts ...CallOption) (*ExecutionResult, error)
func (*Sandbox) SandboxName
func (s *Sandbox) SandboxName() string
func (*Sandbox) ServiceFQDN
func (s *Sandbox) ServiceFQDN() string
ServiceFQDN returns the in-cluster DNS name of the Sandbox’s headless Service, or "" when it has none (spec.service unset or false). Not part of the Info interface, which is frozen for backward compatibility.
func (*Sandbox) Write
func (s *Sandbox) Write(ctx context.Context, path string, content []byte, opts ...CallOption) error
func (*Sandbox) WriteReader
func (s *Sandbox) WriteReader(ctx context.Context, path string, content io.Reader, opts ...CallOption) error
WriteReader streams content from an io.Reader without buffering the entire payload. Streaming uploads use a single request attempt because a generic reader cannot be replayed safely. Passing WithMaxAttempts with a value greater than 1 returns an error; it is not silently reduced to one attempt.
Generated by gomarkdoc