pub struct Session { /* private fields */ }Expand description
The control API of one running MicroVM.
Clone shares the transport, including the cached proxy token, so a clone moved into a
background task (a keepalive) sees the same refresh a resume triggers.
Implementations§
Source§impl Session
impl Session
Sourcepub async fn run_to_completion(
&self,
request: StartRequest,
options: CompletionOptions,
on_output: Option<Box<dyn FnMut(ExecEvent) -> Pin<Box<dyn Future<Output = ControlFlow<()>> + Send>> + Send>>,
) -> Result<ExecResult, Error>
pub async fn run_to_completion( &self, request: StartRequest, options: CompletionOptions, on_output: Option<Box<dyn FnMut(ExecEvent) -> Pin<Box<dyn Future<Output = ControlFlow<()>> + Send>> + Send>>, ) -> Result<ExecResult, Error>
Starts request and drives it to exactly one result. See the module docs.
Source§impl Session
impl Session
Sourcepub fn launch_metrics(&self) -> Option<LaunchMetrics>
pub fn launch_metrics(&self) -> Option<LaunchMetrics>
Launch observations, or None when this session did not originate from a launch.
Sourcepub fn agent_token(&self) -> &str
pub fn agent_token(&self) -> &str
The bearer this session authenticates with.
Public because a caller who launched with a minted token needs to read it back
to reattach later (the Python oracle’s Session.agent_token property, and what
the CLI’s run envelope publishes for microvm exec --agent-token). The value is
still kept out of Debug — readable on purpose is different from printed by
accident.
Sourcepub fn builder(
endpoint: impl Into<String>,
agent_token: impl Into<String>,
) -> SessionBuilder
pub fn builder( endpoint: impl Into<String>, agent_token: impl Into<String>, ) -> SessionBuilder
A builder, for the cases that need a port, a timeout, or a custom backend.
Session::connect, Session::attach and Session::direct are in
microvms_core::prelude, because they build the production HTTP backend (and attach a
signed control plane), which is I/O this module leaves to its caller.
Sourcepub fn egress_posture(&self) -> EgressPosture
pub fn egress_posture(&self) -> EgressPosture
The egress posture of the launch this session addresses (BIND-12).
The value the CLI envelope’s egressPosture reports for the same launch options, set
by crate::sandbox::Sandbox::run from crate::control::egress_posture_for. A
session that does not hold its launch options (attached, direct, or adopted) reports
unsealed, the weakest true claim. Never sealed: see
crate::control::egress_posture_for for the evidence that needs.
Sourcepub fn proxy_auth(&self) -> Option<&Arc<ProxyAuth>>
pub fn proxy_auth(&self) -> Option<&Arc<ProxyAuth>>
The proxy auth, for a caller that needs the mint count or an invalidation.
Sourcepub async fn connect_headers(
&self,
port: u16,
) -> Result<Vec<(String, String)>, Error>
pub async fn connect_headers( &self, port: u16, ) -> Result<Vec<(String, String)>, Error>
Both proxy headers for port, minted through this session’s token cache.
The {url, headers} half of a port-endpoint resolution: pair these with
Self::endpoint and a caller can open its own connection with no knowledge of how
the token is minted or when it refreshes.
Empty for a direct session, which is the correct answer rather than a missing one:
a daemon reached directly takes no proxy headers, so an empty set is exactly what its
requests carry today (see Transport::proxy).
The auth value is a bearer credential and this returns it. Nothing in this crate logs or stores the result.
Sourcepub async fn connect_subprotocols(
&self,
port: u16,
) -> Result<Option<[String; 3]>, Error>
pub async fn connect_subprotocols( &self, port: u16, ) -> Result<Option<[String; 3]>, Error>
The three WebSocket subprotocols for port, minted through this session’s token
cache.
None for a direct session, and that is deliberately not an empty list: the
subprotocol form exists only because a request through the endpoint proxy cannot set
headers, so there is nothing for a directly-reached daemon to offer, and a caller
handed ["lambda-microvms"] with no token would open a handshake that is refused for a
reason naming neither.
See ProxyAuth::subprotocols for the wire format and for the platform’s stripping
behaviour. The middle value carries the credential.
Sourcepub fn rebind(&mut self, endpoint: String)
pub fn rebind(&mut self, endpoint: String)
Points the session at a new endpoint and drops the cached proxy token (STATE-8).
The measured behaviour is that the endpoint URL does not change across suspend/resume, so this is usually a no-op on the URL — but the token drop is not: a token minted against the pre-suspend instance may no longer validate, and that rejection reads exactly like a dead daemon.
Takes &mut self because it changes where the session points, which is not
something a shared reference should be able to do mid-request. The invalidation
itself is &self on ProxyAuth, so a resume path holding only the auth can
still drop the token.
Sourcepub async fn health(&self) -> Result<Health, Error>
pub async fn health(&self) -> Result<Health, Error>
Unauthenticated liveness. bootstrapped is the useful field.
Reachable through the endpoint at all implies bootstrapped in practice — the platform forwards no external traffic until the run hook returns 200 — but a caller inside the VM, or one talking to the daemon directly, can observe the pre-bootstrap state.
Sourcepub async fn discovery(&self) -> Result<Option<Discovery>, Error>
pub async fn discovery(&self) -> Result<Option<Discovery>, Error>
Discover image configuration without changing the published health response.
None means the daemon predates discovery (HTTP 404). A present response
with an explicit null default_user means the historical daemon/root default. Authentication,
transport and malformed response errors remain errors, never guessed defaults.
Sourcepub async fn keep_awake(
&self,
policy: &KeepAwake,
stop: impl Future<Output = ()>,
) -> Result<KeepAwakeReport, Error>
pub async fn keep_awake( &self, policy: &KeepAwake, stop: impl Future<Output = ()>, ) -> Result<KeepAwakeReport, Error>
Keeps the VM awake by polling health until stop resolves or the policy ends it.
See keepalive: idleness is inbound traffic only, so this is the supported way to
hold a VM up while an exec works without client traffic.
Sourcepub async fn wait_until_ready(&self, timeout: Duration) -> Result<Health, Error>
pub async fn wait_until_ready(&self, timeout: Duration) -> Result<Health, Error>
Polls health until the daemon reports bootstrapped.
Connection errors are expected here rather than exceptional: a VM that has just reached RUNNING commonly refuses a connection or two before the proxy path is wired up, and a mint failure is retryable by construction. A fatal error ends the wait immediately — retrying a 401 until the deadline is one of the two mistakes the retryable split exists to prevent.
Sourcepub async fn run(&self, req: StartRequest) -> Result<ExecHandle, Error>
pub async fn run(&self, req: StartRequest) -> Result<ExecHandle, Error>
Starts a command and returns its handle. Does not wait.
The exec_id on the request is the idempotency key. The daemon returns success
for a known id without spawning a second child, so a caller whose retry must be
safe across its own restart supplies a stable one.
poweroff_on_exit requires the daemon’s support header before starting.
It can end every workload in the VM and race delivery of this call’s
acknowledgment or later output. It does not keep an idle VM awake.
Sourcepub fn exec(&self, exec_id: impl Into<String>) -> ExecHandle
pub fn exec(&self, exec_id: impl Into<String>) -> ExecHandle
A handle for an exec started earlier, possibly by another process.
Sourcepub async fn run_sync(
&self,
req: StartRequest,
timeout: Duration,
) -> Result<ExecResult, Error>
pub async fn run_sync( &self, req: StartRequest, timeout: Duration, ) -> Result<ExecResult, Error>
Start, wait, ack. The one-shot shape, for when output is all you want.
Sourcepub async fn kill(&self, exec_id: &str) -> Result<bool, Error>
pub async fn kill(&self, exec_id: &str) -> Result<bool, Error>
Signals an exec’s whole process group. Returns whether anything was signalled.
Sourcepub async fn procs(&self) -> Result<ProcsResponse, Error>
pub async fn procs(&self) -> Result<ProcsResponse, Error>
Process accounting: every registered exec with its group’s live pids.
The daemon reads /proc itself, so this works against a guest with no ps.
child_exited: true beside a non-empty pids is a command that finished while
something it backgrounded did not; the exec_id beside it is what Self::kill
takes. Bearer-guarded, unlike Self::health: the answer names every pid in the
guest, and a caller without the token has no business with it.
Sourcepub async fn upload_file(
&self,
path: &str,
data: &[u8],
mode: Option<&str>,
) -> Result<(), Error>
pub async fn upload_file( &self, path: &str, data: &[u8], mode: Option<&str>, ) -> Result<(), Error>
Writes one file, creating parents. mode is octal as a string.
Sourcepub async fn download_file_lines(
&self,
path: &str,
start_line: Option<u64>,
end_line: Option<u64>,
) -> Result<Vec<u8>, Error>
pub async fn download_file_lines( &self, path: &str, start_line: Option<u64>, end_line: Option<u64>, ) -> Result<Vec<u8>, Error>
Reads lines start_line through end_line of one file, 1-based and inclusive, sliced
by the daemon. Either bound may be absent (line 1, through EOF), and both absent is
Self::download_file’s request. Line 0 and an inverted range are refused with
ERR_INVALID_ARG before any request.
Sourcepub async fn file_exists(&self, path: &str) -> Result<bool, Error>
pub async fn file_exists(&self, path: &str) -> Result<bool, Error>
Whether a path exists, distinguishing absence from every other refusal.
Source§impl Session
impl Session
Sourcepub async fn sync_manifest(&self) -> Result<Option<Manifest>, Error>
pub async fn sync_manifest(&self) -> Result<Option<Manifest>, Error>
The manifest the last sync left in the guest, or None when there’s none.
A manifest that doesn’t parse reads as None too: a different version, or a workload,
wrote that path, and the safe reading of “can’t tell what’s over there” is the same as
“nothing is”: a full upload, which writes a manifest this build understands.
Sourcepub async fn sync_dir(
&self,
tree: &dyn LocalTree,
dir: &Path,
full: bool,
delete_timeout: Duration,
) -> Result<SyncPass, Error>
pub async fn sync_dir( &self, tree: &dyn LocalTree, dir: &Path, full: bool, delete_timeout: Duration, ) -> Result<SyncPass, Error>
Syncs dir into REMOTE_WORKDIR once: against the guest’s own manifest, or with
full against none, so everything travels. Self::sync_manifest then
Self::sync_pass, the whole of a one-shot sync.
Sourcepub async fn sync_pass(
&self,
tree: &dyn LocalTree,
dir: &Path,
baseline: Option<Manifest>,
delete_timeout: Duration,
) -> Result<SyncPass, Error>
pub async fn sync_pass( &self, tree: &dyn LocalTree, dir: &Path, baseline: Option<Manifest>, delete_timeout: Duration, ) -> Result<SyncPass, Error>
One incremental pass of dir into REMOTE_WORKDIR: hash, diff against baseline,
upload what changed, delete what vanished, and rewrite the guest manifest.
baseline is what the guest holds, usually Self::sync_manifest’s answer or the
last pass’s SyncPass::manifest; None uploads everything. The deletions run as one
rm -rf -- in the guest with delete_timeout as the daemon’s deadline, and a failed
one fails the pass with the guest manifest left as it was, so the next pass orders the
deletions again. Only deletable paths are removed.
Sourcepub async fn download_dir(
&self,
tree: &dyn LocalTree,
remote: &str,
globs: &[String],
dir: &Path,
) -> Result<Vec<Artifact>, Error>
pub async fn download_dir( &self, tree: &dyn LocalTree, remote: &str, globs: &[String], dir: &Path, ) -> Result<Vec<Artifact>, Error>
The tree at remote in the guest, written under dir through LocalTree::extract:
only the regular files globs select, never under .git, never outside dir.
The daemon packs the tree (GET /v1/fs/tar), so members are relative to remote.
Trait Implementations§
Source§impl SessionExt for Session
impl SessionExt for Session
Source§fn connect(
endpoint: impl Into<String>,
agent_token: impl Into<String>,
minter: Arc<dyn TokenMinter>,
) -> impl Future<Output = Result<Self, Error>> + Send
fn connect( endpoint: impl Into<String>, agent_token: impl Into<String>, minter: Arc<dyn TokenMinter>, ) -> impl Future<Output = Result<Self, Error>> + Send
Source§fn attach(
region: Region,
microvm_id: impl Into<String>,
endpoint: impl Into<String>,
agent_token: impl Into<String>,
port: Option<u16>,
request_timeout: Option<Duration>,
) -> impl Future<Output = Result<Self, Error>> + Send
fn attach( region: Region, microvm_id: impl Into<String>, endpoint: impl Into<String>, agent_token: impl Into<String>, port: Option<u16>, request_timeout: Option<Duration>, ) -> impl Future<Output = Result<Self, Error>> + Send
Auto Trait Implementations§
impl !RefUnwindSafe for Session
impl !UnwindSafe for Session
impl Freeze for Session
impl Send for Session
impl Sync for Session
impl Unpin for Session
impl UnsafeUnpin for Session
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more