pub enum AgentRequest {
Show 38 variants
Ping,
FsNotify {
events: Vec<FsNotifyEvent>,
},
Pull {
image: String,
oci_platform: Option<String>,
auth: Option<RegistryAuth>,
proxy: Option<String>,
no_proxy: Option<String>,
},
Query {
image: String,
},
ListImages,
GarbageCollect {
dry_run: bool,
purge_all: bool,
},
PrepareOverlay {
image: String,
workload_id: String,
},
CleanupOverlay {
workload_id: String,
},
FormatStorage,
StorageStatus,
MemoryStatus,
NetworkTest {
url: String,
},
Shutdown {
progress: bool,
},
ExportLayer {
image_digest: String,
layer_index: usize,
},
FlattenLayers {
lowerdirs: Vec<String>,
output: Option<String>,
},
BranchpointWait {
timeout_ms: u64,
},
BranchpointArm,
BranchpointPark,
BranchpointRelease {
env_dotenv: Option<String>,
},
BranchpointActivate {
env_dotenv: String,
env_sourceable: String,
env_path: String,
branch_env_path: String,
require_dir: Option<String>,
env_dir: String,
activation_token: String,
},
BranchpointWaitWorkerReady {
token: String,
timeout_ms: u64,
},
VmExec {
command: Vec<String>,
env: Vec<(String, String)>,
workdir: Option<String>,
timeout_ms: Option<u64>,
interactive: bool,
tty: bool,
background: bool,
stdin_data: Option<String>,
},
Run {Show 15 fields
image: String,
command: Vec<String>,
env: Vec<(String, String)>,
workdir: Option<String>,
user: Option<String>,
mounts: Vec<(String, String, bool)>,
timeout_ms: Option<u64>,
interactive: bool,
tty: bool,
detached: bool,
unprivileged: bool,
persistent_overlay_id: Option<String>,
stdin_data: Option<String>,
background: bool,
s3_volumes: Vec<S3Volume>,
},
Stdin {
data: Vec<u8>,
},
Resize {
cols: u16,
rows: u16,
},
FileWrite {
path: String,
data: Vec<u8>,
mode: Option<u32>,
uid: Option<u32>,
gid: Option<u32>,
},
FileWriteBegin {
path: String,
mode: Option<u32>,
uid: Option<u32>,
gid: Option<u32>,
total_size: u64,
},
FileWriteChunk {
data: Vec<u8>,
done: bool,
},
FileRead {
path: String,
},
ListDirectory {
path: String,
},
ArchiveDirectory {
path: String,
},
PodCreate {
id: String,
rootfs_rel: String,
spec_json: String,
tty: bool,
},
PodStart {
id: String,
exec_id: Option<String>,
},
PodExec {
id: String,
exec_id: String,
process_json: String,
tty: bool,
},
PodSignal {
id: String,
exec_id: Option<String>,
signal: u32,
all: bool,
},
PodPids {
id: String,
},
PodStats {
id: String,
},
PodDelete {
id: String,
exec_id: Option<String>,
},
}Expand description
Agent request types (for image management and OCI operations).
Variants§
Ping
Ping to check if agent is alive.
FsNotify
Inject host-originated fsnotify events into the guest.
virtiofs does not deliver host-side file changes to the guest as
fsnotify/inotify events, so inotify-based hot-reload (Vite, webpack,
nodemon) never fires when a mounted file is edited on the host. The host
watches the mount source and sends the resulting events here; the agent
writes them to /proc/smolvm-fsnotify, which fires the matching event on
the guest inode so watchers on the (bind-mounted) container path wake up.
Each path is a guest-side absolute path (the virtiofs staging path),
mask an fsnotify_mask::FS_* bitmask.
Fields
events: Vec<FsNotifyEvent>Host-originated filesystem changes to replay as guest fsnotify events.
Pull
Pull an OCI image and extract layers.
Fields
auth: Option<RegistryAuth>Optional registry authentication credentials.
Query
Query if an image exists locally.
ListImages
List all cached images.
GarbageCollect
Run garbage collection on unused layers.
Fields
PrepareOverlay
Prepare overlay rootfs for a workload.
CleanupOverlay
Clean up overlay rootfs for a workload.
FormatStorage
Format the storage disk (first-time setup).
StorageStatus
Get storage disk status.
MemoryStatus
Report the guest’s own view of machine memory, read from
/proc/meminfo.
The host cannot answer this. macOS charges the VMM’s phys_footprint
as internal + compressed, and the compressed part is counted at the
pages’ uncompressed size, so an idle guest whose memory has been
compressed reports a footprint several times the bytes it actually
occupies. Only the guest’s allocator knows what the machine is using.
NetworkTest
Test network connectivity directly from the agent (not via chroot). Used to debug TSI networking.
Shutdown
Shutdown the agent.
ExportLayer
Export a layer as a tar archive.
Used by smolvm pack to extract OCI layers for packaging.
The agent streams the layer tar data back via LayerData responses.
FlattenLayers
Merge a stack of directories into a single tar archive.
pack create --from-vm ships the machine’s image layers plus whatever the
container has written since as ONE flattened layer. The merge has to apply
whiteouts and opaque markers exactly as the runtime would, so it is done
with a read-only overlay mount rather than a file copy.
The agent owns this rather than the host driving mount(8) over VmExec,
because mount(8) rejects a lowerdir= value beyond ~255 bytes — about
three OCI layer paths — while the agent can append each layer separately
through the same fsconfig path the runtime container mount uses.
Fields
lowerdirs: Vec<String>Directories to merge, bottom -> top. Entries that are missing or empty are dropped, so a caller may include a container overlay’s upper dir without first checking whether the machine ever wrote to it.
output: Option<String>Guest path to write the tar archive to, or None to stream the
archive straight back as DataChunk responses.
Streaming is what a large export wants. The flattened tar is as large as the image it came from, so staging it in the guest means the disk has to hold both the expanded rootfs and a second full copy of it as an archive — the export sizes that disk by guessing, and a big enough image runs it out of space.
BranchpointWait
Wait until the workload has declared a branchpoint, returning the ready
marker’s contents (its profile lines) in data.contents.
BranchpointArm
Put a negotiated helper into its restore-safe loop before capture.
BranchpointPark
Return a parked source to its ordinary wait after capture.
BranchpointRelease
Release a restored clone: write the release marker for the generation recorded in its ready marker, carrying the clone’s identity, and wait for the helper to acknowledge.
BranchpointActivate
Assign and release a held clone in one idempotent step: claim it with
activation_token (a retry with the same token completes a partial
commit; a different token is refused), install the per-clone
parameters, then write the release marker.
Fields
BranchpointWaitWorkerReady
Wait until a released clone’s workload publishes its worker-ready token.
Fields
VmExec
Execute a command directly in the VM (not in a container).
This runs the command in the agent’s Alpine rootfs without any container isolation. Useful for VM-level operations and debugging.
Fields
Run
Run a command in an image’s rootfs.
This prepares an overlay, chroots into it, and executes the command. Returns stdout, stderr, and exit code when the command completes.
Fields
mounts: Vec<(String, String, bool)>Volume mounts to bind into the container. Each tuple is (virtiofs_tag, container_path, read_only).
timeout_ms: Option<u64>Timeout in milliseconds. If the command exceeds this duration, it will be killed and return exit code 124.
interactive: boolInteractive mode - stream I/O instead of buffering. When true, output is streamed via Stdout/Stderr responses, and stdin can be sent via the Stdin request.
tty: boolAllocate a pseudo-TTY for the command. Enables terminal features like colors, line editing, and signal handling.
detached: boolDetached mode — start the container and return immediately with the
container ID. Only meaningful when persistent_overlay_id is set.
Returns a Completed response with stdout containing the container ID.
unprivileged: boolRun the workload as an unprivileged container: restricted capabilities, read-only cgroup, and no extra tmpfs. The default (false) is “VM-grade” — since the microVM is the isolation boundary, the workload gets a full capability set and the mounts an init system needs (so any image, incl. systemd, boots). Opt in for defense-in-depth when running untrusted code.
persistent_overlay_id: Option<String>If set, use a persistent overlay that survives across exec sessions. The overlay is identified by this ID (typically the machine name) and reused on subsequent runs. If not set, an ephemeral overlay is created and destroyed after the run.
stdin_data: Option<String>Data to pipe to the command’s stdin (non-interactive runs only). The pipe is closed after writing, so the command sees EOF.
Stdin
Send stdin data to a running interactive command.
Resize
Resize the PTY window (for TTY mode).
FileWrite
Write a file inside the VM in a single message.
Use only for files up to FILE_WRITE_SINGLE_SHOT_MAX. Larger
files must stream via Self::FileWriteBegin +
Self::FileWriteChunk to avoid exceeding MAX_FRAME_SIZE
after base64 + JSON inflation.
Fields
FileWriteBegin
Open a streaming file upload session on this connection.
Must be followed by one or more Self::FileWriteChunk
requests. The final chunk sets done: true to finalize.
Dropping the connection (or sending any non-chunk request)
before done aborts the session and leaves no partial file
at path.
Sessions are per-connection — one session at a time.
Fields
total_size: u64Expected total size in bytes. Rejected if it exceeds
FILE_TRANSFER_MAX_TOTAL. The agent uses this for an
early-fail check only; the actual size written is the sum
of chunk byte lengths.
FileWriteChunk
Append a chunk to the currently open streaming upload.
If done is true, the agent fsyncs and atomically renames the
staging file onto the target path.
Fields
data: Vec<u8>Chunk bytes. Typically FILE_WRITE_CHUNK_SIZE except
for the last chunk.
FileRead
Read a file from the VM.
ListDirectory
List the entries of a guest directory.
Kept separate from AgentRequest::FileRead, which streams bytes: a
listing is small and structured, and a caller that has to discover what
exists would otherwise guess names and read a 404 for each miss.
ArchiveDirectory
Stream a tar archive of a guest directory without creating a guest-side temporary file. Used by staged mounts to batch many small files across vsock instead of paying one virtiofs round trip per file.
PodCreate
Create (without starting) a Kubernetes pod container whose rootfs is a
virtiofs-shared host directory (containerd snapshotter output) and whose
process definition comes from the host’s OCI config. The agent builds
its crun bundle around the shared rootfs; nothing runs until
PodStart. Part of the containerd shim v2 datapath
(docs/kubernetes-runtime.md).
Fields
rootfs_rel: StringRootfs path relative to the sandbox’s shared virtiofs mount. The
shim boots the sandbox VM with ONE shared dir and bind-mounts each
container’s rootfs under it (virtiofs shares are fixed at boot, but
pod containers are created afterwards), so the guest resolves this
as <sandbox-share-mount>/<rootfs_rel>.
PodStart
Start a pod container created by PodCreate (or an exec process
registered by PodExec), streaming its I/O on THIS connection:
Started → Stdout/Stderr… → Exited. Stdin arrives via Stdin
requests; PTY resize via Resize.
Fields
PodExec
Register an exec process for a running pod container. Started later by
PodStart { exec_id }.
Fields
PodSignal
Signal a pod container’s init process (or one exec process).
Fields
PodPids
List PIDs inside a pod container (guest view).
PodStats
Sample a pod container’s resource usage (guest view). The agent reads the container’s process tree from /proc (there is no per-container cgroup); the shim maps the reply into containerd’s cgroups metrics for CRI stats.
PodDelete
Remove a pod container’s (or exec process’s) guest resources after
exit: bundle, cgroup, PTY. Exit status was already streamed by
PodStart’s Exited.
Implementations§
Source§impl AgentRequest
impl AgentRequest
Sourcepub fn log_summary(&self) -> String
pub fn log_summary(&self) -> String
A log-safe one-line summary of the request.
This string is written to the machine’s console log, which is exposed
over the logs API — so it must NEVER include credential- or data-bearing
fields: registry auth, env (which can carry host-resolved secrets),
proxy (may embed credentials), or data (file/stdin bytes). Only the
variant name plus a non-secret identifier (image) is emitted.
The match is exhaustive with no catch-all on purpose: adding a new variant forces a compile error here, so redaction is a deliberate decision rather than an accidental leak in some future request type.