Back to Microsandbox

Sandbox

docs/sdk/rust/sandbox.mdx

0.4.424.6 KB
Original Source

See Overview for configuration examples and Lifecycle for state management.

Static methods


Sandbox::builder()

rust
fn builder(name: impl Into<String>) -> SandboxBuilder

Create a builder for configuring a new sandbox. The builder lets you set the image, resources, volumes, networking, secrets, and other options before booting the VM. See SandboxBuilder for all available options.

Parameters

NameTypeDescription
nameimpl Into<String>Sandbox name - must be unique among running sandboxes

Returns

TypeDescription
SandboxBuilderBuilder for configuring the sandbox

Sandbox::get()

rust
async fn get(name: &str) -> MicrosandboxResult<SandboxHandle>

Get a handle to an existing sandbox (running or stopped). The handle provides status, configuration, and lifecycle control without requiring a full connection to the guest agent.

Parameters

NameTypeDescription
name&strSandbox name

Returns

TypeDescription
SandboxHandleHandle with status and lifecycle control

Sandbox::list()

rust
async fn list() -> MicrosandboxResult<Vec<SandboxHandle>>

List all sandboxes (running, stopped, and crashed).

Returns

TypeDescription
Vec<SandboxHandle>All sandbox handles

Sandbox::remove()

rust
async fn remove(name: &str) -> MicrosandboxResult<()>

Delete a stopped sandbox and all its state from disk (configuration, logs, runtime directory). Fails if the sandbox is still running - stop it first.

Parameters

NameTypeDescription
name&strSandbox name

Sandbox::start()

rust
async fn start(name: &str) -> MicrosandboxResult<Sandbox>

Restart a previously stopped sandbox. The VM reboots using the persisted configuration. The sandbox enters attached mode - it stops when your process exits.

Parameters

NameTypeDescription
name&strName of a stopped sandbox

Returns

TypeDescription
SandboxRunning sandbox

Sandbox::start_detached()

rust
async fn start_detached(name: &str) -> MicrosandboxResult<Sandbox>

Restart a stopped sandbox in detached mode. The sandbox survives after your process exits.

Parameters

NameTypeDescription
name&strName of a stopped sandbox

Returns

TypeDescription
SandboxRunning sandbox

Instance methods


config()

rust
fn config(&self) -> &SandboxConfig

Access the sandbox's full configuration.

Returns

TypeDescription
&SandboxConfigSandbox configuration

detach()

rust
async fn detach(self)

Release the handle without stopping the sandbox. The sandbox continues running as a background process. Reconnect later with Sandbox::get().


drain()

rust
async fn drain(&self) -> MicrosandboxResult<()>

Start a graceful drain. Existing commands run to completion, but new exec calls are rejected. The sandbox transitions to Stopped when all in-flight commands finish. Useful for zero-downtime rotation of worker sandboxes.


fs()

rust
fn fs(&self) -> SandboxFs<'_>

Get a filesystem handle for reading and writing files inside the running sandbox. See Filesystem for the full API.

Returns

TypeDescription
SandboxFsFilesystem handle

kill()

rust
async fn kill(&self) -> MicrosandboxResult<()>

Force-terminate the sandbox immediately with SIGKILL. No graceful shutdown - use when the sandbox is unresponsive.


metrics()

rust
async fn metrics(&self) -> MicrosandboxResult<SandboxMetrics>

Get a point-in-time snapshot of the sandbox's resource usage: CPU, memory, disk I/O, network I/O, and uptime.

Returns

TypeDescription
SandboxMetricsResource metrics

metrics_stream()

rust
fn metrics_stream(&self, interval: Duration) -> impl Stream<Item = MicrosandboxResult<SandboxMetrics>>

Stream resource metrics at a regular interval. Returns an async stream that yields a new snapshot every interval duration.

Parameters

NameTypeDescription
intervalDurationTime between metric snapshots

Returns

TypeDescription
impl Stream<Item = Result<SandboxMetrics>>Async stream of metrics

logs()

rust
fn logs(&self, opts: &LogOptions) -> MicrosandboxResult<Vec<LogEntry>>

Read captured output from the sandbox's exec.log. Backed by an on-disk JSON Lines file the runtime writes via the relay tap. Works on running and stopped sandboxes alike — there is no protocol traffic. The same method is available on SandboxHandle for callers that don't want to start the sandbox first.

The default sources are Stdout, Stderr, and Output (PTY-merged). Pass LogSource::System to also include synthetic lifecycle markers and runtime/kernel diagnostic lines.

rust
use microsandbox::sandbox::{LogOptions, LogSource, Sandbox};

let handle = Sandbox::get("web").await?;

// Default — all user-program output, regardless of pipe/pty mode
let entries = handle.logs(&LogOptions::default())?;

for e in entries {
    let source = match e.source {
        LogSource::Stdout => "OUT",
        LogSource::Stderr => "ERR",
        LogSource::Output => "PTY",
        LogSource::System => "SYS",
    };
    println!(
        "[{}] {} {:?}: {}",
        e.timestamp.to_rfc3339(),
        source,
        e.session_id,
        String::from_utf8_lossy(&e.data).trim_end()
    );
}

// Filtered: last 50 entries from the past hour, including system lines
let recent = handle.logs(&LogOptions {
    tail: Some(50),
    since: Some(chrono::Utc::now() - chrono::Duration::hours(1)),
    sources: vec![
        LogSource::Stdout,
        LogSource::Stderr,
        LogSource::Output,
        LogSource::System,
    ],
    ..Default::default()
})?;

logs() is synchronous because it's a pure file read.

Parameters

NameTypeDescription
opts&LogOptionsFilters: tail, since, until, sources. LogOptions::default() returns everything for the default sources.

Returns

TypeDescription
Vec<LogEntry>Matching entries in chronological order

name()

rust
fn name(&self) -> &str

Get the sandbox name.

Returns

TypeDescription
&strSandbox name

owns_lifecycle()

rust
fn owns_lifecycle(&self) -> bool

Whether this handle owns the sandbox lifecycle. true in attached mode (sandbox stops when your process exits), false in detached mode.

Returns

TypeDescription
booltrue if attached

remove_persisted()

rust
async fn remove_persisted(self) -> MicrosandboxResult<()>

Remove the sandbox and all its persisted state from disk.


stop()

rust
async fn stop(&self) -> MicrosandboxResult<()>

Gracefully shut down the sandbox. Sends SIGTERM to all guest processes and waits for the VM to exit.


stop_and_wait()

rust
async fn stop_and_wait(&self) -> MicrosandboxResult<ExitStatus>

Stop the sandbox and wait for the exit status.

Returns

TypeDescription
ExitStatusExit code and success flag

wait()

rust
async fn wait(&self) -> MicrosandboxResult<ExitStatus>

Block until the sandbox exits on its own (without triggering a stop). Returns the exit status.

Returns

TypeDescription
ExitStatusExit code and success flag

SandboxBuilder

Builder for configuring a sandbox before creation. Obtained via Sandbox::builder(name).


cpus()

rust
fn cpus(self, count: u8) -> Self

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

Parameters

NameTypeDescription
countu8Number of vCPUs

create()

rust
async fn create(self) -> MicrosandboxResult<Sandbox>

Boot the sandbox in attached mode. The sandbox stops when your process exits.

Returns

TypeDescription
SandboxRunning sandbox

create_detached()

rust
async fn create_detached(self) -> MicrosandboxResult<Sandbox>

Boot the sandbox in detached mode. The sandbox survives after your process exits.

Returns

TypeDescription
SandboxRunning sandbox

disable_network()

rust
fn disable_network(self) -> Self

Fully disable networking. No network interface is created.


entrypoint()

rust
fn entrypoint(self, cmd: impl IntoIterator<Item = impl Into<String>>) -> Self

Override the OCI image's entrypoint.

Parameters

NameTypeDescription
cmdimpl IntoIterator<Item = impl Into<String>>Entrypoint command and arguments

env()

rust
fn env(self, key: impl Into<String>, value: impl Into<String>) -> Self

Set an environment variable visible to all commands. Can be called multiple times. Per-command env vars (via exec_with) are merged on top.

Parameters

NameTypeDescription
keyimpl Into<String>Variable name
valueimpl Into<String>Variable value

hostname()

rust
fn hostname(self, hostname: impl Into<String>) -> Self

Set the guest hostname.

Parameters

NameTypeDescription
hostnameimpl Into<String>Hostname

idle_timeout()

rust
fn idle_timeout(self, secs: u64) -> Self

Auto-drain the sandbox after this many seconds of inactivity (no active exec sessions). Enforced on the host side.


init()

rust
fn init(self, cmd: impl Into<PathBuf>) -> Self

Hand off PID 1 inside the guest to cmd after agentd finishes its boot-time setup. The agent forks; the parent execs the init and becomes PID 1, the agent continues as a child process. See Init handoff for image picks, shutdown semantics, and tradeoffs.

cmd is either an absolute path inside the guest rootfs or the literal "auto" (probes /sbin/init, /lib/systemd/systemd, /usr/lib/systemd/systemd). For init binaries that take argv or extra env (rare), use init_with.

Parameters

NameTypeDescription
cmdimpl Into<PathBuf>Absolute path inside the guest, or "auto"
rust
let sb = Sandbox::builder("worker")
    .image("jrei/systemd-debian:12")
    .init("auto")
    .create()
    .await?;

init_with()

rust
fn init_with(
    self,
    cmd: impl Into<PathBuf>,
    f: impl FnOnce(InitOptionsBuilder) -> InitOptionsBuilder,
) -> Self

Like init, but with a closure-builder for argv and env vars. Mirrors exec_with in shape.

The builder exposes arg, args, env, and envs.

Parameters

NameTypeDescription
cmdimpl Into<PathBuf>Absolute path to the init binary inside the guest
fFnOnce(InitOptionsBuilder) -> InitOptionsBuilderClosure populating argv and env
rust
let sb = Sandbox::builder("worker")
    .image("jrei/systemd-debian:12")
    .init_with("/lib/systemd/systemd", |i| i
        .args(["--unit=multi-user.target"])
        .env("container", "microsandbox"))
    .create()
    .await?;

Calling init or init_with more than once overwrites — different from env, which appends. The init is one-shot pre-boot.

Parameters

NameTypeDescription
secsu64Idle timeout in seconds

image()

rust
fn image(self, image: impl IntoImage) -> Self

Set the root filesystem source. Accepts OCI image names, local directory paths, or disk image paths. The format is auto-detected.

Parameters

NameTypeDescription
imageimpl IntoImageOCI image name, local directory path, or disk image path

image_with()

rust
fn image_with(self, f: impl FnOnce(ImageBuilder) -> ImageBuilder) -> Self

Configure a disk image rootfs with explicit filesystem type. Use when the filesystem type can't be auto-detected.

Parameters

NameTypeDescription
fImageBuilderConfigure the disk image rootfs.

log_level()

rust
fn log_level(self, level: LogLevel) -> Self

Override the sandbox process's log verbosity.

Parameters

NameTypeDescription
levelLogLevelLog level

max_duration()

rust
fn max_duration(self, secs: u64) -> Self

Set the maximum sandbox lifetime in seconds. When exceeded, the sandbox is drained and stopped. Enforced on the host side - the guest cannot override it.

Parameters

NameTypeDescription
secsu64Maximum lifetime in seconds

memory()

rust
fn memory(self, size: impl Into<Mebibytes>) -> Self

Set the guest memory size. Physical pages are only allocated as the guest touches them, so this is a limit, not an upfront reservation. Default: 512 MiB.

Parameters

NameTypeDescription
sizeimpl Into<Mebibytes>Memory in MiB

network()

rust
fn network(self, f: impl FnOnce(NetworkBuilder) -> NetworkBuilder) -> Self

Configure networking. See Networking for the full builder API.

Parameters

NameTypeDescription
fNetworkBuilderConfigure the network.

patch()

rust
fn patch(self, f: impl FnOnce(PatchBuilder) -> PatchBuilder) -> Self

Modify the rootfs before the VM boots. Patches go into the writable layer - the base image is untouched.

Parameters

NameTypeDescription
fPatchBuilderConfigure rootfs patches.

port()

rust
fn port(self, host_port: u16, guest_port: u16) -> Self

Publish a TCP port from the sandbox to the host.

Parameters

NameTypeDescription
host_portu16Port on the host
guest_portu16Port inside the sandbox

port_udp()

rust
fn port_udp(self, host_port: u16, guest_port: u16) -> Self

Publish a UDP port.

Parameters

NameTypeDescription
host_portu16Port on the host
guest_portu16Port inside the sandbox

pull_policy()

rust
fn pull_policy(self, policy: PullPolicy) -> Self

Control when the OCI image is pulled from the registry.

Parameters

NameTypeDescription
policyPullPolicyPull behavior

registry_auth()

rust
fn registry_auth(self, auth: RegistryAuth) -> Self

Authenticate to a private container registry.

Parameters

NameTypeDescription
authRegistryAuthRegistry credentials

replace()

rust
fn replace(self) -> Self

If a sandbox with the same name already exists, stop it, remove it, and create a fresh one. Without this, creation fails on name conflict.


script()

rust
fn script(self, name: impl Into<String>, content: impl Into<String>) -> Self

Add a named script at /.msb/scripts/ inside the guest. Scripts are added to PATH and can be called by name via exec() or shell().

Parameters

NameTypeDescription
nameimpl Into<String>Script name (becomes the filename)
contentimpl Into<String>Script content

secret()

rust
fn secret(self, f: impl FnOnce(SecretBuilder) -> SecretBuilder) -> Self

Add a secret with full configuration. See Secrets for the builder API. Automatically enables TLS interception.

Parameters

NameTypeDescription
fSecretBuilderConfigure the secret.

secret_env()

rust
fn secret_env(self, env_var: impl Into<String>, value: impl Into<String>, allowed_host: impl Into<String>) -> Self

Shorthand for adding a header-injected secret. Equivalent to .secret(|s| s.env(env_var).value(value).allow_host(allowed_host)).

Parameters

NameTypeDescription
env_varimpl Into<String>Environment variable name
valueimpl Into<String>Secret value
allowed_hostimpl Into<String>Allowed destination host

shell()

rust
fn shell(self, shell: impl Into<String>) -> Self

Set the shell used by Sandbox::shell(). Default: /bin/sh.

Parameters

NameTypeDescription
shellimpl Into<String>Shell path (e.g. "/bin/bash")

user()

rust
fn user(self, user: impl Into<String>) -> Self

Set the default guest user for all commands.

Parameters

NameTypeDescription
userimpl Into<String>User name or UID

volume()

rust
fn volume(self, guest_path: impl Into<String>, f: impl FnOnce(MountBuilder) -> MountBuilder) -> Self

Add a volume mount. See Volumes for mount types.

Parameters

NameTypeDescription
guest_pathimpl Into<String>Mount point inside the sandbox
fMountBuilderConfigure the mount.

workdir()

rust
fn workdir(self, path: impl Into<String>) -> Self

Set the default working directory for all commands.

Parameters

NameTypeDescription
pathimpl Into<String>Absolute path inside the guest

Types

LogEntry

A single captured log entry returned by logs().

FieldTypeDescription
timestampDateTime<Utc>Wall-clock capture time on the host
sourceLogSourceWhere the chunk came from
session_idOption<u64>Relay-monotonic session id; None for System entries
dataBytesThe chunk's bytes (UTF-8 lossy decoded by default; raw bytes if --raw mode was used)

LogLevel

Sandbox process log verbosity.

ValueDescription
ErrorErrors only
WarnWarnings and errors only
InfoInfo and higher
DebugDebug and higher
TraceMost verbose - all diagnostic output

LogOptions

Filters passed to logs(). All fields optional. LogOptions::default() returns everything for the default sources (Stdout + Stderr + Output).

FieldTypeDescription
tailOption<usize>Show only the last N entries after other filters apply
sinceOption<DateTime<Utc>>Inclusive lower bound on entry timestamp
untilOption<DateTime<Utc>>Exclusive upper bound on entry timestamp
sourcesVec<LogSource>Sources to include. Empty = [Stdout, Stderr, Output] (the default user-program sources). Add System to merge runtime/kernel diagnostics.

LogSource

Tag indicating where a captured log entry came from.

ValueDescription
StdoutCaptured from a session's stdout (pipe mode — streams stayed separated)
StderrCaptured from a session's stderr (pipe mode)
OutputCaptured from a session running in pty mode. PTY allocation merges stdout and stderr at the kernel level inside the guest, so they arrive as a single stream — tagged Output rather than mislabelled as Stdout.
SystemSynthetic entry: lifecycle markers in exec.log plus runtime/kernel diagnostic lines merged in at read time when System is requested.

PullPolicy

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

ValueDescription
AlwaysPull the image every time, even if cached locally
IfMissingPull only if the image is not already cached. This is the default.
NeverNever pull; fail if the image is not cached locally

RegistryAuth

Credentials for authenticating to a private container registry.

VariantFieldsDescription
Basic- username: String
  • password: String | Username and password authentication |

SandboxConfig

The full configuration of a sandbox. Obtained via config() or built via SandboxBuilder. Contains all settings used to create the sandbox.

FieldTypeDescription
cpusu8Number of virtual CPUs
envVec<(String, String)>Environment variables
idle_timeout_secsOption<u64>Idle timeout
imageRootfsSourceRoot filesystem source (OCI, bind, or disk image)
max_duration_secsOption<u64>Maximum lifetime
memory_mibu32Guest memory in MiB
nameStringSandbox name
patchesVec<Patch>Rootfs patches
scriptsVec<(String, String)>Named scripts
shellOption<String>Shell for shell() calls
volumesVec<VolumeMount>Volume mounts
workdirOption<String>Default working directory

SandboxHandle

A lightweight handle to an existing sandbox (running or stopped). Obtained via Sandbox::get() or Sandbox::list(). Provides status, configuration, and lifecycle control without an active connection to the guest agent. You cannot exec or fs on a handle - call .start() or .connect() to upgrade to a full Sandbox.

Property / MethodTypeDescription
config()Result<SandboxConfig>Parsed configuration
config_json()&strRaw JSON configuration
connect()Result<Sandbox>Connect to a running sandbox
created_at()Option<DateTime<Utc>>Creation timestamp
kill()Result<()>Force terminate
logs()Result<Vec<LogEntry>>Read captured exec.log (works without starting)
metrics()Result<SandboxMetrics>Point-in-time resource metrics
name()&strSandbox name
remove()Result<()>Delete sandbox and state
start()Result<Sandbox>Start in attached mode
start_detached()Result<Sandbox>Start in detached mode
status()SandboxStatusCurrent status
stop()Result<()>Graceful shutdown
updated_at()Option<DateTime<Utc>>Last update timestamp

SandboxMetrics

Point-in-time resource usage snapshot.

FieldTypeDescription
cpu_percentf32CPU usage as a percentage
disk_read_bytesu64Total bytes read from disk since boot
disk_write_bytesu64Total bytes written to disk since boot
memory_bytesu64Current memory usage in bytes
memory_limit_bytesu64Memory limit in bytes
net_rx_bytesu64Total bytes received over the network since boot
net_tx_bytesu64Total bytes sent over the network since boot
timestampDateTime<Utc>When this measurement was taken
uptimeDurationTime since the sandbox was created

SandboxStatus

ValueDescription
CrashedVM exited unexpectedly (kernel panic, OOM, etc.)
DrainingGraceful shutdown in progress; existing commands finish, new ones rejected
RunningGuest agent is ready; exec, shell, fs work
StoppedVM shut down; configuration persisted; can be restarted