Skip to main content

Crate microsandbox_control_client

Crate microsandbox_control_client 

Source
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: JsonControlClient

Automatic 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.
ClientError
Error with conservative delivery state. Diagnostics never include payloads.
ConnectOptions
Connection configuration. Builders have no I/O or background side effects.
ControlConnection
Shared discovery result and operation adapter. Standalone JSON connections rediscover before fresh exchanges unless a verified runtime owner is supplied.
ControlError
A recoverable peer error. Codes stay strings for future interoperability.
ControlHello
Opening framed-control offer. The envelope generation is always one.
ControlMessageTypeIter
An iterator over the variants of ControlMessageType
ControlProtocol
Generation-one hello/welcome and operation metadata.
ControlReady
Negotiated limits and the exact original welcome envelope.
ControlWelcome
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.
EncodedMessage
Already-encoded application payload, separate from the outer envelope.
GetCapabilities
Query available host operations.
GetCpuState
Read CPU capacity, target, observation, and enforcement.
GetMemoryState
Read accepted and observed memory quantities.
JsonControlClient
Explicit JSON adapter. Construction is inert; every call opens one stream.
JsonControlResponse
Existing JSON response with an additive discovery advertisement.
JsonNumber
An original JSON number token, including its integer precision and spelling.
JsonReply
One actual response line, retaining unknown fields and lossless numbers.
MemoryState
Accepted and observed memory quantities, all in MiB.
MemoryTarget
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.
RequestOptions
Options for one request or stream-opening attempt.
SecretValue
Secret material that is redacted in diagnostics and cleared on drop.
SecretsUpdate
Sequential, non-transactional secret modifications.
SetCpuTarget
Set a CPU target without waiting for guest convergence.
SetMemoryTarget
Set a memory target without waiting for guest convergence.
TypedMessage
Native payload paired with an explicit wire name; this is not schema proof.
UpdateSecrets
Apply ordered secret changes, preserving partial completion in the result.

Enums§

ControlClientError
Operation failure distinct from generic routing and application observations.
ControlMessageType
Known control wire names. The strum spelling is the authoritative mapping.
ControlMode
Operation format selected during this connection’s setup.
ControlReply
The actual reply format. JSON never receives synthetic IDs or CBOR bytes.
ControlRequest
Legacy JSON request, also used as a checked dispatch representation.
Delivery
Whether this attempt crossed writer admission; never a retry instruction.
ErrorEffect
State mutation certainty reported by an operation error.
ErrorKind
Transport/router failure, independent of application response errors.
JsonValue
Inspectable JSON that preserves number tokens and rejects duplicate keys.
SecretChange
One ordered host secret modification, preserving the JSON operation tags.
SecretsResult
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§

CheckedControlRequest
Checked control requests sharing operation records across both formats.
Connector
Opens independent transports, without negotiation or application parsing.
IntoControlMessage
Named messages that can choose a real framed or legacy representation.
Request
Pair a prepared protocol request with checked terminal-response decoding.
VerifiedControlConnector
A connector that binds every returned stream to one verified runtime.

Type Aliases§

ControlClient
Always-framed host control, including the full generic low-level surface.
ControlClientResult
Result from an optional checked control operation.