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 validated discovery snapshot without network I/O. GetCapabilities remains available for an explicit fresh observation. closed().await observes shared closure, including an idle framed disconnect; a successful JSON exchange ending in EOF does not close the session.
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§
- Capabilities
- Facilities available for this runtime and VM configuration.
- Client
- Cheap shared handle to one reader, writer, allocator, and set of subscriptions.
- Client
Error - Error with conservative delivery state. Diagnostics never include payloads.
- 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.
- 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.
- 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.
- RawFrame
- A frame with the binary header parsed but the body left untouched.
- Request
Options - Options for one request or stream-opening attempt.
- 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§
- 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
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_
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.
Traits§
- Checked
Control Request - Checked control requests sharing operation records across both formats.
- 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.
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.