docs/sdk/go/sandbox.mdx
Create and control a microVM sandbox: boot it from an image, run commands, stream logs and metrics, then shut it down. See Overview for configuration examples and Lifecycle for state management. Examples assume the package is imported as m "github.com/superradcompany/microsandbox/sdk/go".
import m "github.com/superradcompany/microsandbox/sdk/go"
sb, err := m.CreateSandbox(ctx, "api", // 1. configure + boot
m.WithImage("python"),
m.WithMemory(1024),
)
if err != nil {
return err
}
defer sb.Close() // 4. shut down
out, err := sb.Exec(ctx, "python", []string{"-V"}) // 2. run
if err != nil {
return err
}
fmt.Println(out.Stdout()) // 3. read output
func CreateSandbox(ctx context.Context, name string, opts ...SandboxOption) (*Sandbox, error)
Create and boot a new sandbox. Pulls the image if needed, boots the VM, starts the guest agent, and waits until it is ready to accept commands. Sandbox names must be non-empty and no longer than 128 UTF-8 bytes. The returned *Sandbox owns the VM process, call Close (or Stop + Close) when done. See Options for all configuration knobs.
sb, err := m.CreateSandbox(ctx, "api",
m.WithImage("python:3.12"),
m.WithMemory(512),
m.WithCPUs(2),
m.WithEnv(map[string]string{"PYTHONDONTWRITEBYTECODE": "1"}),
)
if err != nil {
return err
}
defer func() {
_ = sb.Stop(context.Background())
_ = sb.Close()
}()
func GetSandbox(ctx context.Context, name string) (*SandboxHandle, error)
Look up a sandbox by name and return a metadata handle without connecting to it. Returns an error with Kind == ErrSandboxNotFound if no such sandbox exists. The returned *SandboxHandle exposes Connect, Start, Stop, Kill, Remove, Metrics, Logs, and snapshot methods.
h, err := m.GetSandbox(ctx, "api")
if err != nil {
return err
}
fmt.Println(h.Status())
func ListSandboxes(ctx context.Context) ([]*SandboxHandle, error)
Return metadata for every known sandbox (running, stopped, draining, crashed), ordered by creation time, newest first.
<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#sandboxhandle">[]*SandboxHandle</a></div> <div className="msb-param-desc">All sandbox handles.</div> </div> </div> <Accordion title="Example">handles, err := m.ListSandboxes(ctx)
if err != nil {
return err
}
for _, h := range handles {
fmt.Printf("%s — %s\n", h.Name(), h.Status())
}
func ListSandboxesWith(ctx context.Context, filter SandboxFilter) ([]*SandboxHandle, error)
Return sandbox metadata narrowed by a SandboxFilter. Label selectors are AND-matched: a sandbox matches only if it carries every label in the filter.
filter := m.NewSandboxFilter().WithLabels(map[string]string{"user.id": "alice"})
handles, err := m.ListSandboxesWith(ctx, filter)
func NewSandboxFilter() SandboxFilter
Return an empty SandboxFilter that matches every sandbox. Chain WithLabels to narrow the results passed to ListSandboxesWith.
func StartSandbox(ctx context.Context, name string) (*Sandbox, error)
Restart a previously stopped sandbox. The VM reboots using the persisted configuration and returns a live *Sandbox.
sb, err := m.StartSandbox(ctx, "api")
func StartSandboxDetached(ctx context.Context, name string) (*Sandbox, error)
Boot a stopped sandbox in detached mode. The VM keeps running after the returned handle is released.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>name</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Name of a stopped sandbox, up to 128 UTF-8 bytes.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#methods">*Sandbox</a></div> <div className="msb-param-desc">Running sandbox in detached mode.</div> </div> </div>func RemoveSandbox(ctx context.Context, name string) error
Delete a stopped sandbox and all its persisted state from disk. Fails if the sandbox is still running, stop it first.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>name</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Sandbox name, up to 128 UTF-8 bytes.</div> </div> </div> <Accordion title="Example">err := m.RemoveSandbox(ctx, "api")
func AllSandboxMetrics(ctx context.Context) (map[string]*Metrics, error)
Return a point-in-time Metrics snapshot for every running sandbox, keyed by sandbox name. Only running and draining sandboxes appear.
all, err := m.AllSandboxMetrics(ctx)
for name, metrics := range all {
fmt.Printf("%s: %.1f%% CPU\n", name, metrics.CPUPercent)
}
func EnsureInstalled(ctx context.Context, opts ...SetupOption) error
Optional. Ensure msb + libkrunfw are present under ~/.microsandbox/, downloading them from the matching GitHub release if not. Call at startup to surface install errors up front; otherwise the first sandbox call handles it. The FFI library is embedded in the Go binary and loads automatically, EnsureInstalled does not govern it. Idempotent; options apply only to the first call.
if err := m.EnsureInstalled(ctx); err != nil {
log.Fatal(err)
}
func IsInstalled() bool
Report whether msb + libkrunfw are present on disk at the SDK's pinned version. Does not dlopen the FFI library (which ships embedded).
<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">bool</span></div> <div className="msb-param-desc"><code>true</code> if the runtime is present at the expected version.</div> </div> </div>func SDKVersion() string
Return the microsandbox release version this SDK was compiled against.
<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">string</span></div> <div className="msb-param-desc">Pinned release version, e.g. <code>"0.5.8"</code>.</div> </div> </div>func RuntimeVersion() (string, error)
Return the version reported by the loaded FFI library. Auto-loads the library on first use; returns an error with Kind == ErrLibraryNotLoaded only if loading fails (e.g. unsupported platform or GLIBC mismatch).
The *Sandbox returned by CreateSandbox, StartSandbox, and SandboxHandle.Connect carries the methods below. *Sandbox is safe for concurrent use from multiple goroutines. The command-execution methods, Exec, ExecStream, Shell, and ShellStream, live on the same value and are documented under Execution.
func (s *Sandbox) Name() string
Return the sandbox name.
<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">string</span></div> <div className="msb-param-desc">Sandbox name, up to 128 UTF-8 bytes.</div> </div> </div>func (s *Sandbox) FS() *SandboxFSOps
Return a filesystem accessor for reading and writing files inside the running sandbox. See Filesystem for the API.
<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="/sdk/go/filesystem">*SandboxFSOps</a></div> <div className="msb-param-desc">Filesystem accessor.</div> </div> </div> <Accordion title="Example">err := sb.FS().Write(ctx, "/tmp/hello.txt", []byte("hi"))
func (s *Sandbox) SSH() *SandboxSSHOps
Return an SSH accessor for opening a native in-process SSH client or preparing a reusable SSH server endpoint against the running sandbox. See SSH for the API.
<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="/sdk/go/ssh">*SandboxSSHOps</a></div> <div className="msb-param-desc">SSH accessor.</div> </div> </div> <Accordion title="Example">client, err := sb.SSH().OpenClient(ctx)
func (s *Sandbox) Logs(ctx context.Context, opts LogOptions) ([]LogEntry, error)
Read persisted output from the sandbox's exec.log. Backed by an on-disk file, so it works for running and stopped sandboxes alike without guest-agent protocol traffic. The default sources are stdout and stderr; add LogSourceOutput for PTY-merged output or LogSourceSystem for runtime and kernel diagnostics. The same method exists on SandboxHandle for callers that don't want to start the sandbox first.
entries, err := sb.Logs(ctx, m.LogOptions{
Sources: []m.LogSource{m.LogSourceStdout, m.LogSourceStderr},
})
for _, e := range entries {
fmt.Printf("[%s] %s", e.Source, e.Text())
}
func (s *Sandbox) LogStream(ctx context.Context, opts LogStreamOptions) (*LogStreamHandle, error)
Start a streaming log subscription against a live sandbox. Pass LogStreamOptions{Follow: true} to keep the stream open past current EOF and pick up new entries as they are written. Close the returned *LogStreamHandle when done. Also available on SandboxHandle.
stream, err := sb.LogStream(ctx, m.LogStreamOptions{Follow: true})
if err != nil {
return err
}
defer stream.Close()
for {
entry, err := stream.Recv(ctx)
if err != nil || entry == nil {
break
}
fmt.Print(entry.Text())
}
func (s *Sandbox) Metrics(ctx context.Context) (*Metrics, error)
Get a point-in-time snapshot of the sandbox's resource usage: CPU, memory, disk I/O, network I/O, optional upper-disk usage, and uptime.
<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#metrics">*Metrics</a></div> <div className="msb-param-desc">Resource snapshot.</div> </div> </div> <Accordion title="Example">metrics, err := sb.Metrics(ctx)
fmt.Printf("cpu %.1f%% · mem %d MiB\n",
metrics.CPUPercent, metrics.MemoryBytes/(1<<20))
func (s *Sandbox) MetricsStream(ctx context.Context, interval time.Duration) (*MetricsStreamHandle, error)
Start a streaming metrics subscription that delivers a Metrics snapshot every interval. Sub-millisecond precision is rounded up; a zero or negative value uses the runtime minimum (~1 ms). Close the returned *MetricsStreamHandle when done.
stream, err := sb.MetricsStream(ctx, 500*time.Millisecond)
if err != nil {
return err
}
defer stream.Close()
for {
metrics, err := stream.Recv(ctx)
if err != nil || metrics == nil {
break
}
fmt.Printf("CPU: %.1f%%\n", metrics.CPUPercent)
}
func (s *Sandbox) Attach(ctx context.Context, cmd string, args ...string) (int, error)
Bridge the caller's terminal to a process inside the sandbox for a fully interactive PTY session. Blocks until the process exits and returns its exit code. The caller's terminal must be a real TTY, so this is primarily useful for CLI tools, not library code.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>cmd</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Command to run.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>args</code><span className="msb-type">...string</span></div> <div className="msb-param-desc">Command arguments.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">int</span></div> <div className="msb-param-desc">Exit code of the process.</div> </div> </div>func (s *Sandbox) AttachShell(ctx context.Context) (int, error)
Attach to the sandbox's default shell (configured via WithShell, defaults to /bin/sh). Blocks until the shell exits and returns its exit code.
func (s *Sandbox) Stop(ctx context.Context, opts ...StopOption) error
Gracefully shut down the sandbox and wait until stopped state is observed. Lets the workload finish writing any pending data to disk before it exits. Defaults to a ten-second graceful window before force-kill; pass WithStopTimeout to change it.
err := sb.Stop(ctx, m.WithStopTimeout(30*time.Second))
func (s *Sandbox) RequestStop(ctx context.Context) error
Request graceful shutdown and return once the request is sent, without waiting for the sandbox to reach stopped state. Pair with WaitUntilStopped to await termination.
func (s *Sandbox) Kill(ctx context.Context, opts ...KillOption) error
Force-terminate the sandbox with SIGKILL and wait until stopped state is observed. No graceful shutdown, so pending writes the workload hasn't fsync'd may be lost. Prefer Stop for graceful shutdown. Defaults to a five-second observation window; pass WithKillTimeout to change it.
err := sb.Kill(ctx)
func (s *Sandbox) RequestKill(ctx context.Context) error
Request force termination and return once the request is sent, without waiting for the sandbox to reach stopped state.
func (s *Sandbox) RequestDrain(ctx context.Context) error
Request a graceful drain and return once the request is sent. Existing commands run to completion while new exec calls are rejected; the sandbox transitions to stopped when all in-flight commands finish. Useful for zero-downtime rotation of worker sandboxes.
func (s *Sandbox) WaitUntilStopped(ctx context.Context) (*SandboxStopResult, error)
Block until the sandbox is observed in a terminal state, then return how it ended.
<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#sandboxstopresult">*SandboxStopResult</a></div> <div className="msb-param-desc">Terminal status, exit code, and signal.</div> </div> </div> <Accordion title="Example">result, err := sb.WaitUntilStopped(ctx)
fmt.Printf("ended as %s\n", result.Status)
func (s *Sandbox) Detach(ctx context.Context) error
Release the Rust-side handle without stopping the VM. Use on sandboxes created with WithDetached once the caller is done with the handle but the sandbox should keep running in the background. After Detach, the handle is invalid; a subsequent Close returns an error with Kind == ErrInvalidHandle. Reconnect later with GetSandbox.
err := sb.Detach(ctx) // keeps running in the background
func (s *Sandbox) Close() error
Release the Rust-side handle. Safe to call multiple times; the second call returns an error with Kind == ErrInvalidHandle. For a sandbox created with WithDetached, Close stops the VM, use Detach instead to leave it running.
defer sb.Close()
func (s *Sandbox) OwnsLifecycle() (bool, error)
Report whether this handle owns the VM process. When true, closing or stopping the handle terminates the sandbox (attached mode); false means it is detached. The error return covers stale handles and FFI failures; use OwnsLifecycleOrFalse when you don't care.
func (s *Sandbox) OwnsLifecycleOrFalse() bool
Convenience wrapper around OwnsLifecycle that swallows the error and returns false on any failure. Suitable for log lines and best-effort branching.
Functional options for CreateSandbox. Map and slice options merge across repeated calls; single-value setters like WithImage replace. Simple setters are demonstrated by the Typical flow above.
func WithImage(image string) SandboxOption
Set the root filesystem source: an OCI image name, local directory path, or disk image path (e.g. "python:3.12", "docker.io/library/alpine"). Required unless WithSnapshot is used. Use WithImageDisk when a disk-image root needs an explicit filesystem type.
func WithOCIUpperSize(mebibytes uint32) SandboxOption
Set the writable overlay upper size for an OCI image, in MiB. Valid only with an OCI image rootfs, not disk images or snapshots.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>mebibytes</code><span className="msb-type">uint32</span></div> <div className="msb-param-desc">Upper layer size in MiB.</div> </div> </div>func WithImageDisk(path string, fstype string) SandboxOption
Use a disk image as the root filesystem and optionally provide the inner filesystem type, e.g. "ext4". The disk format is inferred from the path extension (.qcow2, .raw, or .vmdk).
func WithSnapshot(pathOrName string) SandboxOption
Boot from a snapshot artifact by bare name or filesystem path. Mutually exclusive with WithImage. See Snapshots.
func WithMemory(mebibytes uint32) SandboxOption
Set the guest memory limit in MiB. This is a limit, not an upfront reservation. Default: 512 MiB.
func WithCPUs(cpus uint8) SandboxOption
Set the number of virtual CPUs. This is a limit, not a reservation. Default: 1.
func WithWorkdir(path string) SandboxOption
Set the default working directory for all commands.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Absolute path inside the guest.</div> </div> </div>func WithShell(shell string) SandboxOption
Set the shell used by Shell and AttachShell. Defaults to /bin/sh on most images.
func WithSecurityProfile(profile SecurityProfile) SandboxOption
Set the in-guest security profile. SecurityProfileRestricted applies stronger hardening: sets no_new_privs, drops mount-admin capability from user commands, and forces nosuid,nodev on user mounts.
func WithEnv(env map[string]string) SandboxOption
Set environment variables visible to all commands. Called repeatedly, the maps merge; later keys overwrite earlier ones.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>env</code><span className="msb-type">map[string]string</span></div> <div className="msb-param-desc">Environment variables.</div> </div> </div>func WithLabels(labels map[string]string) SandboxOption
Attach labels to the sandbox for metrics attribution and ListSandboxesWith filtering. Called repeatedly, the maps merge; later keys overwrite earlier ones. Keys must not use the reserved prefixes sandbox., microsandbox., or service..
func WithLabel(key, value string) SandboxOption
Attach a single label. Shorthand for WithLabels with one entry.
func WithHostname(hostname string) SandboxOption
Set the guest hostname.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>hostname</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Hostname.</div> </div> </div>func WithUser(user string) SandboxOption
Set the default guest user (UID or name) for all commands.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>user</code><span className="msb-type">string</span></div> <div className="msb-param-desc">User name or UID.</div> </div> </div>func WithReplace() SandboxOption
Replace any existing sandbox with the same name. Sends SIGTERM, waits up to 10s for graceful exit, then escalates to SIGKILL. Without this, creation fails on name conflict. Use WithReplaceWithTimeout to set a different window.
func WithReplaceWithTimeout(timeout time.Duration) SandboxOption
Like WithReplace but with a caller-specified timeout between SIGTERM and SIGKILL. Implies WithReplace, calling this alone is enough. A zero duration skips SIGTERM and SIGKILLs immediately.
func WithDetached() SandboxOption
Create the sandbox in detached mode. The VM continues running after the Go process exits; reattach via GetSandbox. Note that Close stops a detached sandbox, use Detach to leave it running.
func WithEphemeral(ephemeral bool) SandboxOption
Mark whether the runtime should remove the sandbox's DB row, on-disk state, logs, and captured output after it reaches a terminal status.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ephemeral</code><span className="msb-type">bool</span></div> <div className="msb-param-desc"><code>true</code> to delete all state on termination.</div> </div> </div>func WithEntrypoint(cmd ...string) SandboxOption
Override the user-workload entrypoint baked into the image: the command the agent execs per request. This is the user workload, not the guest PID 1, for that, use WithInit instead.
func WithInit(cfg InitConfig) SandboxOption
Hand off PID 1 inside the guest to a custom init binary after agentd finishes boot-time setup. Construct cfg via the Init factory. See Custom init system for image picks and shutdown semantics.
sb, err := m.CreateSandbox(ctx, "worker",
m.WithImage("jrei/systemd-debian:12"),
m.WithInit(m.Init.Auto()),
)
func WithLogLevel(level LogLevel) SandboxOption
Override the sandbox process's log verbosity. See LogLevel.
func WithQuietLogs() SandboxOption
Suppress sandbox-level log output entirely.
func WithScripts(scripts map[string]string) SandboxOption
Add named scripts mounted at /.msb/scripts/<name> inside the guest. Scripts are added to PATH and can be called by name. Called repeatedly, entries merge; later names overwrite earlier ones.
func WithPullPolicy(p PullPolicy) SandboxOption
Control when the OCI image is pulled from the registry. See PullPolicy.
func WithMaxDuration(d time.Duration) SandboxOption
Cap the sandbox's total runtime. When exceeded, the sandbox is drained and stopped. Zero means unlimited. Sub-second precision is rounded up to whole seconds. Enforced on the host side.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>d</code><span className="msb-type">time.Duration</span></div> <div className="msb-param-desc">Maximum lifetime.</div> </div> </div>func WithIdleTimeout(d time.Duration) SandboxOption
Stop the sandbox after this much wall-clock time without exec activity. Zero means unlimited. Sub-second precision is rounded up to whole seconds.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>d</code><span className="msb-type">time.Duration</span></div> <div className="msb-param-desc">Idle timeout.</div> </div> </div>func WithRegistryAuth(auth RegistryAuth) SandboxOption
Set credentials for pulling from a private OCI registry. See RegistryAuth.
func WithPorts(ports map[uint16]uint16) SandboxOption
Publish guest TCP ports onto host ports (map key = host port, value = guest port). The default host bind address is 127.0.0.1. Called repeatedly, the maps merge.
func WithPortsUDP(ports map[uint16]uint16) SandboxOption
Publish guest UDP ports onto host ports. The default host bind address is 127.0.0.1.
func WithPortBindings(bindings ...PortBinding) SandboxOption
Publish ports on explicit host bind addresses, such as 0.0.0.0. See PortBinding for the type definition and UDP examples.
func WithNetwork(net *NetworkConfig) SandboxOption
Configure the network stack: preset, custom rules, DNS, and TLS interception. Build via the NetworkPolicy factory or a *NetworkConfig literal. See Networking.
sb, err := m.CreateSandbox(ctx, "api",
m.WithImage("python"),
m.WithNetwork(m.NetworkPolicy.PublicOnly()),
)
func WithSecrets(secrets ...SecretEntry) SandboxOption
Append credential secrets to the sandbox. Secrets never enter the VM; the network proxy substitutes them at the transport layer. Build entries via the Secret factory. See Secrets.
func WithPatches(patches ...PatchConfig) SandboxOption
Append rootfs patches applied before the VM boots. Patches go into the writable layer; the base image is untouched. Only compatible with OverlayFS rootfs (not disk images). Build entries via the Patch factory.
sb, err := m.CreateSandbox(ctx, "api",
m.WithImage("python"),
m.WithPatches(
m.Patch.Mkdir("/app", m.PatchOptions{}),
m.Patch.Text("/app/config.txt", "ready\n", m.PatchOptions{}),
),
)
func WithMounts(mounts map[string]MountConfig) SandboxOption
Add volume mount configurations keyed by guest path. Build values via the Mount factory. Called repeatedly, the maps merge; later entries overwrite earlier ones for the same guest path. See Volumes.
sb, err := m.CreateSandbox(ctx, "api",
m.WithImage("python"),
m.WithMounts(map[string]m.MountConfig{
"/data": m.Mount.Named("my-vol", m.MountOptions{}),
"/tmp": m.Mount.Tmpfs(m.TmpfsOptions{SizeMiB: 256}),
}),
)
func WithStopTimeout(timeout time.Duration) StopOption
Set how long Stop waits for graceful shutdown before force-killing. Default: 10 seconds. This is a StopOption, not a SandboxOption, pass it to Stop.
func WithKillTimeout(timeout time.Duration) KillOption
Set how long Kill waits for stopped-state observation. Default: 5 seconds. This is a KillOption, pass it to Kill.
func WithSkipDownload() SetupOption
Prevent EnsureInstalled from fetching the msb + libkrunfw bundle from GitHub. Use when the runtime is already on disk at the install path (e.g. air-gapped CI). The embedded FFI library is unaffected. This is a SetupOption, pass it to EnsureInstalled.
Factory that constructs rootfs patches for WithPatches. Access via the package-level Patch value. Each method returns a PatchConfig. Mkdir and Remove are idempotent; other operations error at boot when targeting a path already present in the image unless Replace: true is passed in PatchOptions. See Patches for conceptual context.
func (patchFactory) Text(path, content string, opts PatchOptions) PatchConfig
Write UTF-8 text content at path.
func (patchFactory) Append(path, content string) PatchConfig
Append content to an existing file at path. If the file lives in a lower image layer, it is copied up first.
func (patchFactory) Mkdir(path string, opts PatchOptions) PatchConfig
Create a directory. Idempotent. Only opts.Mode is honored; Replace is ignored.
func (patchFactory) Remove(path string) PatchConfig
Delete a file or directory at path. Idempotent.
func (patchFactory) Symlink(target, link string, opts PatchOptions) PatchConfig
Create a symlink at link pointing to target. Only opts.Replace is honored.
func (patchFactory) CopyFile(src, dst string, opts PatchOptions) PatchConfig
Copy a single host file at src into the guest rootfs at dst.
func (patchFactory) CopyDir(src, dst string, opts PatchOptions) PatchConfig
Recursively copy a host directory at src into the guest rootfs at dst. Only opts.Replace is honored.
Factory that constructs InitConfig values for WithInit, handing off PID 1 inside the guest after agentd setup. Access via the package-level Init value. See Custom init system for image picks and shutdown semantics.
func (initFactory) Auto() InitConfig
Use a known init at the start of the image ENTRYPOINT when present, preserving attached init-entrypoint commands; otherwise delegate to agentd to probe common init paths (/sbin/init, /lib/systemd/systemd, ...) inside the guest.
m.WithInit(m.Init.Auto())
func (initFactory) Cmd(cmd string, opts InitOptions) InitConfig
Specify the init binary explicitly with optional argv and env. cmd must be an absolute path inside the guest rootfs.
m.WithInit(m.Init.Cmd(
"/lib/systemd/systemd",
m.InitOptions{
Args: []string{"--unit=multi-user.target"},
Env: map[string]string{"container": "microsandbox"},
},
))
A lightweight reference to a sandbox's persisted state. Carries metadata (name, status, config JSON, timestamps) and offers lifecycle methods that operate on the sandbox without an active guest-agent connection. You cannot Exec or FS on a handle, call Connect or Start to upgrade to a full *Sandbox.
| Method | Returns | Description |
|---|---|---|
Name() | string | Sandbox name, up to 128 UTF-8 bytes |
Status() | SandboxStatus | Last-known lifecycle status |
ConfigJSON() | string | Raw JSON configuration |
Config() | (*SandboxConfig, error) | Parsed configuration |
CreatedAt() | time.Time | Creation time, zero value if unknown |
UpdatedAt() | time.Time | Last-update time, zero value if unknown |
Refresh(ctx) | (*SandboxHandle, error) | Fresh handle for the same name |
Metrics(ctx) | (*Metrics, error) | Point-in-time resource metrics |
Logs(ctx, opts) | ([]LogEntry, error) | Read captured exec.log (works without starting) |
LogStream(ctx, opts) | (*LogStreamHandle, error) | Stream captured output |
Connect(ctx) | (*Sandbox, error) | Reattach to the running sandbox |
Start(ctx) | (*Sandbox, error) | Boot a stopped sandbox in attached mode |
StartDetached(ctx) | (*Sandbox, error) | Boot a stopped sandbox in detached mode |
Stop(ctx, opts...) | error | Graceful shutdown; accepts StopOption |
RequestStop(ctx) | error | Async stop request |
Kill(ctx, opts...) | error | Force terminate; accepts KillOption |
RequestKill(ctx) | error | Async kill request |
RequestDrain(ctx) | error | Async drain request |
WaitUntilStopped(ctx) | (*SandboxStopResult, error) | Block until terminal state |
Remove(ctx) | error | Delete sandbox and persisted state |
Snapshot(ctx, name) | (*SnapshotArtifact, error) | Snapshot a stopped sandbox under a bare name |
SnapshotTo(ctx, path) | (*SnapshotArtifact, error) | Snapshot a stopped sandbox to an explicit path |
Narrows the results of ListSandboxesWith. The zero value matches every sandbox. Built fluently; WithLabels returns a new value so calls chain.
| Method | Returns | Description |
|---|---|---|
WithLabels(labels) | SandboxFilter | Require all of these labels (AND-matched). Repeated calls merge; later keys overwrite earlier ones |
The full configuration of a sandbox. Most callers build a sandbox via CreateSandbox(ctx, name, ...opts); SandboxConfig is exported for callers that prefer to construct a value directly.
| Field | Type | Description |
|---|---|---|
| Name | string | Sandbox name, up to 128 UTF-8 bytes |
| Image | string | OCI image, local path, or disk image |
| ImageFstype | string | Optional inner filesystem type for disk-image roots |
| OCIUpperSizeMiB | uint32 | Writable overlay upper size for OCI image roots |
| Snapshot | string | Snapshot artifact path or bare name; mutually exclusive with Image |
| MemoryMiB | uint32 | Guest memory in MiB |
| CPUs | uint8 | Virtual CPUs |
| Workdir | string | Default working directory |
| Shell | string | Shell binary used by Shell calls |
| SecurityProfile | SecurityProfile | In-guest security profile |
| Hostname | string | Guest hostname |
| User | string | Default guest user |
| Replace | bool | Replace existing sandbox with same name |
| ReplaceWithTimeout | *time.Duration | Timeout between SIGTERM and SIGKILL (implies Replace) |
| Env | map[string]string | Environment variables |
| Labels | map[string]string | Labels for metrics attribution and filtering |
| Detached | bool | If true, sandbox survives after the process exits |
| Ephemeral | bool | If true, all state is removed on termination |
| Entrypoint | []string | Override image entrypoint |
| Init | *InitConfig | Hand PID 1 off to a guest init binary |
| LogLevel | LogLevel | Sandbox log verbosity override |
| QuietLogs | bool | Suppress sandbox-level log output |
| Scripts | map[string]string | Named scripts mounted at /.msb/scripts/ |
| PullPolicy | PullPolicy | Image pull behaviour |
| MaxDuration | time.Duration | Maximum sandbox lifetime |
| IdleTimeout | time.Duration | Idle timeout |
| RegistryAuth | *RegistryAuth | Private registry credentials |
| Ports | map[uint16]uint16 | Host to guest TCP port mappings |
| PortsUDP | map[uint16]uint16 | Host to guest UDP port mappings |
| PortBindings | []PortBinding | Port mappings with explicit bind addresses |
| Network | *NetworkConfig | Network policy and configuration |
| Secrets | []SecretEntry | Secret injection entries |
| Patches | []PatchConfig | Rootfs modifications applied before boot |
| Volumes | map[string]MountConfig | Volume mounts keyed by guest path |
type SandboxOption func(*SandboxConfig)
A functional option for CreateSandbox. Every WithX helper in the Options section returns one. The lifecycle setters WithStopTimeout and WithKillTimeout return distinct StopOption / KillOption types passed to Stop and Kill instead.
Point-in-time resource usage snapshot.
| Field | Type | Description |
|---|---|---|
| CPUPercent | float64 | CPU usage as a percentage |
| VCPUTimeNs | uint64 | Cumulative vCPU time in nanoseconds |
| MemoryBytes | uint64 | Current memory usage in bytes |
| MemoryAvailableBytes | *uint64 | Guest-reported available memory when known |
| MemoryHostResidentBytes | *uint64 | Host RSS backing the guest when known |
| MemoryLimitBytes | uint64 | Memory limit in bytes |
| DiskReadBytes | uint64 | Total bytes read from disk since boot |
| DiskWriteBytes | uint64 | Total bytes written to disk since boot |
| NetRxBytes | uint64 | Total bytes received over the network since boot |
| NetTxBytes | uint64 | Total bytes sent over the network since boot |
| UpperUsedBytes | *uint64 | Guest-visible OCI upper filesystem used bytes when the protected reporter is available and fresh |
| UpperFreeBytes | *uint64 | Guest-visible OCI upper filesystem free bytes when the protected reporter is available and fresh |
| UpperHostAllocatedBytes | *uint64 | Host-allocated bytes for the writable OCI upper image when available |
| Uptime | time.Duration | Time since the sandbox was created |
Live metrics subscription. Call Close to release Rust-side resources.
| Method | Returns | Description |
|---|---|---|
Recv(ctx) | (*Metrics, error) | Block until the next snapshot arrives. Returns (nil, nil) when the stream ends (sandbox exited) |
Close() | error | Stop the stream and release Rust-side resources |
Describes a terminal sandbox state observed by WaitUntilStopped.
| Field | Type | Description |
|---|---|---|
| Name | string | Sandbox name |
| Status | SandboxStatus | Terminal status (stopped or crashed) |
| ExitCode | *int | Process exit code when known |
| Signal | *int | Terminating signal when known |
| ObservedAt | time.Time | When the terminal state was observed |
| Source | *string | Origin of the stop observation when known |
type SandboxStatus string
| Constant | Value | Description |
|---|---|---|
SandboxStatusRunning | "running" | Guest agent is ready; Exec, Shell, FS work |
SandboxStatusStopped | "stopped" | VM shut down; configuration persisted; can be restarted |
SandboxStatusCrashed | "crashed" | VM exited unexpectedly (kernel panic, OOM, etc.) |
SandboxStatusDraining | "draining" | Graceful shutdown in progress; existing commands finish, new ones rejected |
SandboxStatusPaused | "paused" | VM is paused |
A single captured log entry.
| Field | Type | Description |
|---|---|---|
| Source | LogSource | Origin of the captured data |
| SessionID | *uint64 | Relay-monotonic session id; nil for system entries |
| Timestamp | time.Time | Wall-clock capture time on the host |
| Data | []byte | The captured bytes |
| Cursor | string | Opaque resume token; pass to LogStreamOptions.FromCursor |
| Method | Returns | Description |
|---|---|---|
Text() | string | Captured bytes as a string |
Filters passed to Logs. The zero value returns everything for the default sources (stdout + stderr).
| Field | Type | Description |
|---|---|---|
| Tail | uint64 | Keep only the last N matching entries |
| Since | time.Time | Inclusive lower timestamp bound |
| Until | time.Time | Exclusive upper timestamp bound |
| Sources | []LogSource | Sources to include; empty = stdout + stderr. Add LogSourceOutput or LogSourceSystem for PTY-merged output or runtime/kernel diagnostics |
Configures a live log stream. The zero value reads the default sources from the beginning with follow off. Since and FromCursor are mutually exclusive.
| Field | Type | Description |
|---|---|---|
| Sources | []LogSource | Sources to include; empty = stdout + stderr + output |
| Since | time.Time | Start at the first entry with timestamp >= this; mutually exclusive with FromCursor |
| FromCursor | string | Resume strictly after the entry whose Cursor matches; mutually exclusive with Since |
| Until | time.Time | Stop at the first entry with timestamp >= this |
| Follow | bool | Keep the stream open past EOF and yield new entries as written |
Live log subscription. Call Close to release Rust-side resources.
| Method | Returns | Description |
|---|---|---|
Recv(ctx) | (*LogEntry, error) | Block until the next entry arrives. Returns (nil, nil) when the stream ends |
Close() | error | Stop the stream and release Rust-side resources |
type LogSource string
| Constant | Value | Description |
|---|---|---|
LogSourceStdout | "stdout" | Captured stdout (pipe mode, streams stayed separated) |
LogSourceStderr | "stderr" | Captured stderr (pipe mode) |
LogSourceOutput | "output" | PTY-merged stdout and stderr from a session running in pty mode |
LogSourceSystem | "system" | Synthetic lifecycle markers plus runtime/kernel diagnostic lines |
type LogLevel string
Sandbox process log verbosity.
| Constant | Value | Description |
|---|---|---|
LogLevelDefault | "" | Runtime default |
LogLevelTrace | "trace" | Most verbose, all diagnostic output |
LogLevelDebug | "debug" | Debug and higher |
LogLevelInfo | "info" | Info and higher |
LogLevelWarn | "warn" | Warnings and errors only |
LogLevelError | "error" | Errors only |
type PullPolicy string
Controls when the SDK fetches an OCI image from the registry.
| Constant | Value | Description |
|---|---|---|
PullPolicyDefault | "" | Runtime default (currently PullPolicyIfMissing) |
PullPolicyAlways | "always" | Pull every time, even if cached locally |
PullPolicyIfMissing | "if-missing" | Pull only if not already cached |
PullPolicyNever | "never" | Never pull; fail if missing |
type SecurityProfile string
Sandbox-wide in-guest security profile.
| Constant | Value | Description |
|---|---|---|
SecurityProfileDefault | "default" | Normal guest-root semantics |
SecurityProfileRestricted | "restricted" | Stronger hardening: no_new_privs, dropped mount-admin capability, forced nosuid,nodev on user mounts |
Credentials for a private OCI registry.
| Field | Type | Description |
|---|---|---|
| Username | string | Registry username |
| Password | string | Registry password |
Custom guest PID-1 init specification. Construct via the Init factory rather than building the struct directly.
| Field | Type | Description |
|---|---|---|
| Cmd | string | Absolute path inside the guest, or "auto" |
| Args | []string | Supplemental argv (argv[0] is implicitly Cmd) |
| Env | map[string]string | Extra env vars merged on top of the inherited env |
Tuning struct for Init.Cmd beyond the required cmd.
| Field | Type | Description |
|---|---|---|
| Args | []string | Supplemental argv |
| Env | map[string]string | Extra env vars |
Package-level factory namespace for InitConfig values. See the Init section for its methods.
| Method | Returns | Description |
|---|---|---|
Auto() | InitConfig | Auto-detect a guest init |
Cmd(cmd, opts) | InitConfig | Explicit init binary with argv and env |
A single rootfs patch. Construct via the Patch factory; the fields populated depend on the PatchKind.
| Field | Type | Description |
|---|---|---|
| Kind | PatchKind | Patch flavour |
| Path | string | Absolute guest path (text / append / mkdir / remove) |
| Content | string | Text content (text / append) |
| Mode | *uint32 | File or directory mode, e.g. 0o644 |
| Replace | bool | When true, overwrite an existing path at the destination |
| Src | string | Host source path (copy_file / copy_dir) |
| Dst | string | Guest destination path (copy_file / copy_dir) |
| Target | string | Symlink target |
| Link | string | Symlink path |
Tuning struct passed to Patch methods that accept a mode and replace flag.
| Field | Type | Description |
|---|---|---|
| Mode | *uint32 | File or directory mode |
| Replace | bool | Overwrite an existing path |
type PatchKind string
Discriminator for PatchConfig. Prefer the Patch factory.
| Constant | Value |
|---|---|
PatchKindText | "text" |
PatchKindAppend | "append" |
PatchKindMkdir | "mkdir" |
PatchKindRemove | "remove" |
PatchKindSymlink | "symlink" |
PatchKindCopyFile | "copy_file" |
PatchKindCopyDir | "copy_dir" |
Package-level factory namespace for PatchConfig values. See the Patch section for its methods.
| Method | Returns | Description |
|---|---|---|
Text(path, content, opts) | PatchConfig | Write UTF-8 text |
Append(path, content) | PatchConfig | Append to an existing file |
Mkdir(path, opts) | PatchConfig | Create a directory (idempotent) |
Remove(path) | PatchConfig | Delete a file or directory (idempotent) |
Symlink(target, link, opts) | PatchConfig | Create a symlink |
CopyFile(src, dst, opts) | PatchConfig | Copy a host file into the rootfs |
CopyDir(src, dst, opts) | PatchConfig | Copy a host directory into the rootfs |
type SetupOption func(*setupConfig)
A functional option for EnsureInstalled. The only helper is WithSkipDownload.