Expand description
§Rust control client
ControlConnection discovers whether an existing control endpoint supports framed CBOR or legacy JSON. ControlClient is the explicitly framed Client<ControlProtocol> entry point, and JsonControlClient is an explicit legacy unary adapter. Their checked helpers share the same operation records.
ControlConnection -- JSON capabilities --+-- advertised CBOR: fresh stream + hello
| |
| ControlClient
|
+-- legacy: JsonControlClientAutomatic discovery has one deadline across the probe, redial, and hello. It selects CBOR only after a valid affirmative capability response. Malformed replies, arbitrary peer errors, empty EOF, and failed framed setup are errors. There is no error-string downgrade or mutation replay. ControlClient sends its hello directly when callers already know the peer supports framed control.
use microsandbox_control_client::{
ControlConnection, ControlMessageType, ControlReply, Empty, GetMemoryState, TypedMessage,
};
async fn inspect(path: &std::path::Path) -> Result<(), Box<dyn std::error::Error>> {
let connection = ControlConnection::connect(path).await?;
let reply = connection.request(TypedMessage::new(ControlMessageType::MemoryState, Empty {})).await?;
match reply {
ControlReply::Framed(message) => println!("{}", message.t),
ControlReply::Json(reply) => println!("{} original JSON bytes", reply.raw().len()),
}
println!("{} MiB", connection.request_typed(&GetMemoryState).await?.target_mib);
connection.close().await;
Ok(())
}In framed mode, clones reuse one connection. Automatic JSON mode rediscovers before each fresh exchange when its connector cannot prove runtime identity. An owner implementing VerifiedControlConnector verifies the connected peer and the runtime’s OS birth token on every dial, then rechecks the active run before each operation; connect_verified_connector can reuse that owner’s JSON selection. A path or PID alone is insufficient. A detected change invalidates the handle before sending instead of silently retargeting the request. The runtime owner, such as an SDK backend, supplies that identity implementation; the protocol package does not claim to verify it itself.
JsonControlClient::new(path) and from_connector(...) are inert constructors for callers explicitly choosing legacy mode. Its request translates only known native requests and returns the actual JsonReply, including ok:false replies. Checked helpers report LegacyRemote with the original reply and unknown batch progress. JSON numbers retain their original tokens; checked memory fields use u64 without a floating-point intermediate. connection.framed() fails locally in JSON mode, and encoded-payload input is rejected there before dialing. Raw streams and exact packets remain available on the explicitly framed client.
connection.capabilities() borrows the released generation-1 discovery projection without network I/O, while connection.runtime_capabilities() exposes the complete discovered facility set. GetCapabilities remains available for a fresh generation-1-compatible observation and GetRuntimeCapabilities requests the complete record on generation 2. closed().await observes shared closure, including an idle framed disconnect; a successful JSON exchange ending in EOF does not close the session.
Generation 1 remains the released capabilities, memory, CPU, and secrets surface. Generation 2 adds CreateCheckpoint, CreateDiskCheckpoint, CreateBranch, PauseRuntime, ResumeRuntime, GetPauseState, GrowRootDisk, and CompactDisks. ControlConnection talking to a framed generation-1 runtime selects the historical JSON representation for these checked operations before sending anything; it never retries a mutation after a framed failure. The explicit ControlClient instead returns a not-sent unsupported-operation error. Linux descriptor-backed branch creation remains an SDK-level JSON/SCM_RIGHTS exception because ordinary framed messages cannot transfer file descriptors.
Enable uds for Unix endpoint connections or named-pipe for Windows endpoint connections. Caller-owned transports and connectors can be used without either native feature. Endpoint paths are accepted verbatim.
use microsandbox_control_client::{
ControlClient, GetMemoryState, SetMemoryTarget, size::SizeExt,
};
async fn resize(path: &std::path::Path) -> Result<(), Box<dyn std::error::Error>> {
let client = ControlClient::connect(path).await?;
let before = client.request_typed(&GetMemoryState).await?;
let accepted = client.request_typed(&SetMemoryTarget::new(2048.mib())).await?;
println!("{} -> {} MiB", before.target_mib, accepted.target_mib);
client.close().await;
Ok(())
}Memory wire records retain u64 values. The existing size helpers retain their conversion rules; direct SetMemoryTarget { total_mib } construction provides full-width wire input. Target responses report acceptance and current observations, not guest convergence. Ordered secret batches preserve partial completion and the index of the first failed entry.
The client keeps request, stream, request_raw, stream_raw, explicit-ID send/send_raw, exact write_unchecked, owned into_parts, and checked request_typed operations. Generic requests return peer error frames as messages; checked helpers interpret them and retain the original response. No sandbox, execution, filesystem, or convergence service is required to use any of these paths.
use microsandbox_control_client::{ControlClient, EncodedMessage};
async fn inspect(client: &ControlClient, payload: Vec<u8>) -> Result<(), Box<dyn std::error::Error>> {
let response = client.request(EncodedMessage::new("extension.inspect", payload)).await?;
println!("{}: {} payload bytes", response.t, response.p.len());
Ok(())
}Setup defaults to one ten-second deadline and requests to a thirty-second local wait. Request expiry does not cancel remote work or trigger replay. ClientError retains NotSent versus Unknown delivery. Clones and owned streams share a connection; close closes it for all owners.
Run cargo test -p microsandbox-control-client --all-features --locked. For live tests, set MSB_CONTROL_TEST_SOCKET and MSB_CONTROL_TEST_MODE=cbor or json. The explicitly framed test requires CBOR; run only live_automatic_discovery_and_explicit_json -- --ignored --exact against a JSON-only runtime. Use bounded disposable fixtures (512 MiB and two CPUs), and run live tests serially. The automatic test changes targets and restores them through explicit JSON. Optional MSB_CONTROL_TEST_SECRET names a dummy fixture initially set to before and allowed for example.invalid; the test exercises legacy partial-failure reporting and restores that fixture. Skipped live tests are not runtime or platform validation.
Modules§
- size
- Byte-size types and conversion helpers.
Structs§
- Branch
Create - Capture directly into a reserved child-owned local handoff directory.
- Branch
Result - Completed direct local branch handoff.
- Capabilities
- Facilities available for this runtime and VM configuration.
- Checkpoint
Create - Create one same-epoch full checkpoint.
- Checkpoint
Result - Full-checkpoint completion, including a published result whose source recovery failed.
- Checkpoint
State - Published full-checkpoint state.
- Client
- Cheap shared handle to one reader, writer, allocator, and set of subscriptions.
- Client
Error - Error with conservative delivery state. Diagnostics never include payloads.
- Compact
Disks - Compact selected owned disk chains.
- Connect
Options - Connection configuration. Builders have no I/O or background side effects.
- Control
Connection - Shared discovery result and operation adapter. Standalone JSON connections rediscover before fresh exchanges unless a verified runtime owner is supplied.
- Control
Error - A recoverable peer error. Codes stay strings for future interoperability.
- Control
Hello - Opening framed-control offer. The envelope generation is always one.
- Control
Message Type Iter - An iterator over the variants of ControlMessageType
- Control
Protocol - Generation-one hello/welcome and operation metadata.
- Control
Ready - Negotiated limits and the exact original welcome envelope.
- Control
Welcome - Selected generation and limits. The welcome envelope is always generation one.
- CpuState
- CPU capacity, accepted target, observation, and enforcement.
- CpuTarget
- Native CPU-target payload.
- Create
Branch - Create one direct local branch without descriptor transfer.
- Create
Checkpoint - Create one full checkpoint.
- Create
Disk Checkpoint - Create one disk-only checkpoint.
- Disk
Checkpoint Create - Seal the owned root disk without capturing RAM or execution state.
- Disk
Checkpoint State - Complete disk-only capture result.
- Disk
Compact - Compact selected sandbox-owned disk chains.
- Empty
- Empty map payload for state and capability queries.
- Encoded
Message - Already-encoded application payload, separate from the outer envelope.
- GetCapabilities
- Query available host operations.
- GetCpu
State - Read CPU capacity, target, observation, and enforcement.
- GetMemory
State - Read accepted and observed memory quantities.
- GetPause
State - Inspect resident pause state.
- GetRuntime
Capabilities - Query the complete generation-two runtime facility inventory.
- Grow
Root Disk - Grow the owned root disk and filesystem.
- Json
Control Client - Explicit JSON adapter. Construction is inert; every call opens one stream.
- Json
Control Response - Existing JSON response with an additive discovery advertisement.
- Json
Number - An original JSON number token, including its integer precision and spelling.
- Json
Reply - One actual response line, retaining unknown fields and lossless numbers.
- Memory
State - Accepted and observed memory quantities, all in MiB.
- Memory
Target - Native memory-target payload, without SDK convergence policy.
- Message
- Decoded message with its original frame retained for unknown fields/forwarding.
- Pause
- Pause the runtime, optionally requiring guest writeback first.
- Pause
Runtime - Pause the runtime, optionally requiring guest writeback.
- Pause
State - Host-confirmed resident suspension state.
- RawFrame
- A frame with the binary header parsed but the body left untouched.
- Request
Options - Options for one request or stream-opening attempt.
- Resume
Runtime - Resume a resident pause.
- Root
Disk Grow - Grow the owned root disk and its mounted filesystem.
- Root
Disk State - Verified root-disk growth and measured phases.
- Runtime
Capabilities - Complete generation-two runtime facility inventory.
- Secret
Value - Secret material that is redacted in diagnostics and cleared on drop.
- Secrets
Update - Sequential, non-transactional secret modifications.
- SetCpu
Target - Set a CPU target without waiting for guest convergence.
- SetMemory
Target - Set a memory target without waiting for guest convergence.
- Typed
Message - Native payload paired with an explicit wire name; this is not schema proof.
- Update
Secrets - Apply ordered secret changes, preserving partial completion in the result.
Enums§
- Checkpoint
Capture Intent - Purpose of a full checkpoint capture.
- Control
Client Error - Operation failure distinct from generic routing and application observations.
- Control
Message Type - Known control wire names. The strum spelling is the authoritative mapping.
- Control
Mode - Operation format selected during this connection’s setup.
- Control
Operation - One decoded application operation across all negotiated control generations.
- Control
Reply - The actual reply format. JSON never receives synthetic IDs or CBOR bytes.
- Control
Request - Legacy JSON request, also used as a checked dispatch representation.
- Delivery
- Whether this attempt crossed writer admission; never a retry instruction.
- Error
Effect - State mutation certainty reported by an operation error.
- Error
Kind - Transport/router failure, independent of application response errors.
- Json
Value - Inspectable JSON that preserves number tokens and rejects duplicate keys.
- Secret
Change - One ordered host secret modification, preserving the JSON operation tags.
- Secrets
Result - Completion of a sequential secret batch.
Constants§
- CONTROL_
GENERATION - Current framed host-control generation.
- CONTROL_
GENERATION_ TWO_ MESSAGES - Application messages introduced by framed control generation two.
- CONTROL_
HANDSHAKE_ GENERATION - Stable generation of hello, welcome, and setup errors.
- CONTROL_
PROTOCOL - Stable protocol discriminator; it does not authenticate a peer.
- DEFAULT_
MAX_ IN_ FLIGHT - Maximum outstanding control IDs on a default connection.
- DEFAULT_
REQUEST_ TIMEOUT - Default local request wait, which never cancels or retries a mutation.
- DEFAULT_
SETUP_ TIMEOUT - Default deadline for the complete automatic connection setup.
- MAX_
DISCOVERY_ RESPONSE_ SIZE - Bound applies to new-client discovery replies, not legacy request lines.
- MAX_
HANDSHAKE_ FRAME_ SIZE - The opening frame stays small and zero-prefixed across future generations.
- MIN_
CONTROL_ GENERATION - Oldest framed host-control generation retained for released 0.7.x peers.
Traits§
- Checked
Control Request - Checked control requests sharing operation records across both formats.
- Compatible
Control Request - A checked request that can select framed CBOR or the historical JSON representation.
- Connector
- Opens independent transports, without negotiation or application parsing.
- Into
Control Message - Named messages that can choose a real framed or legacy representation.
- Request
- Pair a prepared protocol request with checked terminal-response decoding.
- Verified
Control Connector - A connector that binds every returned stream to one verified runtime.
Functions§
- control_
message_ min_ generation - Generation in which a known application message first became available.
Type Aliases§
- Control
Client - Always-framed host control, including the full generic low-level surface.
- Control
Client Result - Result from an optional checked control operation.
- Disk
Compaction Result - Aggregate disk-compaction result shared with SDK-facing types.