supermachine/lib.rs
1#![recursion_limit = "256"]
2//! supermachine — run any OCI/Docker image as a hardware-isolated
3//! microVM on macOS HVF (Linux KVM and Windows WHP in progress).
4//!
5//! ## Quick start
6//!
7//! ```no_run
8//! use supermachine::{Image, Vm, VmConfig};
9//!
10//! // Load an already-baked snapshot (use the `supermachine` CLI to
11//! // bake one once: `supermachine run nginx:1.27-alpine --no-push`).
12//! let image = Image::from_snapshot("snapshots/nginx/restore.snap")?;
13//!
14//! // Spin up a microVM. Default VmConfig: 256 MiB, 1 vCPU,
15//! // auto-discovered kernel + init shim.
16//! let vm = Vm::start(&image, &VmConfig::new())?;
17//!
18//! // Talk to the guest via the host-side vsock-mux unix socket.
19//! // Bytes you write here proxy through to the first TSI listener
20//! // inside the guest (typically the workload's `:80`).
21//! let mut sock = vm.connect()?;
22//! use std::io::Write;
23//! sock.write_all(b"GET / HTTP/1.0\r\nHost: workload\r\n\r\n")?;
24//!
25//! vm.stop()?;
26//! # Ok::<(), supermachine::Error>(())
27//! ```
28//!
29//! ## Three integration patterns
30//!
31//! 1. **Shell out to the CLI** — exec `supermachine run IMAGE`.
32//! 2. **Long-lived router daemon** — start `supermachine-router`,
33//! talk HTTP to it. Process-isolated from your app.
34//! 3. **Embed this library directly** (this crate) — lowest
35//! latency, in-process VMM. Requires codesigning your binary;
36//! see [`assets::ENTITLEMENTS_PLIST`] and the
37//! `cargo-supermachine` plugin (`cargo install supermachine`).
38
39#![allow(dead_code)]
40
41// ---------- public API ----------
42
43pub mod assets;
44#[cfg(feature = "tokio")]
45#[path = "async.rs"]
46pub mod async_;
47// Worker CLI parsing + the vsock TSI token helpers. Needed on macOS (HVF worker)
48// and on Linux/x86 (the KVM backend mints + enforces a per-VM control token).
49#[cfg(any(target_os = "macos", all(target_os = "linux", target_arch = "x86_64")))]
50pub mod cli;
51pub mod codesign;
52#[cfg(target_os = "macos")]
53pub mod dedup;
54/// Cross-platform golden-base selection for snapshot dedup (macOS clonefile +
55/// Linux/KVM golden-base diff snapshots).
56pub mod snapshot_dedup;
57/// Linux/other stub — sibling-snapshot block dedup is an APFS `clonefile`
58/// optimization (host disk space, not VM latency). No-op where the snapshot FS
59/// has no reflink (e.g. ext4); a `FICLONE`-based dedup for btrfs/XFS hosts is a
60/// future enhancement. Callers stay platform-agnostic.
61#[cfg(not(target_os = "macos"))]
62pub mod dedup {
63 use std::path::Path;
64 pub fn auto_dedup_on_bake(
65 _snapshots_dir: &Path,
66 _fresh_snap_dir: &Path,
67 _image: &str,
68 _memory_mib: u32,
69 _baked_by_version: &str,
70 ) {
71 }
72}
73pub mod exec;
74pub mod memory_admission;
75mod net;
76pub mod spawn_concurrency;
77pub mod trace;
78
79mod api;
80pub use api::{
81 Error, Image, OciImageBuilder, Pool, PoolBuilder, PoolStats, PooledVm, PullPolicy,
82 TcpForwarder, Vm, VmConfig,
83};
84
85/// Internal wire-format helpers exposed for sibling crates that
86/// need to talk to the in-guest agent directly (specifically the
87/// napi binding in `npm/supermachine-core/`). The action JSON shape
88/// these support is internal — outside embedders should prefer
89/// [`Vm::write_file`] / [`Vm::read_file`] / [`Vm::exec`] which call
90/// these for you.
91pub mod wire {
92 pub use crate::api::{b64_decode, b64_encode};
93 pub use crate::exec::send_control_with_ack;
94}
95pub use assets::AssetPaths;
96pub use exec::{
97 ExecBuilder, ExecChild, ExecEof, ExecOutcome, ExecSignaler, ExecStderr, ExecStdin, ExecStdout,
98};
99pub use vmm::resources::{SymlinkPolicy, VolumeSpec};
100
101// ---------- internal modules used by the in-tree binaries ----------
102//
103// These are implementation modules for the CLI, router, and
104// bench-compare crates that ship inside this same workspace. They
105// aren't a stable public API: their shape changes as production
106// hardening lands (multi-vCPU, vsock auth tokens, snapshot format
107// revisions, KVM/WHP backends, …).
108//
109// We expose them through a single `internal` namespace so any
110// embedder reading the docs sees a clear "not for you" boundary.
111// If you reach into `supermachine::internal::*` from your own
112// crate, that's a deliberate choice; pin a specific git commit or
113// be ready for breakage on every minor.
114
115/// **Unstable internals.** Subject to breaking changes on every
116/// minor. The stable embedder API is at the crate root: [`Image`],
117/// [`Vm`], [`VmConfig`], [`AssetPaths`], [`Error`].
118///
119/// Exposed for the in-tree binaries (`supermachine-router`,
120/// `supermachine-bench-compare`) and for rare cases where the
121/// stable surface doesn't yet cover a need (raise an issue if so;
122/// the high-level types are designed to grow additive methods).
123pub mod internal {
124 /// VMM modules: device emulation, HVF wrappers, kernel loader,
125 /// VM lifecycle. The public API at the crate root sits on top
126 /// of these.
127 pub mod vmm {
128 pub use crate::vmm::*;
129 }
130 pub use crate::arch;
131 pub use crate::bake;
132 pub use crate::devices;
133 // HVF backend + the VM-execution stack only exist on a platform with a
134 // hypervisor backend (macOS/HVF today; KVM next — broaden this gate then).
135 #[cfg(all(target_os = "macos", target_arch = "aarch64"))]
136 pub use crate::hvf;
137 pub use crate::kernel;
138 pub use crate::utils;
139
140 #[cfg(all(target_os = "macos", target_arch = "aarch64"))]
141 pub use crate::vmm::pool::{
142 warm_pool, PoolClientError, PoolHandle, PoolRestoreResult, PoolWorker, WarmPool,
143 WarmPoolError, WarmRestoreTimings,
144 };
145 pub use crate::vmm::resources::{
146 EndpointResources, ResourceError, SnapshotResources, VmProfile, VmResources,
147 };
148 #[cfg(all(target_os = "macos", target_arch = "aarch64"))]
149 pub use crate::vmm::runner::{run, RunError, RunOptions, RunReport};
150 #[cfg(any(
151 all(target_os = "macos", target_arch = "aarch64"),
152 all(target_os = "linux", target_arch = "x86_64")
153 ))]
154 pub use crate::vmm::tls::TlsConfig;
155}
156
157// ---------- module declarations ----------
158//
159// We need the underlying modules `pub` so the `internal` re-exports
160// above resolve, and so the in-tree binaries that live in
161// `src/bin/` can use them across the lib boundary. Each is hidden
162// from rustdoc; consumers should reach for them only through
163// `supermachine::internal::*`.
164
165#[doc(hidden)]
166pub mod arch;
167#[doc(hidden)]
168pub mod bake;
169/// In-VM Dockerfile builder — parse + (later) snapshot-per-layer executor.
170#[doc(hidden)]
171pub mod builder;
172#[doc(hidden)]
173pub mod devices;
174/// FUSE-over-virtio wire protocol types. Shared between the virtio-fs
175/// device emulation and the host-side FUSE server. No logic — just the
176/// struct definitions matching `include/uapi/linux/fuse.h`. Will be
177/// promoted out of `doc(hidden)` once the mount API stabilizes.
178#[doc(hidden)]
179pub mod fuse;
180#[doc(hidden)]
181pub mod hvf;
182/// The portable hypervisor backend contract (HVF today, KVM next). See
183/// [`hypervisor::HypervisorVm`].
184#[doc(hidden)]
185pub mod hypervisor;
186#[doc(hidden)]
187pub mod kernel;
188/// KVM backend (Linux/x86_64) — sibling of `hvf`, implementing the same
189/// [`hypervisor`] seam. See [`kvm::KvmVm`].
190#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
191#[doc(hidden)]
192pub mod kvm;
193/// Portable snapshot-container substrate shared by both backends' snapshot
194/// pipelines: little-endian readers, count caps, RAM-region bounds checks, and
195/// the page-aligned copy-on-write RAM restore. Security-critical (a bug here is
196/// a host SIGBUS/OOB), so it lives in ONE audited place. See
197/// [`snapshot_frame`].
198#[doc(hidden)]
199pub mod snapshot_frame;
200#[doc(hidden)]
201pub mod utils;
202/// Portable run-loop convergence vocabulary (Phase 3 7b) — the shared
203/// per-exit [`vcpu_dispatch::VcpuOutcome`] both backends' vCPU loops speak.
204#[doc(hidden)]
205pub mod vcpu_dispatch;
206#[doc(hidden)]
207pub mod vmm;