pub struct DockerBackend { /* private fields */ }Expand description
Drives the Docker daemon over DockerClient. See the module docs for the shape.
Implementations§
Source§impl DockerBackend
impl DockerBackend
Sourcepub fn connecting_to_env() -> Self
pub fn connecting_to_env() -> Self
Builds a backend pointed at the daemon DOCKER_HOST (or the default socket)
names — the same resolution crate::DockerBackendProvider’s create uses,
exposed directly for callers that want a concrete DockerBackend without
going through rightsize::backends::resolve (integration tests, mainly).
Trait Implementations§
Source§impl SandboxBackend for DockerBackend
impl SandboxBackend for DockerBackend
Source§fn find_running<'life0, 'life1, 'async_trait>(
&'life0 self,
spec: &'life1 ContainerSpec,
) -> Pin<Box<dyn Future<Output = Result<Option<Box<dyn SandboxHandle>>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn find_running<'life0, 'life1, 'async_trait>(
&'life0 self,
spec: &'life1 ContainerSpec,
) -> Pin<Box<dyn Future<Output = Result<Option<Box<dyn SandboxHandle>>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
GET /containers/json?filters={"name":["^/<name>$"],"status":["running"]} —
the reuse adopt path’s own query (rightsize::reuse). The name filter is
anchored the same way blocking_find_container_id_by_name anchors it
(Docker’s name filter is substring-by-default); status is explicit
rather than relying on the daemon’s own “no all=true” default meaning
running-only, so the intent reads directly off the request. Ok(None) for
no match OR a non-200 response — matching this backend’s other best-effort
list-then-not-found reads (e.g. lookup_network_id_by_name).
Source§fn create_checkpoint<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
nonce: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn create_checkpoint<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
nonce: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
POST /commit?container=&repo=&tag= — the checkpoint feature’s own backend
primitive (rightsize::ContainerGuard::checkpoint). Formats nonce (a
random 12-lowercase-hex string the generic layer generates fresh per call)
into this backend’s own ref shape, rightsize/checkpoint:<nonce>, splitting
it into the repo/tag pair the endpoint wants (the same split
split_repo_tag already does for image pulls), and returns the ref.
Source§fn remove_checkpoint<'life0, 'life1, 'async_trait>(
&'life0 self,
checkpoint_ref: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn remove_checkpoint<'life0, 'life1, 'async_trait>(
&'life0 self,
checkpoint_ref: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
DELETE /images/{ref}?force=true — best-effort; a 404 (already gone) is
success, matching Self::remove_by_name’s own “not found is fine”
contract.
Source§fn has_checkpoint<'life0, 'life1, 'async_trait>(
&'life0 self,
checkpoint_ref: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn has_checkpoint<'life0, 'life1, 'async_trait>(
&'life0 self,
checkpoint_ref: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
GET /images/{ref}/json — the named-checkpoint existence probe
(SandboxBackend::has_checkpoint, Checkpoint::find’s staleness check).
A 200 means the tagged image still exists; a 404 is a definite “not
there.” Any OTHER status (or a transport-level request failure, via the
? above) surfaces as an error — this SPI forbids a probe failure from
resolving to “absent,” unlike Self::pull_if_missing’s own inspect,
which only reacts to affirmatively-404 and doesn’t fail loudly on
inspect trouble.
Source§fn copy_to_container<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
host_path: &'life2 Path,
container_path: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn copy_to_container<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
host_path: &'life2 Path,
container_path: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Shells out to the docker CLI (docker cp <host_path> <id>:<container_path>)
rather than the daemon HTTP API this backend otherwise speaks exclusively —
the daemon’s copy endpoints are tar-archive-in/tar-archive-out, and adding
tar encode/decode here would mean either a new third-party dependency or a
hand-rolled tar implementation, both worse than shelling out. The docker
CLI is already a hard requirement for this backend regardless (the reaping
watchdog’s own kill command is a plain docker rm -f), so this adds no new
external dependency.
Source§fn copy_from_container<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
container_path: &'life2 str,
host_path: &'life3 Path,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn copy_from_container<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
container_path: &'life2 str,
host_path: &'life3 Path,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
The reverse direction of Self::copy_to_container, same docker cp
shape and error-surfacing.
Source§fn name(&self) -> &str
fn name(&self) -> &str
"docker" / "microsandbox" — shown in errors and
matched against RIGHTSIZE_BACKEND.Source§fn supports_native_networks(&self) -> bool
fn supports_native_networks(&self) -> bool
SandboxBackend::install_network_links).Source§fn capabilities(&self) -> Capabilities
fn capabilities(&self) -> Capabilities
Capabilities). Default: neither
hardware-isolated nor checkpoint-capable — the conservative answer for a test
double or any backend that hasn’t opted into either; both real backends (msb,
docker) override this with their real values.Source§fn create<'life0, 'async_trait>(
&'life0 self,
spec: ContainerSpec,
) -> Pin<Box<dyn Future<Output = Result<Box<dyn SandboxHandle>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn create<'life0, 'async_trait>(
&'life0 self,
spec: ContainerSpec,
) -> Pin<Box<dyn Future<Output = Result<Box<dyn SandboxHandle>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
spec. spec.ports are already
chosen — this call binds them, it never allocates.Source§fn start<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn start<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
SandboxBackend::create.Source§fn stop<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn stop<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn remove<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn remove<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn exec<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
cmd: &'life2 [String],
) -> Pin<Box<dyn Future<Output = Result<ExecResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn exec<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
cmd: &'life2 [String],
) -> Pin<Box<dyn Future<Output = Result<ExecResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
cmd inside the running container and returns its exit code plus captured
output.Source§fn logs<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn logs<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn follow_logs<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
consumer: Box<dyn Fn(String) + Send + Sync>,
) -> Pin<Box<dyn Future<Output = Result<FollowHandle>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn follow_logs<'life0, 'life1, 'async_trait>(
&'life0 self,
handle: &'life1 dyn SandboxHandle,
consumer: Box<dyn Fn(String) + Send + Sync>,
) -> Pin<Box<dyn Future<Output = Result<FollowHandle>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
consumer as they arrive. Read moreSource§fn ensure_network<'life0, 'life1, 'async_trait>(
&'life0 self,
network_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn ensure_network<'life0, 'life1, 'async_trait>(
&'life0 self,
network_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn remove_network<'life0, 'life1, 'async_trait>(
&'life0 self,
network_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn remove_network<'life0, 'life1, 'async_trait>(
&'life0 self,
network_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn close<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn close<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn cleanup_sync(&self, container_id: &str)
fn cleanup_sync(&self, container_id: &str)
Drop-path cleanup thread (see
crate::cleanup). Given a container id/name, tears it down with blocking std I/O
only — never Tokio, never block_on — because this runs on a dedicated OS thread
with no async runtime in context. Called only from that thread, never from async
code.Source§fn remove_by_name(&self, name: &str)
fn remove_by_name(&self, name: &str)
SandboxHandle carries — the shape the reaping ledger
needs, since it persists names (ContainerSpec::name), never ids (see
crate::reaper). “Not found” is expected and must be silently ignored —
sweeps are idempotent and may race another process’s sweep of the same
leftover. Read moreSource§fn watchdog_kill_command(&self) -> Vec<String>
fn watchdog_kill_command(&self) -> Vec<String>
<word>... <sandbox-name> (the name is appended as the final argument at call
time). Must be self-sufficient: the watchdog is a standalone process with no
access to anything living only inside this process (no in-memory client, no
open socket this process owned) — see crate::reaper::watchdog.Source§fn watchdog_network_kill_command(&self) -> Vec<String>
fn watchdog_network_kill_command(&self) -> Vec<String>
Self::watchdog_kill_command, for removing a network by id.
Default empty — “nothing to do” — for backends with no real network resource
to remove externally (e.g. microsandbox, whose networking is emulated and
creates nothing at the backend level).Source§fn install_network_links<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_handle: &'life1 dyn SandboxHandle,
_links: &'life2 [NetworkLink],
) -> Pin<Box<dyn Future<Output = Result<(), RightsizeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn install_network_links<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_handle: &'life1 dyn SandboxHandle,
_links: &'life2 [NetworkLink],
) -> Pin<Box<dyn Future<Output = Result<(), RightsizeError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
start, before the wait strategy runs, to make links reachable
from handle by alias. Read moreSource§fn backend_binary_path(&self) -> Option<PathBuf>
fn backend_binary_path(&self) -> Option<PathBuf>
msbPath in the
cross-language JSON schema) so a same-language sweep or diagnostic can
identify exactly which toolchain a dead run used. Default None for backends
with no such on-disk binary (docker, which talks to a daemon socket).