Back to Microsandbox

Sandbox

docs/sdk/go/sandbox.mdx

0.6.789.0 KB
Original Source

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".

For local sandboxes, call EnsureInstalled once at process startup. It installs the msb + libkrunfw runtime into ~/.microsandbox/ when needed, is idempotent, and surfaces runtime setup failures before the first sandbox operation. Use IsInstalled when you only need to check whether the runtime is already present.

<p className="msb-label" id="typical-flow">Typical flow</p>
go
import m "github.com/superradcompany/microsandbox/sdk/go"

if err := m.EnsureInstalled(ctx); err != nil {      // 1. prepare local runtime
    return err
}

sb, err := m.CreateSandbox(ctx, "api",              // 2. configure + boot
    m.WithImage("python"),
    m.WithMemory(1024),
)
if err != nil {
    return err
}
defer sb.Close()                                    // 5. release handle

out, err := sb.Exec(ctx, "python", []string{"-V"})  // 3. run
if err != nil {
    return err
}
fmt.Println(out.Stdout())                           // 4. read output

Functions

<span className="msb-recv">m.</span><span className="msb-hn">CreateSandbox()</span>

go
func CreateSandbox(ctx context.Context, name string, opts ...SandboxOption) (*Sandbox, error)
<Accordion title="Example">
go
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()
}()
</Accordion>

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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the boot operation only. Cancelling after this function returns has no effect on the running sandbox.</div> </div> <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 className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#options">...SandboxOption</a></div> <div className="msb-param-desc">Functional options applied in order.</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. Safe for concurrent use from multiple goroutines.</div> </div> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc">Typed <code>*Error</code>, see <a href="/sdk/errors">Error Handling</a>.</div> </div> </div>

<span className="msb-recv">m.</span><span className="msb-hn">GetSandbox()</span>

go
func GetSandbox(ctx context.Context, name string) (*SandboxHandle, error)
<Accordion title="Example">
go
h, err := m.GetSandbox(ctx, "api")
if err != nil {
    return err
}
fmt.Println(h.Status())
</Accordion>

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, Ping, Touch, Metrics, Logs, and snapshot methods.

<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> <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">Metadata handle with status and lifecycle control.</div> </div> </div>

<span className="msb-recv">m.</span><span className="msb-hn">ListSandboxes()</span>

go
func ListSandboxes(ctx context.Context) ([]*SandboxHandle, error)
<Accordion title="Example">
go
handles, err := m.ListSandboxes(ctx)
if err != nil {
    return err
}
for _, h := range handles {
    fmt.Printf("%s - %s\n", h.Name(), h.Status())
}
</Accordion>

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>

<span className="msb-recv">m.</span><span className="msb-hn">ListSandboxesWith()</span>

go
func ListSandboxesWith(ctx context.Context, filter SandboxFilter) ([]*SandboxHandle, error)
<Accordion title="Example">
go
filter := m.NewSandboxFilter().WithLabels(map[string]string{"user.id": "alice"})
handles, err := m.ListSandboxesWith(ctx, filter)
</Accordion>

Return sandbox metadata narrowed by a SandboxFilter. Label selectors are AND-matched: a sandbox matches only if it carries every label in the filter.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>filter</code><a className="msb-type" href="#sandboxfilter">SandboxFilter</a></div> <div className="msb-param-desc">Label selector. The zero value matches every sandbox.</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="#sandboxhandle">[]*SandboxHandle</a></div> <div className="msb-param-desc">Matching sandbox handles.</div> </div> </div>

<span className="msb-recv">m.</span><span className="msb-hn">NewSandboxFilter()</span>

go
func NewSandboxFilter() SandboxFilter

Return an empty SandboxFilter that matches every sandbox. Chain WithLabels to narrow the results passed to ListSandboxesWith.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#sandboxfilter">SandboxFilter</a></div> <div className="msb-param-desc">Empty filter.</div> </div> </div>

<span className="msb-recv">m.</span><span className="msb-hn">StartSandbox()</span>

go
func StartSandbox(ctx context.Context, name string) (*Sandbox, error)
<Accordion title="Example">
go
sb, err := m.StartSandbox(ctx, "api")
</Accordion>

Restart a previously stopped sandbox. The VM reboots using the persisted configuration and returns a live *Sandbox.

<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.</div> </div> </div>

<span className="msb-recv">m.</span><span className="msb-hn">StartSandboxDetached()</span>

go
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>

<span className="msb-recv">m.</span><span className="msb-hn">RemoveSandbox()</span>

go
func RemoveSandbox(ctx context.Context, name string) error
<Accordion title="Example">
go
err := m.RemoveSandbox(ctx, "api")
</Accordion>

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>

<span className="msb-recv">m.</span><span className="msb-hn">AllSandboxMetrics()</span>

go
func AllSandboxMetrics(ctx context.Context) (map[string]*Metrics, error)
<Accordion title="Example">
go
all, err := m.AllSandboxMetrics(ctx)
for name, metrics := range all {
    fmt.Printf("%s: %.1f%% CPU\n", name, metrics.CPUPercent)
}
</Accordion>

Return a point-in-time Metrics snapshot for every running sandbox, keyed by sandbox name. Only running and draining sandboxes appear.

<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">map[string]*Metrics</a></div> <div className="msb-param-desc">Per-sandbox metrics keyed by name.</div> </div> </div>

<span className="msb-recv">m.</span><span className="msb-hn">EnsureInstalled()</span>

go
func EnsureInstalled(ctx context.Context, opts ...SetupOption) error
<Accordion title="Example">
go
if err := m.EnsureInstalled(ctx); err != nil {
    log.Fatalf("microsandbox setup: %v", err)
}
</Accordion>

Ensure msb + libkrunfw are present under ~/.microsandbox/ (%USERPROFILE%\.microsandbox on Windows), downloading them from the matching GitHub release if needed. Call this at process startup when the program will create local sandboxes so runtime download/setup failures surface before the first sandbox operation. The Go FFI library is embedded in the Go binary and loads automatically on first use; EnsureInstalled only governs the msb + libkrunfw runtime install. Idempotent; options apply only to the first call.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels an in-flight msb + libkrunfw download.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#setupoption">...SetupOption</a></div> <div className="msb-param-desc">Install knobs, e.g. <a href="#withskipdownload">WithSkipDownload()</a>.</div> </div> </div>

<span className="msb-recv">m.</span><span className="msb-hn">IsInstalled()</span>

go
func IsInstalled() bool

Report whether msb + libkrunfw are present on disk at the SDK's pinned version. Use this when you only need to check whether the runtime is already available at the SDK install location. 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>

<span className="msb-recv">m.</span><span className="msb-hn">SDKVersion()</span>

go
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 for this SDK build.</div> </div> </div>

<span className="msb-recv">m.</span><span className="msb-hn">RuntimeVersion()</span>

go
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).

<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">FFI library version.</div> </div> </div>

Methods

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.

<span className="msb-recv">sb.</span><span className="msb-hn">Name()</span>

go
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>

<span className="msb-recv">sb.</span><span className="msb-hn">FS()</span>

go
func (s *Sandbox) FS() *SandboxFSOps
<Accordion title="Example">
go
err := sb.FS().Write(ctx, "/tmp/hello.txt", []byte("hi"))
</Accordion>

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>

<span className="msb-recv">sb.</span><span className="msb-hn">SSH()</span>

go
func (s *Sandbox) SSH() *SandboxSSHOps
<Accordion title="Example">
go
client, err := sb.SSH().OpenClient(ctx)
</Accordion>

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>

<span className="msb-recv">sb.</span><span className="msb-hn">Logs()</span>

go
func (s *Sandbox) Logs(ctx context.Context, opts LogOptions) ([]LogEntry, error)
<Accordion title="Example">
go
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())
}
</Accordion>

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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#logoptions">LogOptions</a></div> <div className="msb-param-desc">Filters: <code>Tail</code>, <code>Since</code>, <code>Until</code>, <code>Sources</code>. The zero value returns everything for the default stdout and stderr sources.</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="#logentry">[]LogEntry</a></div> <div className="msb-param-desc">Matching entries in chronological order.</div> </div> </div>

<span className="msb-recv">sb.</span><span className="msb-hn">LogStream()</span>

go
func (s *Sandbox) LogStream(ctx context.Context, opts LogStreamOptions) (*LogStreamHandle, error)
<Accordion title="Example">
go
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())
}
</Accordion>

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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#logstreamoptions">LogStreamOptions</a></div> <div className="msb-param-desc">Sources, follow mode, and a <code>Since</code> or <code>FromCursor</code> start point.</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="#logstreamhandle">*LogStreamHandle</a></div> <div className="msb-param-desc">Live subscription; call <code>Recv</code> in a loop.</div> </div> </div>

<span className="msb-recv">sb.</span><span className="msb-hn">Ping()</span>

go
func (s *Sandbox) Ping(ctx context.Context) (*SandboxPingResult, error)
<Accordion title="Example">
go
health, err := sb.Ping(ctx)
if err != nil {
    return err
}
fmt.Printf("%s: %s\n", health.Name, health.Latency)
</Accordion>

Check that the running sandbox's guest agent is reachable without refreshing idle activity. This sends core.ping and waits for core.pong; it does not start stopped sandboxes and returns an error if the sandbox is not running or agentd cannot respond. After upgrading from a runtime that predates protocol generation 6, restart already-running sandboxes so the guest agent understands the message.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#sandboxpingresult">*SandboxPingResult</a></div> <div className="msb-param-desc">Sandbox name and agent round-trip latency.</div> </div> </div>

<span className="msb-recv">sb.</span><span className="msb-hn">Touch()</span>

go
func (s *Sandbox) Touch(ctx context.Context) (*SandboxTouchResult, error)
<Accordion title="Example">
go
keepalive, err := sb.Touch(ctx)
if err != nil {
    return err
}
fmt.Printf("%s: %d\n", keepalive.Name, keepalive.ActivitySeq)
</Accordion>

Explicitly refresh the running sandbox's idle activity. This sends core.touch, receives core.touched, and advances the guest activity sequence used by the runtime idle-timeout monitor. It does not start stopped sandboxes and it does not bypass MaxDuration.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#sandboxtouchresult">*SandboxTouchResult</a></div> <div className="msb-param-desc">Sandbox name and updated activity sequence.</div> </div> </div>

<span className="msb-recv">sb.</span><span className="msb-hn">Modify()</span>

go
func (s *Sandbox) Modify(ctx context.Context, opts ModifyOptions) (*SandboxModificationPlan, error)
<Accordion title="Example">
go
// Live resize: applies to the running VM when within the booted capacity
plan, err := sb.Modify(ctx, m.ModifyOptions{CPUs: 4, MemoryMiB: 4096})
if err != nil {
    return err
}
for _, r := range plan.ResizeStatus {
    fmt.Printf("%s: %s -> %s (%s)\n", r.Resource, r.Requested, r.Actual, r.State)
}

// Preview a change without applying it
preview, err := sb.Modify(ctx, m.ModifyOptions{MaxMemoryMiB: 16384, DryRun: true})
if err != nil {
    return err
}
for _, c := range preview.Changes {
    fmt.Printf("%s: %s\n", c.Field, c.Disposition)
}

// Make an env change active now by restarting
_, err = sb.Modify(ctx, m.ModifyOptions{
    Env:    map[string]string{"MODE": "prod"},
    Policy: m.ModificationPolicyRestart,
})
</Accordion>

Plan or apply a configuration change. The returned plan labels each change "live", "next start", "requires restart", or "unsupported", and apply is all-or-nothing.

CPUs and MemoryMiB resize live within the WithMaxCPUs / WithMaxMemory ceilings; raising a ceiling requires a restart. Env and workdir changes affect future execs only. On a stopped sandbox, changes are saved for the next boot.

Secret changes are Rust-SDK and CLI only for now. The CLI equivalent is msb modify.

A live CPU or memory resize can take a moment to settle. The new limits are enforced immediately, and the returned plan's ResizeStatus reports when the sandbox has finished adjusting. See SandboxModificationPlan.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#modifyoptions">ModifyOptions</a></div> <div className="msb-param-desc">Requested changes plus <code>Policy</code> and <code>DryRun</code>. Zero-valued fields are left unchanged.</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="#sandboxmodificationplan">*SandboxModificationPlan</a></div> <div className="msb-param-desc">The modification plan, applied unless <code>DryRun</code> is set.</div> </div> </div>

<span className="msb-recv">sb.</span><span className="msb-hn">Metrics()</span>

go
func (s *Sandbox) Metrics(ctx context.Context) (*Metrics, error)
<Accordion title="Example">
go
metrics, err := sb.Metrics(ctx)
fmt.Printf("cpu %.1f%% · mem %d MiB\n",
    metrics.CPUPercent, metrics.MemoryBytes/(1<<20))
</Accordion>

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>

<span className="msb-recv">sb.</span><span className="msb-hn">MetricsStream()</span>

go
func (s *Sandbox) MetricsStream(ctx context.Context, interval time.Duration) (*MetricsStreamHandle, error)
<Accordion title="Example">
go
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)
}
</Accordion>

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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>interval</code><span className="msb-type">time.Duration</span></div> <div className="msb-param-desc">Time between snapshots.</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="#metricsstreamhandle">*MetricsStreamHandle</a></div> <div className="msb-param-desc">Live subscription; call <code>Recv</code> in a loop.</div> </div> </div>

<span className="msb-recv">sb.</span><span className="msb-hn">Attach()</span>

go
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>

<span className="msb-recv">sb.</span><span className="msb-hn">AttachShell()</span>

go
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.

<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 shell.</div> </div> </div>

<span className="msb-recv">sb.</span><span className="msb-hn">Stop()</span>

go
func (s *Sandbox) Stop(ctx context.Context, opts ...StopOption) error
<Accordion title="Example">
go
err := sb.Stop(ctx, m.WithStopTimeout(30*time.Second))
</Accordion>

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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#withstoptimeout">...StopOption</a></div> <div className="msb-param-desc">Graceful shutdown window, e.g. <code>WithStopTimeout(30 * time.Second)</code>.</div> </div> </div>

<span className="msb-recv">sb.</span><span className="msb-hn">RequestStop()</span>

go
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.

<span className="msb-recv">sb.</span><span className="msb-hn">Kill()</span>

go
func (s *Sandbox) Kill(ctx context.Context, opts ...KillOption) error
<Accordion title="Example">
go
err := sb.Kill(ctx)
</Accordion>

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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#withkilltimeout">...KillOption</a></div> <div className="msb-param-desc">Stopped-state observation window.</div> </div> </div>

<span className="msb-recv">sb.</span><span className="msb-hn">RequestKill()</span>

go
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.

<span className="msb-recv">sb.</span><span className="msb-hn">RequestDrain()</span>

go
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.

<span className="msb-recv">sb.</span><span className="msb-hn">WaitUntilStopped()</span>

go
func (s *Sandbox) WaitUntilStopped(ctx context.Context) (*SandboxStopResult, error)
<Accordion title="Example">
go
result, err := sb.WaitUntilStopped(ctx)
fmt.Printf("ended as %s\n", result.Status)
</Accordion>

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>

<span className="msb-recv">sb.</span><span className="msb-hn">Detach()</span>

go
func (s *Sandbox) Detach(ctx context.Context) error
<Accordion title="Example">
go
err := sb.Detach(ctx) // keeps running in the background
</Accordion>

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.

<span className="msb-recv">sb.</span><span className="msb-hn">Close()</span>

go
func (s *Sandbox) Close() error
<Accordion title="Example">
go
defer sb.Close()
</Accordion>

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.

<span className="msb-recv">sb.</span><span className="msb-hn">OwnsLifecycle()</span>

go
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.

<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 attached.</div> </div> </div>

<span className="msb-recv">sb.</span><span className="msb-hn">OwnsLifecycleOrFalse()</span>

go
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.

<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 attached, <code>false</code> on detach or error.</div> </div> </div>

Options

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.

<span className="msb-recv"></span><span className="msb-hn">WithImage()</span>

go
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 WithFromSnapshot is used. Use WithImageDisk when a disk-image root needs an explicit filesystem type.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>image</code><span className="msb-type">string</span></div> <div className="msb-param-desc">OCI image, local path, or disk image.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithOCIUpperSize()</span>

go
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>

<span className="msb-recv"></span><span className="msb-hn">WithImageDisk()</span>

go
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).

<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">Host path to the disk image.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>fstype</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Inner filesystem hint, empty to auto-detect.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithFromSnapshot()</span>

<div className="msb-tags"><span className="msb-tag is-builder">option</span></div>
go
func WithFromSnapshot(pathOrName string) SandboxOption

Boot from a snapshot artifact by bare name or filesystem path. Mutually exclusive with WithImage. See Snapshots.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>pathOrName</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Snapshot artifact path or bare name.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithMemory()</span>

go
func WithMemory(mebibytes uint32) SandboxOption

Set the guest memory limit in MiB. This is a limit, not an upfront reservation. Default: 512 MiB.

<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">Memory in MiB.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithMaxMemory()</span>

go
func WithMaxMemory(mebibytes uint32) SandboxOption

Set the boot-time maximum hotpluggable guest memory in MiB. This reserves the envelope a sandbox can use after restart-backed changes and future live memory activation; it does not increase the effective memory by itself.

<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">Maximum memory in MiB.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithCPUs()</span>

go
func WithCPUs(cpus uint8) SandboxOption

Set the number of virtual CPUs. This is a limit, not a reservation. Default: 1.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>cpus</code><span className="msb-type">uint8</span></div> <div className="msb-param-desc">Number of vCPUs.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithMaxCPUs()</span>

go
func WithMaxCPUs(cpus uint8) SandboxOption

Set the boot-time maximum possible virtual CPU capacity. This reserves the envelope a sandbox can use after restart-backed changes and future live CPU activation; it does not increase the effective vCPU count by itself.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>cpus</code><span className="msb-type">uint8</span></div> <div className="msb-param-desc">Maximum possible vCPUs.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithWorkdir()</span>

go
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>

<span className="msb-recv"></span><span className="msb-hn">WithShell()</span>

go
func WithShell(shell string) SandboxOption

Set the shell used by Shell and AttachShell. Defaults to /bin/sh on most images.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>shell</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Shell path, e.g. <code>"/bin/bash"</code>.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithSecurityProfile()</span>

go
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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>profile</code><a className="msb-type" href="#securityprofile">SecurityProfile</a></div> <div className="msb-param-desc">Security profile.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithEnv()</span>

go
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>

<span className="msb-recv"></span><span className="msb-hn">WithLabels()</span>

go
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..

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>labels</code><span className="msb-type">map[string]string</span></div> <div className="msb-param-desc">Label key-value pairs.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithLabel()</span>

go
func WithLabel(key, value string) SandboxOption

Attach a single label. Shorthand for WithLabels with one entry.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>key</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Label key.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>value</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Label value.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithHostname()</span>

go
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>

<span className="msb-recv"></span><span className="msb-hn">WithUser()</span>

go
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>

<span className="msb-recv"></span><span className="msb-hn">WithReplace()</span>

go
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.

<span className="msb-recv"></span><span className="msb-hn">WithReplaceWithTimeout()</span>

go
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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>timeout</code><span className="msb-type">time.Duration</span></div> <div className="msb-param-desc">Grace period before SIGKILL.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithDetached()</span>

go
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.

<span className="msb-recv"></span><span className="msb-hn">WithEphemeral()</span>

go
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>

<span className="msb-recv"></span><span className="msb-hn">WithEntrypoint()</span>

go
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.

<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">Entrypoint command and arguments.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithInit()</span>

go
func WithInit(cfg InitConfig) SandboxOption
<Accordion title="Example">
go
sb, err := m.CreateSandbox(ctx, "worker",
    m.WithImage("jrei/systemd-debian:12"),
    m.WithInit(m.Init.Auto()),
)
</Accordion>

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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>cfg</code><a className="msb-type" href="#initconfig">InitConfig</a></div> <div className="msb-param-desc">Init specification.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithLogLevel()</span>

go
func WithLogLevel(level LogLevel) SandboxOption

Override the sandbox process's log verbosity. See LogLevel.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>level</code><a className="msb-type" href="#loglevel">LogLevel</a></div> <div className="msb-param-desc">Log level.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithQuietLogs()</span>

go
func WithQuietLogs() SandboxOption

Suppress sandbox-level log output entirely.

<span className="msb-recv"></span><span className="msb-hn">WithScripts()</span>

go
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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>scripts</code><span className="msb-type">map[string]string</span></div> <div className="msb-param-desc">Script name to script content.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithPullPolicy()</span>

go
func WithPullPolicy(p PullPolicy) SandboxOption

Control when the OCI image is pulled from the registry. See PullPolicy.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>p</code><a className="msb-type" href="#pullpolicy">PullPolicy</a></div> <div className="msb-param-desc">Pull behavior.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithMaxDuration()</span>

go
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>

<span className="msb-recv"></span><span className="msb-hn">WithIdleTimeout()</span>

go
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>

<span className="msb-recv"></span><span className="msb-hn">WithRegistryAuth()</span>

go
func WithRegistryAuth(auth RegistryAuth) SandboxOption

Set credentials for pulling from a private OCI registry. See RegistryAuth.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>auth</code><a className="msb-type" href="#registryauth">RegistryAuth</a></div> <div className="msb-param-desc">Registry credentials.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithPorts()</span>

go
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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ports</code><span className="msb-type">map[uint16]uint16</span></div> <div className="msb-param-desc">Host port to guest port.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithPortsUDP()</span>

go
func WithPortsUDP(ports map[uint16]uint16) SandboxOption

Publish guest UDP ports onto host ports. The default host bind address is 127.0.0.1.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ports</code><span className="msb-type">map[uint16]uint16</span></div> <div className="msb-param-desc">Host port to guest port.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithPortBindings()</span>

go
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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>bindings</code><a className="msb-type" href="/sdk/go/networking#portbinding">...PortBinding</a></div> <div className="msb-param-desc">Explicit bind-address port mappings.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithNetwork()</span>

go
func WithNetwork(net *NetworkConfig) SandboxOption
<Accordion title="Example">
go
sb, err := m.CreateSandbox(ctx, "api",
    m.WithImage("python"),
    m.WithNetwork(m.NetworkPolicy.FromProfiles(m.NetworkProfilePublic)),
)
</Accordion>

Configure the network stack: profiles, custom rules, DNS, and TLS interception. Build via the NetworkPolicy factory or a *NetworkConfig literal. See Networking.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>net</code><a className="msb-type" href="/sdk/go/networking#networkconfig">*NetworkConfig</a></div> <div className="msb-param-desc">Network configuration.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithSecrets()</span>

go
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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>secrets</code><a className="msb-type" href="/sdk/go/secrets#secretentry">...SecretEntry</a></div> <div className="msb-param-desc">Secret injection entries.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithPatches()</span>

go
func WithPatches(patches ...PatchConfig) SandboxOption
<Accordion title="Example">
go
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{}),
    ),
)
</Accordion>

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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>patches</code><a className="msb-type" href="#patchconfig">...PatchConfig</a></div> <div className="msb-param-desc">Ordered rootfs patches.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithMounts()</span>

go
func WithMounts(mounts map[string]MountConfig) SandboxOption
<Accordion title="Example">
go
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}),
    }),
)
</Accordion>

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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>mounts</code><span className="msb-type">map[string]MountConfig</span></div> <div className="msb-param-desc">Guest path to mount config.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithStopTimeout()</span>

go
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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>timeout</code><span className="msb-type">time.Duration</span></div> <div className="msb-param-desc">Graceful shutdown window.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithKillTimeout()</span>

go
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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>timeout</code><span className="msb-type">time.Duration</span></div> <div className="msb-param-desc">Observation window.</div> </div> </div>

<span className="msb-recv"></span><span className="msb-hn">WithSkipDownload()</span>

go
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.

Patch

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.

<span className="msb-recv">Patch.</span><span className="msb-hn">Text()</span>

go
func (patchFactory) Text(path, content string, opts PatchOptions) PatchConfig

Write UTF-8 text content at path.

<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 className="msb-param"> <div className="msb-param-key"><code>content</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Text content.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#patchoptions">PatchOptions</a></div> <div className="msb-param-desc"><code>Mode</code> and <code>Replace</code>.</div> </div> </div>

<span className="msb-recv">Patch.</span><span className="msb-hn">Append()</span>

go
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.

<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 className="msb-param"> <div className="msb-param-key"><code>content</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Text to append.</div> </div> </div>

<span className="msb-recv">Patch.</span><span className="msb-hn">Mkdir()</span>

go
func (patchFactory) Mkdir(path string, opts PatchOptions) PatchConfig

Create a directory. Idempotent. Only opts.Mode is honored; Replace is ignored.

<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 className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#patchoptions">PatchOptions</a></div> <div className="msb-param-desc">Only <code>Mode</code> applies.</div> </div> </div>

<span className="msb-recv">Patch.</span><span className="msb-hn">Remove()</span>

go
func (patchFactory) Remove(path string) PatchConfig

Delete a file or directory at path. Idempotent.

<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>

<span className="msb-recv">Patch.</span><span className="msb-hn">Symlink()</span>

go
func (patchFactory) Symlink(target, link string, opts PatchOptions) PatchConfig

Create a symlink at link pointing to target. Only opts.Replace is honored.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>target</code><span className="msb-type">string</span></div> <div className="msb-param-desc">What the symlink points to.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>link</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Absolute path of the symlink itself.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#patchoptions">PatchOptions</a></div> <div className="msb-param-desc">Only <code>Replace</code> applies.</div> </div> </div>

<span className="msb-recv">Patch.</span><span className="msb-hn">CopyFile()</span>

go
func (patchFactory) CopyFile(src, dst string, opts PatchOptions) PatchConfig

Copy a single host file at src into the guest rootfs at dst.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>src</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Host source file.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>dst</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Absolute destination path inside the guest.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#patchoptions">PatchOptions</a></div> <div className="msb-param-desc"><code>Mode</code> and <code>Replace</code>.</div> </div> </div>

<span className="msb-recv">Patch.</span><span className="msb-hn">CopyDir()</span>

go
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.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>src</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Host source directory.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>dst</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Absolute destination path inside the guest.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#patchoptions">PatchOptions</a></div> <div className="msb-param-desc">Only <code>Replace</code> applies.</div> </div> </div>

Init

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.

<span className="msb-recv">Init.</span><span className="msb-hn">Auto()</span>

go
func (initFactory) Auto() InitConfig
<Accordion title="Example">
go
m.WithInit(m.Init.Auto())
</Accordion>

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.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#initconfig">InitConfig</a></div> <div className="msb-param-desc">Auto-detect init config.</div> </div> </div>

<span className="msb-recv">Init.</span><span className="msb-hn">Cmd()</span>

go
func (initFactory) Cmd(cmd string, opts InitOptions) InitConfig
<Accordion title="Example">
go
m.WithInit(m.Init.Cmd(
    "/lib/systemd/systemd",
    m.InitOptions{
        Args: []string{"--unit=multi-user.target"},
        Env:  map[string]string{"container": "microsandbox"},
    },
))
</Accordion>

Specify the init binary explicitly with optional argv and env. cmd must be an absolute path inside the guest rootfs.

<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">Absolute path to the init binary inside the guest.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#initoptions">InitOptions</a></div> <div className="msb-param-desc">Argv and env.</div> </div> </div>

Types

SandboxHandle

<p className="msb-backref">Returned by <a href="#m-getsandbox">GetSandbox()</a> · <a href="#m-listsandboxes">ListSandboxes()</a> · <a href="#m-listsandboxeswith">ListSandboxesWith()</a></p>

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.

MethodReturnsDescription
Name()stringSandbox name, up to 128 UTF-8 bytes
Status()SandboxStatusLast-known lifecycle status
ConfigJSON()stringRaw JSON configuration
Config()(*SandboxConfig, error)Parsed configuration
CreatedAt()time.TimeCreation time, zero value if unknown
UpdatedAt()time.TimeLast-update time, zero value if unknown
Refresh(ctx)(*SandboxHandle, error)Fresh handle for the same name
Ping(ctx)(*SandboxPingResult, error)Check agent reachability without refreshing idle activity; does not start stopped sandboxes
Touch(ctx)(*SandboxTouchResult, error)Explicitly refresh idle activity; does not start stopped sandboxes
Modify(ctx, opts)(*SandboxModificationPlan, error)Plan or apply a configuration change; same ModifyOptions as Modify(). Does not start stopped sandboxes; changes persist for the next boot
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...)errorGraceful shutdown; accepts StopOption
RequestStop(ctx)errorAsync stop request
Kill(ctx, opts...)errorForce terminate; accepts KillOption
RequestKill(ctx)errorAsync kill request
RequestDrain(ctx)errorAsync drain request
WaitUntilStopped(ctx)(*SandboxStopResult, error)Block until terminal state
Remove(ctx)errorDelete sandbox and persisted state
Snapshot(ctx, name)(*SnapshotArtifact, error)Snapshot a stopped sandbox under a bare name

SandboxPingResult

<p className="msb-backref">Returned by <a href="#sb-ping">Ping()</a></p>

Agent reachability result.

FieldTypeDescription
NamestringSandbox name
Latencytime.DurationRound-trip latency

SandboxTouchResult

<p className="msb-backref">Returned by <a href="#sb-touch">Touch()</a></p>

Explicit idle-refresh result.

FieldTypeDescription
NamestringSandbox name
ActivitySequint64Monotonic activity sequence after the touch

ModifyOptions

<p className="msb-backref">Used by <a href="#sb-modify">Modify()</a></p>

A requested sandbox modification. Zero-valued fields are left unchanged (0 is not a valid CPU or memory size). Secret changes are Rust-SDK and CLI only for now.

FieldTypeDescription
CPUsuint8Desired effective vCPU count. Live when within the booted MaxCPUs
MaxCPUsuint8Boot-time maximum possible vCPUs (restart-backed)
MemoryMiBuint32Desired effective guest memory in MiB. Live when within the booted MaxMemoryMiB
MaxMemoryMiBuint32Boot-time maximum hotpluggable memory in MiB (restart-backed)
Envmap[string]stringEnvironment variables to set for future execs
EnvRemove[]stringEnvironment variable keys to remove
Labelsmap[string]stringLabels to set
LabelsRemove[]stringLabel keys to remove
WorkdirstringWorking directory for future execs
PolicyModificationPolicyModificationPolicyNoRestart (default) applies only changes that can complete without restarting; ModificationPolicyNextStart persists changes for the next start without mutating a running VM; ModificationPolicyRestart restarts if needed so restart-required changes become active now
DryRunboolCompute the plan without applying anything

SandboxModificationPlan

<p className="msb-backref">Returned by <a href="#sb-modify">Modify()</a></p>

Dry-run or apply plan for a sandbox modification. Values never appear in a plan: secret entries carry only guest-visible references.

FieldTypeDescription
SandboxstringSandbox being modified
StatusstringStatus used for classification ("running", "stopped", ...)
AppliedboolWhether the changes were applied; false for dry runs
PolicyModificationPolicyPolicy used to produce the plan
Changes[]PlannedChangePlanned changes, one entry per field or secret (see below)
Conflicts[]ModificationConflictConflicts (Field + Message) that must be resolved before the patch can apply
Warnings[]ModificationWarningNon-fatal warnings (Field + Message), e.g. the future-execs-only env caveat
ResizeStatus[]ResourceResizeStatusLive resource resize outcomes, populated by apply when a live change ran (see below)

PlannedChange is one planned entry. Kind is "config" or "secret"; config entries carry Before / After while secret entries carry Name, BeforeRef / AfterRef (guest-visible references, values are omitted by construction), and AllowHosts:

FieldTypeDescription
Kindstring"config" or "secret"
FieldstringConfig field being changed; always "secret" for secret entries
NamestringSecret name (secret entries only)
Changestring"added", "updated", or "removed" for config; "added", "rotated", "removed", "renamed", "hosts updated", or "placeholder updated" for secrets
Before / After*stringPrevious / new visible state (config entries)
BeforeRef / AfterRef*stringPrevious / new guest-visible reference (secret entries)
Dispositionstring"live", "next start", "requires restart", or "unsupported"
AllowHosts[]stringAllowed hosts after the requested change (secret entries)
Reason*stringHuman-readable reason for the classification, when useful

ResourceResizeStatus reports runtime convergence for a live resize; enforcement applies immediately, the guest converges asynchronously:

FieldTypeDescription
Resourcestring"cpus" or "memory"
RequestedstringRequested value
ActualstringActual value observed in the guest/runtime
EnforcedstringHost/VMM-enforced value
Statestring"applied" when requested, actual, and enforced match; "converging" while the guest is still onlining CPUs or plugging memory; "guest-refused" when the guest would not cooperate (the host enforces the new limit anyway); "accepted" or "failed" otherwise

SandboxFilter

<p className="msb-backref">Built by <a href="#m-newsandboxfilter">NewSandboxFilter()</a> · used by <a href="#m-listsandboxeswith">ListSandboxesWith()</a></p>

Narrows the results of ListSandboxesWith. The zero value matches every sandbox. Built fluently; WithLabels returns a new value so calls chain.

MethodReturnsDescription
WithLabels(labels)SandboxFilterRequire all of these labels (AND-matched). Repeated calls merge; later keys overwrite earlier ones

SandboxConfig

<p className="msb-backref">Populated by <a href="#options">SandboxOption</a> · parsed by <a href="#sandboxhandle">SandboxHandle.Config()</a></p>

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.

FieldTypeDescription
NamestringSandbox name, up to 128 UTF-8 bytes
ImagestringOCI image, local path, or disk image
ImageFstypestringOptional inner filesystem type for disk-image roots
OCIUpperSizeMiBuint32Writable overlay upper size for OCI image roots
SnapshotstringSnapshot artifact path or bare name; mutually exclusive with Image
MemoryMiBuint32Guest memory in MiB
CPUsuint8Virtual CPUs
MaxMemoryMiBuint32Boot-time maximum hotpluggable memory in MiB
MaxCPUsuint8Boot-time maximum possible virtual CPUs
WorkdirstringDefault working directory
ShellstringShell binary used by Shell calls
SecurityProfileSecurityProfileIn-guest security profile
HostnamestringGuest hostname
UserstringDefault guest user
ReplaceboolReplace existing sandbox with same name
ReplaceWithTimeout*time.DurationTimeout between SIGTERM and SIGKILL (implies Replace)
Envmap[string]stringEnvironment variables
Labelsmap[string]stringLabels for metrics attribution and filtering
DetachedboolIf true, sandbox survives after the process exits
EphemeralboolIf true, all state is removed on termination
Entrypoint[]stringOverride image entrypoint
Init*InitConfigHand PID 1 off to a guest init binary
LogLevelLogLevelSandbox log verbosity override
QuietLogsboolSuppress sandbox-level log output
Scriptsmap[string]stringNamed scripts mounted at /.msb/scripts/
PullPolicyPullPolicyImage pull behaviour
MaxDurationtime.DurationMaximum sandbox lifetime
IdleTimeouttime.DurationIdle timeout
RegistryAuth*RegistryAuthPrivate registry credentials
Portsmap[uint16]uint16Host to guest TCP port mappings
PortsUDPmap[uint16]uint16Host to guest UDP port mappings
PortBindings[]PortBindingPort mappings with explicit bind addresses
Network*NetworkConfigNetwork policy and configuration
Secrets[]SecretEntrySecret injection entries
Patches[]PatchConfigRootfs modifications applied before boot
Volumesmap[string]MountConfigVolume mounts keyed by guest path

SandboxOption

<p className="msb-backref">Consumed by <a href="#m-createsandbox">CreateSandbox()</a></p>
go
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.

Metrics

<p className="msb-backref">Returned by <a href="#sb-metrics">Metrics()</a> · <a href="#sb-metricsstream">MetricsStream()</a> · <a href="#m-allsandboxmetrics">AllSandboxMetrics()</a></p>

Point-in-time resource usage snapshot.

FieldTypeDescription
CPUPercentfloat64CPU usage as a percentage
VCPUTimeNsuint64Cumulative vCPU time in nanoseconds
MemoryBytesuint64Current memory usage in bytes
MemoryAvailableBytes*uint64Guest-reported available memory when known
MemoryHostResidentBytes*uint64Host RSS backing the guest when known
MemoryLimitBytesuint64Memory limit in bytes
DiskReadBytesuint64Total bytes read from disk since boot
DiskWriteBytesuint64Total bytes written to disk since boot
NetRxBytesuint64Total bytes received over the network since boot
NetTxBytesuint64Total bytes sent over the network since boot
UpperUsedBytes*uint64Guest-visible OCI upper filesystem used bytes when the protected reporter is available and fresh
UpperFreeBytes*uint64Guest-visible OCI upper filesystem free bytes when the protected reporter is available and fresh
UpperHostAllocatedBytes*uint64Host-allocated bytes for the writable OCI upper image when available
Uptimetime.DurationTime since the sandbox was created

MetricsStreamHandle

<p className="msb-backref">Returned by <a href="#sb-metricsstream">MetricsStream()</a></p>

Live metrics subscription. Call Close to release Rust-side resources.

MethodReturnsDescription
Recv(ctx)(*Metrics, error)Block until the next snapshot arrives. Returns (nil, nil) when the stream ends (sandbox exited)
Close()errorStop the stream and release Rust-side resources

SandboxStopResult

<p className="msb-backref">Returned by <a href="#sb-waituntilstopped">WaitUntilStopped()</a></p>

Describes a terminal sandbox state observed by WaitUntilStopped.

FieldTypeDescription
NamestringSandbox name
StatusSandboxStatusTerminal status (stopped or crashed)
ExitCode*intProcess exit code when known
Signal*intTerminating signal when known
ObservedAttime.TimeWhen the terminal state was observed
Source*stringOrigin of the stop observation when known

SandboxStatus

<p className="msb-backref">Used by <a href="#sandboxhandle">SandboxHandle.Status()</a> · <a href="#sandboxstopresult">SandboxStopResult.Status</a></p>
go
type SandboxStatus string
ConstantValueDescription
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

LogEntry

<p className="msb-backref">Returned by <a href="#sb-logs">Logs()</a> · <a href="#sb-logstream">LogStream()</a></p>

A single captured log entry.

FieldTypeDescription
SourceLogSourceOrigin of the captured data
SessionID*uint64Relay-monotonic session id; nil for system entries
Timestamptime.TimeWall-clock capture time on the host
Data[]byteThe captured bytes
CursorstringOpaque resume token; pass to LogStreamOptions.FromCursor
MethodReturnsDescription
Text()stringCaptured bytes as a string

LogOptions

<p className="msb-backref">Used by <a href="#sb-logs">Logs()</a></p>

Filters passed to Logs. The zero value returns everything for the default sources (stdout + stderr).

FieldTypeDescription
Tailuint64Keep only the last N matching entries
Sincetime.TimeInclusive lower timestamp bound
Untiltime.TimeExclusive upper timestamp bound
Sources[]LogSourceSources to include; empty = stdout + stderr. Add LogSourceOutput or LogSourceSystem for PTY-merged output or runtime/kernel diagnostics

LogStreamOptions

<p className="msb-backref">Used by <a href="#sb-logstream">LogStream()</a></p>

Configures a live log stream. The zero value reads the default sources from the beginning with follow off. Since and FromCursor are mutually exclusive.

FieldTypeDescription
Sources[]LogSourceSources to include; empty = stdout + stderr + output
Sincetime.TimeStart at the first entry with timestamp >= this; mutually exclusive with FromCursor
FromCursorstringResume strictly after the entry whose Cursor matches; mutually exclusive with Since
Untiltime.TimeStop at the first entry with timestamp >= this
FollowboolKeep the stream open past EOF and yield new entries as written

LogStreamHandle

<p className="msb-backref">Returned by <a href="#sb-logstream">LogStream()</a></p>

Live log subscription. Call Close to release Rust-side resources.

MethodReturnsDescription
Recv(ctx)(*LogEntry, error)Block until the next entry arrives. Returns (nil, nil) when the stream ends
Close()errorStop the stream and release Rust-side resources

LogSource

<p className="msb-backref">Used by <a href="#logentry">LogEntry.Source</a> · <a href="#logoptions">LogOptions.Sources</a> · <a href="#logstreamoptions">LogStreamOptions.Sources</a></p>
go
type LogSource string
ConstantValueDescription
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

LogLevel

<p className="msb-backref">Used by <a href="#withloglevel">WithLogLevel()</a></p>
go
type LogLevel string

Sandbox process log verbosity.

ConstantValueDescription
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

PullPolicy

<p className="msb-backref">Used by <a href="#withpullpolicy">WithPullPolicy()</a></p>
go
type PullPolicy string

Controls when the SDK fetches an OCI image from the registry.

ConstantValueDescription
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

SecurityProfile

<p className="msb-backref">Used by <a href="#withsecurityprofile">WithSecurityProfile()</a></p>
go
type SecurityProfile string

Sandbox-wide in-guest security profile.

ConstantValueDescription
SecurityProfileDefault"default"Normal guest-root semantics
SecurityProfileRestricted"restricted"Stronger hardening: no_new_privs, dropped mount-admin capability, forced nosuid,nodev on user mounts

RegistryAuth

<p className="msb-backref">Used by <a href="#withregistryauth">WithRegistryAuth()</a></p>

Credentials for a private OCI registry.

FieldTypeDescription
UsernamestringRegistry username
PasswordstringRegistry password

InitConfig

<p className="msb-backref">Built by <a href="#init">Init</a> · used by <a href="#withinit">WithInit()</a></p>

Custom guest PID-1 init specification. Construct via the Init factory rather than building the struct directly.

FieldTypeDescription
CmdstringAbsolute path inside the guest, or "auto"
Args[]stringSupplemental argv (argv[0] is implicitly Cmd)
Envmap[string]stringExtra env vars merged on top of the inherited env

InitOptions

<p className="msb-backref">Used by <a href="#init-cmd">Init.Cmd()</a></p>

Tuning struct for Init.Cmd beyond the required cmd.

FieldTypeDescription
Args[]stringSupplemental argv
Envmap[string]stringExtra env vars

Init

<p className="msb-backref">Produces <a href="#initconfig">InitConfig</a> for <a href="#withinit">WithInit()</a></p>

Package-level factory namespace for InitConfig values. See the Init section for its methods.

MethodReturnsDescription
Auto()InitConfigAuto-detect a guest init
Cmd(cmd, opts)InitConfigExplicit init binary with argv and env

PatchConfig

<p className="msb-backref">Built by <a href="#patch">Patch</a> · used by <a href="#withpatches">WithPatches()</a></p>

A single rootfs patch. Construct via the Patch factory; the fields populated depend on the PatchKind.

FieldTypeDescription
KindPatchKindPatch flavour
PathstringAbsolute guest path (text / append / mkdir / remove)
ContentstringText content (text / append)
Mode*uint32File or directory mode, e.g. 0o644
ReplaceboolWhen true, overwrite an existing path at the destination
SrcstringHost source path (copy_file / copy_dir)
DststringGuest destination path (copy_file / copy_dir)
TargetstringSymlink target
LinkstringSymlink path

PatchOptions

<p className="msb-backref">Used by <a href="#patch">Patch</a> methods</p>

Tuning struct passed to Patch methods that accept a mode and replace flag.

FieldTypeDescription
Mode*uint32File or directory mode
ReplaceboolOverwrite an existing path

PatchKind

<p className="msb-backref">Used by <a href="#patchconfig">PatchConfig.Kind</a></p>
go
type PatchKind string

Discriminator for PatchConfig. Prefer the Patch factory.

ConstantValue
PatchKindText"text"
PatchKindAppend"append"
PatchKindMkdir"mkdir"
PatchKindRemove"remove"
PatchKindSymlink"symlink"
PatchKindCopyFile"copy_file"
PatchKindCopyDir"copy_dir"

Patch

<p className="msb-backref">Produces <a href="#patchconfig">PatchConfig</a> for <a href="#withpatches">WithPatches()</a></p>

Package-level factory namespace for PatchConfig values. See the Patch section for its methods.

MethodReturnsDescription
Text(path, content, opts)PatchConfigWrite UTF-8 text
Append(path, content)PatchConfigAppend to an existing file
Mkdir(path, opts)PatchConfigCreate a directory (idempotent)
Remove(path)PatchConfigDelete a file or directory (idempotent)
Symlink(target, link, opts)PatchConfigCreate a symlink
CopyFile(src, dst, opts)PatchConfigCopy a host file into the rootfs
CopyDir(src, dst, opts)PatchConfigCopy a host directory into the rootfs

SetupOption

<p className="msb-backref">Consumed by <a href="#m-ensureinstalled">EnsureInstalled()</a></p>
go
type SetupOption func(*setupConfig)

A functional option for EnsureInstalled. The only helper is WithSkipDownload.