Back to Microsandbox

Snapshots

docs/sdk/rust/snapshots.mdx

0.6.934.3 KB
Original Source

Create and manage disk-only snapshots of stopped sandboxes. See Snapshots for usage and lifecycle concepts.

Snapshot

<span className="msb-recv">Snapshot::</span><span className="msb-hn">builder()</span>

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

Start configuring a new snapshot named name, resolved under the default snapshots directory (~/.microsandbox/snapshots/<name>/) or under dest_dir() when set. The source sandbox is set with from_sandbox(), which is required; the other setters cover labels and whether to record content integrity before capturing. See SnapshotBuilder for all options.

<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">impl Into&lt;String&gt;</span></div> <div className="msb-param-desc">Bare snapshot name. Must not be empty, contain <code>/</code>, or start with <code>.</code>.</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="#snapshotbuilder">SnapshotBuilder</a></div> <div className="msb-param-desc">Builder for configuring the snapshot.</div> </div> </div> <Accordion title="Example">
rust
let snap = Snapshot::builder("baseline")
    .from_sandbox("api")
    .create()
    .await?;
</Accordion>

<span className="msb-recv">Snapshot::</span><span className="msb-hn">create()</span>

rust
async fn create(config: SnapshotConfig) -> MicrosandboxResult<Snapshot>

Create a snapshot artifact from a stopped sandbox. Writes the snapshot.json descriptor and the captured upper.ext4 into the artifact directory atomically (the descriptor is renamed into place last), then best-effort upserts a row into the local index. Index failures are logged but do not fail the call; the artifact is the source of truth. Most callers use the builder's create() instead of constructing a SnapshotConfig by hand.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>config</code><a className="msb-type" href="#snapshotconfig">SnapshotConfig</a></div> <div className="msb-param-desc">Name, source sandbox, labels, and integrity flag.</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="#instance-methods">Snapshot</a></div> <div className="msb-param-desc">The created artifact handle.</div> </div> </div> <Accordion title="Example">
rust
let snap = Snapshot::create(
    Snapshot::builder("baseline").from_sandbox("api").build()?
).await?;
</Accordion>

<span className="msb-recv">Snapshot::</span><span className="msb-hn">open()</span>

rust
async fn open(path_or_name: impl AsRef<str>) -> MicrosandboxResult<Snapshot>
<Accordion title="Example">
rust
let snap = Snapshot::open("baseline").await?;
println!("{}", snap.manifest().image.reference);
</Accordion>

Open an existing artifact by path or bare name. Bare names (no path separator, not starting with . or ~) resolve under the default snapshots directory; anything else is treated as a path. This is a fast metadata operation: it verifies the manifest structure, recomputes the manifest digest, and checks that the upper file exists with the recorded size. It does not read the full upper contents; use verify() for that.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>path_or_name</code><span className="msb-type">impl AsRef&lt;str&gt;</span></div> <div className="msb-param-desc">Bare snapshot name or filesystem path to an artifact directory.</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="#instance-methods">Snapshot</a></div> <div className="msb-param-desc">The opened artifact handle.</div> </div> </div>

<span className="msb-recv">Snapshot::</span><span className="msb-hn">get()</span>

rust
async fn get(name_or_digest: &str) -> MicrosandboxResult<SnapshotHandle>
<Accordion title="Example">
rust
let h = Snapshot::get("after-pip-install").await?;
println!("{} from {}", h.digest(), h.image_ref());
</Accordion>

Look up a lightweight SnapshotHandle in the local index by name, digest (sha256:/sha512: prefix), or path.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>name_or_digest</code><span className="msb-type">&amp;str</span></div> <div className="msb-param-desc">Snapshot name, manifest digest, or artifact path.</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="#snapshothandle">SnapshotHandle</a></div> <div className="msb-param-desc">Handle backed by the matching index row.</div> </div> </div>

<span className="msb-recv">Snapshot::</span><span className="msb-hn">list()</span>

rust
async fn list() -> MicrosandboxResult<Vec<SnapshotHandle>>
<Accordion title="Example">
rust
for h in Snapshot::list().await? {
    println!("{:?} - {}", h.name(), h.digest());
}
</Accordion>

List indexed snapshots from the local DB cache, newest first. External-path artifacts booted by full path aren't in the index and won't appear here; use list_dir to enumerate artifacts on disk directly.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#snapshothandle">Vec&lt;SnapshotHandle&gt;</a></div> <div className="msb-param-desc">Indexed snapshot handles, ordered by creation time descending.</div> </div> </div>

<span className="msb-recv">Snapshot::</span><span className="msb-hn">list_dir()</span>

rust
async fn list_dir(dir: impl AsRef<Path>) -> MicrosandboxResult<Vec<Snapshot>>

Walk a directory and parse each subdirectory's manifest. Does not touch the index. Skips entries that don't look like snapshot artifacts (no snapshot.json) and malformed artifacts.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>dir</code><span className="msb-type">impl AsRef&lt;Path&gt;</span></div> <div className="msb-param-desc">Directory to scan for artifacts.</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="#instance-methods">Vec&lt;Snapshot&gt;</a></div> <div className="msb-param-desc">One handle per valid artifact found.</div> </div> </div>

<span className="msb-recv">Snapshot::</span><span className="msb-hn">remove()</span>

rust
async fn remove(path_or_name: &str, force: bool) -> MicrosandboxResult<()>
<Accordion title="Example">
rust
Snapshot::remove("after-pip-install", false).await?;
</Accordion>

Remove a snapshot artifact (by digest, name, or path) and its index row. Refuses if the snapshot has indexed children unless force is set. The artifact directory is deleted on success and the parent's child count is decremented.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>path_or_name</code><span className="msb-type">&amp;str</span></div> <div className="msb-param-desc">Snapshot digest, name, or artifact path.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>force</code><span className="msb-type">bool</span></div> <div className="msb-param-desc">When <code>true</code>, remove even if the snapshot has indexed children.</div> </div> </div>

<span className="msb-recv">Snapshot::</span><span className="msb-hn">reindex()</span>

rust
async fn reindex(dir: impl AsRef<Path>) -> MicrosandboxResult<usize>
<Accordion title="Example">
rust
let n = Snapshot::reindex("/data/snapshots").await?;
println!("indexed {n} snapshots");
</Accordion>

Rebuild the local index from the artifacts in dir. Upserts an index row for every artifact found, then recomputes parent-edge child counts in one pass so the cache stays honest about the current set of artifacts.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>dir</code><span className="msb-type">impl AsRef&lt;Path&gt;</span></div> <div className="msb-param-desc">Directory of artifacts to index.</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">usize</span></div> <div className="msb-param-desc">Number of artifacts indexed.</div> </div> </div> <Accordion title="Example">
rust
let n = Snapshot::reindex("/data/snapshots").await?;
println!("indexed {n} snapshots");
</Accordion>

<span className="msb-recv">Snapshot::</span><span className="msb-hn">save()</span>

<div className="msb-tags"><span className="msb-tag is-static">static</span><span className="msb-tag is-async">async</span></div>
rust
async fn save(name_or_path: &str, out: &Path, opts: SaveOpts) -> MicrosandboxResult<()>

Bundle a snapshot into a .tar.zst archive (or plain .tar) at out. Recorded payload integrity is preserved but not executed implicitly; call verify() when an independent content scan is part of your workflow. See SaveOpts to also include ancestors and the OCI image cache.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>name_or_path</code><span className="msb-type">&amp;str</span></div> <div className="msb-param-desc">Snapshot name or artifact path to save.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>out</code><span className="msb-type">&amp;Path</span></div> <div className="msb-param-desc">Output archive path. Parent directories are created if missing.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#saveopts">SaveOpts</a></div> <div className="msb-param-desc">Bundling options. <code>SaveOpts::default()</code> writes the head snapshot only, zstd-compressed.</div> </div> </div> <Accordion title="Example">
rust
use microsandbox::snapshot::SaveOpts;
use std::path::Path;

Snapshot::save(
    "baseline",
    Path::new("/tmp/baseline.tar.zst"),
    SaveOpts { with_parents: true, with_image: true, ..Default::default() },
).await?;
</Accordion>

<span className="msb-recv">Snapshot::</span><span className="msb-hn">load()</span>

<div className="msb-tags"><span className="msb-tag is-static">static</span><span className="msb-tag is-async">async</span></div>
rust
async fn load(archive_path: &Path, dest: Option<&Path>) -> MicrosandboxResult<SnapshotHandle>
<Accordion title="Example">
rust
use std::path::Path;

let h = Snapshot::load(Path::new("/tmp/baseline.tar.zst"), None).await?;
println!("loaded {}", h.digest());
</Accordion>

Unpack a snapshot archive (.tar.zst or .tar, detected from magic bytes) into the snapshots directory (or dest), routing any bundled image-cache entries into the global cache and registering everything found in the index. Structural and archive-entry checks remain mandatory, while recorded payload integrity is preserved for explicit verify(). Returns a handle for the head snapshot.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>archive_path</code><span className="msb-type">&amp;Path</span></div> <div className="msb-param-desc">Archive to unpack.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>dest</code><span className="msb-type">Option&lt;&amp;Path&gt;</span></div> <div className="msb-param-desc">Destination directory. <code>None</code> uses the default snapshots directory.</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="#snapshothandle">SnapshotHandle</a></div> <div className="msb-param-desc">Handle for the head (last-listed) snapshot.</div> </div> </div> <Accordion title="Example">
rust
use std::path::Path;

let h = Snapshot::load(Path::new("/tmp/baseline.tar.zst"), None).await?;
println!("loaded {}", h.digest());
</Accordion>
<p className="msb-member-group">Instance methods</p>

Methods on an opened Snapshot artifact.

<span className="msb-recv">snap.</span><span className="msb-hn">digest()</span>

rust
fn digest(&self) -> &str

Canonical content digest of this snapshot's manifest (sha256:hex). This is the snapshot's identity.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">&amp;str</span></div> <div className="msb-param-desc">Manifest digest in <code>sha256:hex</code> form.</div> </div> </div>

<span className="msb-recv">snap.</span><span className="msb-hn">path()</span>

rust
fn path(&self) -> &Path

Path to the artifact directory holding the canonical snapshot.json descriptor and the captured upper file.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">&amp;Path</span></div> <div className="msb-param-desc">Artifact directory path.</div> </div> </div>

<span className="msb-recv">snap.</span><span className="msb-hn">manifest()</span>

rust
fn manifest(&self) -> &Manifest
<Accordion title="Example">
rust
let snap = Snapshot::open("baseline").await?;
let m = snap.manifest();
println!("{} @ {}", m.image.reference, m.image.manifest_digest);
</Accordion>

The parsed Manifest: schema, format, fstype, image reference, parent, creation time, labels, and upper-layer metadata.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#manifest">&amp;Manifest</a></div> <div className="msb-param-desc">Parsed snapshot manifest.</div> </div> </div>

<span className="msb-recv">snap.</span><span className="msb-hn">size_bytes()</span>

rust
fn size_bytes(&self) -> u64

Apparent size of the captured upper layer in bytes (the ext4 virtual size; sparse on disk).

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">u64</span></div> <div className="msb-param-desc">Upper-layer apparent size in bytes.</div> </div> </div>

<span className="msb-recv">snap.</span><span className="msb-hn">verify()</span>

rust
async fn verify(&self) -> MicrosandboxResult<SnapshotVerifyReport>
<Accordion title="Example">
rust
use microsandbox::snapshot::UpperVerifyStatus;

let snap = Snapshot::open("baseline").await?;
match snap.verify().await?.upper {
    UpperVerifyStatus::Verified { algorithm, .. } => println!("ok via {algorithm}"),
    UpperVerifyStatus::NotRecorded => println!("no integrity hash recorded"),
}
</Accordion>

Recompute the upper layer's recorded content integrity and compare it against the descriptor. Current BLAKE3 Merkle integrity skips known all-hole subtrees and hashes allocated leaves in batches. Released SHA algorithms retain their exact verifier and may still cost O(logical size). Returns NotRecorded without reading payload contents when the descriptor has integrity: null; errors with SnapshotIntegrity on mismatch.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#snapshotverifyreport">SnapshotVerifyReport</a></div> <div className="msb-param-desc">Digest, path, and upper-layer verification status.</div> </div> </div>

SnapshotHandle

<div className="msb-tags"><span className="msb-tag is-type">struct</span></div> <p className="msb-backref">Returned by <a href="#snapshotget">Snapshot::get()</a> · <a href="#snapshotlist">Snapshot::list()</a> · <a href="#snapshotload">Snapshot::load()</a></p>

A snapshot handle backed by the local index.

<span className="msb-recv">h.</span><span className="msb-hn">digest()</span>

rust
fn digest(&self) -> &str

Manifest digest (sha256:hex), the canonical identity.

<span className="msb-recv">h.</span><span className="msb-hn">name()</span>

rust
fn name(&self) -> Option<&str>

Name alias, or None for digest-only entries.

<span className="msb-recv">h.</span><span className="msb-hn">parent_digest()</span>

rust
fn parent_digest(&self) -> Option<&str>

The parent snapshot's digest, or None for a root. Always None today; populated once chained snapshots land.


<span className="msb-recv">h.</span><span className="msb-hn">scope()</span>

<div className="msb-tags"><span className="msb-tag is-instance">instance</span></div>
rust
fn scope(&self) -> SnapshotScope

Snapshot payload scope: SnapshotScope::Disk for a disk-only snapshot, Resumable once resumable snapshots land. Always Disk today.


<span className="msb-recv">h.</span><span className="msb-hn">image_ref()</span>

rust
fn image_ref(&self) -> &str

Image reference the snapshot was taken from.

<span className="msb-recv">h.</span><span className="msb-hn">format()</span>

rust
fn format(&self) -> SnapshotFormat

On-disk format of the upper layer.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#snapshotformat">SnapshotFormat</a></div> <div className="msb-param-desc">Upper-layer format (<code>Raw</code> today).</div> </div> </div>

<span className="msb-recv">h.</span><span className="msb-hn">size_bytes()</span>

rust
fn size_bytes(&self) -> Option<u64>

Apparent size of the upper file at index time, if recorded.

<span className="msb-recv">h.</span><span className="msb-hn">created_at()</span>

rust
fn created_at(&self) -> chrono::NaiveDateTime

Snapshot creation time, parsed from the manifest.

<span className="msb-recv">h.</span><span className="msb-hn">path()</span>

rust
fn path(&self) -> &Path

Local artifact directory path.

<span className="msb-recv">h.</span><span className="msb-hn">open()</span>

rust
async fn open(&self) -> MicrosandboxResult<Snapshot>
<Accordion title="Example">
rust
let h = Snapshot::get("baseline").await?;
let snap = h.open().await?;
snap.verify().await?;
</Accordion>

Open the underlying artifact metadata, upgrading this lightweight handle to a full Snapshot. Equivalent to Snapshot::open(self.path()).

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Snapshot</a></div> <div className="msb-param-desc">The opened artifact.</div> </div> </div>

<span className="msb-recv">h.</span><span className="msb-hn">remove()</span>

rust
async fn remove(&self, force: bool) -> MicrosandboxResult<()>
<Accordion title="Example">
rust
let h = Snapshot::get("baseline").await?;
h.remove(false).await?;
</Accordion>

Remove this snapshot. Delegates to Snapshot::remove(self.digest(), force).

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>force</code><span className="msb-type">bool</span></div> <div className="msb-param-desc">When <code>true</code>, remove even if the snapshot has indexed children.</div> </div> </div>

SandboxBuilder

Snapshot-related methods that live on the sandbox builder and handle. See Sandbox for the full sandbox API.

<span className="msb-recv">sandbox.</span><span className="msb-hn">from_snapshot()</span>

rust
fn from_snapshot(self, path_or_name: impl Into<String>) -> Self
<Accordion title="Example">
rust
let sb = Sandbox::builder("api-restored")
    .from_snapshot("after-pip-install")
    .create()
    .await?;
</Accordion>

SandboxBuilder setter. Boot a fresh sandbox from a snapshot artifact. The snapshot already pins the image reference and digest, so this is mutually exclusive with image() and image_with(). The artifact is structurally opened at create() time; persistent payload integrity is checked only through explicit Snapshot::verify().

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>path_or_name</code><span className="msb-type">impl Into&lt;String&gt;</span></div> <div className="msb-param-desc">Bare name resolved under the default snapshots directory, or a path to an artifact directory.</div> </div> </div>

SandboxHandle

<span className="msb-recv">h.</span><span className="msb-hn">snapshot()</span>

rust
async fn snapshot(&self, name: &str) -> MicrosandboxResult<Snapshot>

SandboxHandle method. Snapshot this sandbox under a bare name in the default snapshots directory (~/.microsandbox/snapshots/<name>/). The sandbox must be stopped or crashed; running sandboxes are rejected with SnapshotSandboxRunning. Local handles only. To place the artifact elsewhere, use Snapshot::save() / Snapshot::load() or move the self-contained artifact directory.

<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">&amp;str</span></div> <div className="msb-param-desc">Bare snapshot name.</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="#instance-methods">Snapshot</a></div> <div className="msb-param-desc">The created artifact handle.</div> </div> </div>

<span className="msb-recv">h.</span><span className="msb-hn">snapshot_to()</span>

rust
async fn snapshot_to(&self, path: impl AsRef<Path>) -> MicrosandboxResult<Snapshot>
<Accordion title="Example">
rust
let h = Sandbox::get("api").await?;
h.stop().await?;
let snap = h.snapshot_to("/data/snapshots/baseline").await?;
</Accordion>

SnapshotBuilder

Builder for snapshot configuration.


<span className="msb-recv">snapshot_builder.</span><span className="msb-hn">from_sandbox()</span>

<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>
rust
fn from_sandbox(self, source_sandbox: impl Into<String>) -> Self

Set the sandbox to capture. Required; build() and create() fail without it.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>source_sandbox</code><span className="msb-type">impl Into&lt;String&gt;</span></div> <div className="msb-param-desc">Name of the source sandbox. Must be stopped or crashed, and rooted on an OCI image.</div> </div> </div>

<span className="msb-recv">snapshot_builder.</span><span className="msb-hn">dest_dir()</span>

<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>
rust
fn dest_dir(self, dest_dir: impl Into<PathBuf>) -> Self

Create the artifact under this parent directory instead of the default snapshots store. The artifact directory is dest_dir/<name>; the name stays the snapshot's identity either way.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>dest_dir</code><span className="msb-type">impl Into&lt;PathBuf&gt;</span></div> <div className="msb-param-desc">Parent directory to create the artifact in (e.g. a larger volume).</div> </div> </div>

<span className="msb-recv">snapshot_builder.</span><span className="msb-hn">label()</span>

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

Add a user label. Can be called multiple times. Labels are sorted by key in the manifest's canonical form.

<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">impl Into&lt;String&gt;</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">impl Into&lt;String&gt;</span></div> <div className="msb-param-desc">Label value.</div> </div> </div>

<span className="msb-recv">snapshot_builder.</span><span className="msb-hn">force()</span>

rust
fn force(self) -> Self

Overwrite an existing artifact with the same name. Without this, creation fails with SnapshotAlreadyExists if the artifact directory exists.

<span className="msb-recv">snapshot_builder.</span><span className="msb-hn">record_integrity()</span>

rust
fn record_integrity(self) -> Self

Compute and record sparse-aware BLAKE3 Merkle integrity during creation. verify() checks it explicitly; ordinary open, boot, save, load, and upgrade preserve the value without adding an independent payload pass.


<span className="msb-recv">snapshot_builder.</span><span className="msb-hn">resumable()</span>

<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>
rust
fn resumable(self) -> Self

Request a resumable snapshot (disk plus VM state). Accepted by the builder, but create() currently fails with Unsupported; resumable snapshots have not landed yet.

<span className="msb-recv">snapshot_builder.</span><span className="msb-hn">build()</span>

rust
fn build(self) -> MicrosandboxResult<SnapshotConfig>

Materialize the SnapshotConfig without creating the snapshot. Errors with InvalidConfig if from_sandbox was not called. For capturing, use create instead; it calls build internally.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#snapshotconfig">SnapshotConfig</a></div> <div className="msb-param-desc">Validated snapshot configuration.</div> </div> </div>

<span className="msb-recv">snapshot_builder.</span><span className="msb-hn">create()</span>

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

Build and execute the snapshot in one step. Equivalent to Snapshot::create(self.build()?).

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Snapshot</a></div> <div className="msb-param-desc">The created artifact handle.</div> </div> </div>

Types

SnapshotConfig

<p className="msb-backref">Used by <a href="#snapshotcreate">Snapshot::create()</a> · returned by <a href="#build">build()</a></p>

Inputs to create a snapshot. A type alias for SnapshotSpec. Usually built via SnapshotBuilder rather than constructed directly.

FieldTypeDescription
nameStringBare snapshot name; always the artifact directory's basename
dest_dirOption<PathBuf>Parent directory for the artifact; None = the default snapshots directory
source_sandboxStringName of the source sandbox; must be stopped
labelsVec<(String, String)>User-supplied labels
forceboolOverwrite an existing artifact with the same name
record_integrityboolCompute and record upper-layer integrity at creation
resumableboolRequest a resumable snapshot; returns an unsupported-feature error today

SnapshotFormat

<p className="msb-backref">Used by <a href="#h-format">format()</a> · <a href="#manifest">Manifest.format</a></p>

On-disk format of the captured upper layer. Today only Raw is produced; the variant exists so qcow2 chains drop in later without a schema migration.

ValueDescription
RawRaw ext4 image, sparse on disk
Qcow2qcow2 with optional backing chain (future)

SnapshotScope

<div className="msb-tags"><span className="msb-tag is-type">enum</span></div> <p className="msb-backref">Used by <a href="#h-scope">scope()</a> · <a href="#manifest">Manifest.scope</a></p>

Snapshot payload scope. Parsing accepts every known scope so older runtimes can still list and inspect artifacts they cannot restore; create and restore paths enforce support. Re-exported as microsandbox::snapshot::SnapshotScope.

ValueDescription
DiskDisk-only snapshot; captures the writable filesystem state
ResumableReserved for future memory/device-state capture

SaveOpts

<div className="msb-tags"><span className="msb-tag is-type">struct</span></div> <p className="msb-backref">Used by <a href="#snapshotsave">Snapshot::save()</a></p>

Options for Snapshot::save(). Implements Default; SaveOpts::default() writes the head snapshot only, zstd-compressed.

FieldTypeDescription
with_parentsboolWalk the parent chain and include each ancestor in the archive
with_imageboolBundle the OCI image artifacts (EROFS layers, fsmeta, VMDK descriptor) from the global cache so the archive boots offline
plain_tarboolSkip zstd compression and write a plain .tar. Default: zstd

SnapshotVerifyReport

<p className="msb-backref">Returned by <a href="#snap-verify">verify()</a></p>

Result of explicit snapshot verification.

FieldTypeDescription
digestStringSnapshot manifest digest
pathPathBufArtifact directory
upperUpperVerifyStatusUpper-layer content verification result

UpperVerifyStatus

<p className="msb-backref">Used by <a href="#snapshotverifyreport">SnapshotVerifyReport.upper</a></p>

Upper-layer content verification result.

VariantFieldsDescription
NotRecorded-No content integrity descriptor was recorded in the manifest
Verified- algorithm: String
  • digest: String | Recorded integrity matched the computed digest |

Manifest

<p className="msb-backref">Returned by <a href="#snap-manifest">manifest()</a></p>

The snapshot artifact manifest, the source of truth for an artifact, serialized as the snapshot.json descriptor (DESCRIPTOR_FILENAME). Re-exported as microsandbox::snapshot::Manifest. Its SHA-256 digest over the canonical byte form is the snapshot's identity. Field order is load-bearing (it determines the canonical byte layout) and must not be reordered.

FieldTypeDescription
schemau32Manifest schema version; readers reject unknown values
artifactStringArtifact kind; always "snapshot"
scopeSnapshotScopePayload scope; only disk snapshots are created today
formatSnapshotFormatOn-disk format of the upper layer
fstypeStringFilesystem type inside the upper (e.g. ext4)
imageImageRefImage the snapshot was taken from
parentOption<String>Parent snapshot digest, or None for a root
created_atStringRFC 3339 creation timestamp
labelsBTreeMap<String, String>User-supplied labels, sorted by key in canonical form
upperUpperLayerThe captured upper layer
source_sandboxOption<String>Best-effort name of the source sandbox (informational)

ImageRef

<p className="msb-backref">Used by <a href="#manifest">Manifest.image</a></p>

Reference to the OCI image the snapshot was taken from. Re-exported as microsandbox::snapshot::ImageRef.

FieldTypeDescription
referenceStringHuman-readable image reference (e.g. docker.io/library/python:3.12)
manifest_digestStringDigest of the OCI manifest, in sha256:hex form

UpperLayer

<p className="msb-backref">Used by <a href="#manifest">Manifest.upper</a></p>

Captured upper-layer file metadata. Re-exported as microsandbox::snapshot::UpperLayer.

FieldTypeDescription
fileStringFilename inside the artifact directory (e.g. upper.ext4)
size_bytesu64Apparent size in bytes (ext4 virtual size; sparse on disk)
integrityOption<UpperIntegrity>Optional content integrity descriptor; None on local hot paths

UpperIntegrity

<p className="msb-backref">Used by <a href="#upperlayer">UpperLayer.integrity</a></p>

Content integrity descriptor for the captured upper layer.

FieldTypeDescription
VariantSerialized algorithmFields
---------------------------------------
Sha256sha256digest
SparseSha256V1msb-sparse-sha256-v1digest
FileMerkleBlake3V1msb-file-merkle-blake3-v1root, logical_size, leaf_size