Skip to main content

Scripts

Scripts are files mounted at /.msb/scripts/ inside the sandbox. The directory is on PATH, so each script is callable by name through exec() or shell(). It provides a clean way to bundle setup procedures or entry points with a sandbox without baking them into the image.
use indoc::indoc;
use microsandbox::Sandbox;

let sb = Sandbox::builder("worker")
    .image("ubuntu:22.04")
    .script("setup", indoc! {"
        #!/bin/bash
        apt-get update && apt-get install -y python3 curl
    "})
    .script("start", indoc! {"
        #!/bin/bash
        exec python3 /app/main.py
    "})
    .create()
    .await?;

sb.shell("setup").await?;
let output = sb.shell("start").await?;

Patches

Patches modify the rootfs before the VM boots. Write config files, copy directories from the host, create symlinks, append to existing files, remove things you don’t need. The base image stays untouched since patches are written to the writable layer on top. Patches are applied in order and work with OCI images and bind-mounted rootfs. They’re not supported with disk image roots (QCOW2, Raw).
By default, patching a path that already exists in the image will error. Pass replace: true on the operation to allow it. Mkdir and Remove are idempotent and won’t error either way.
use microsandbox::Sandbox;

let sb = Sandbox::builder("worker")
    .image("alpine:latest")
    .patch(|p| p
        .text("/etc/greeting.txt", "Hello from a patched rootfs!\n", None, false)
        .text("/etc/motd", "Custom message of the day.\n", None, true) // replace existing
        .mkdir("/app", Some(0o755))
        .text("/app/config.json", r#"{"debug": true}"#, Some(0o644), false)
        .copy_file("./cert.pem", "/etc/ssl/cert.pem", None, false)
        .append("/etc/hosts", "127.0.0.1 myapp.local\n")
    )
    .create()
    .await?;

Available operations

MethodDescription
Patch.text(path, content, opts?)Write text content to a file
Patch.mkdir(path, opts?)Create a directory (idempotent)
Patch.append(path, content)Append content to an existing file
Patch.copyFile(src, dst, opts?)Copy a file from the host into the rootfs
Patch.copyDir(src, dst, opts?)Recursively copy a directory from the host
Patch.symlink(target, link, opts?)Create a symlink
Patch.remove(path)Delete a file or directory (idempotent)