pub(crate) mod archive;
mod attach;
pub(crate) mod box_impl;
mod clone_export;
pub(crate) mod config;
pub mod copy;
mod crash_report;
mod exec;
mod init;
pub(crate) mod local_snapshot;
mod manager;
mod network;
pub(crate) mod ports;
mod snapshot;
pub(crate) mod snapshot_mgr;
mod state;
mod watcher;
pub use attach::AttachOptions;
pub use copy::{CopyOptions, CopySourceKind};
pub(crate) use crash_report::CrashReport;
pub use exec::{BoxCommand, ExecResult, ExecStderr, ExecStdin, ExecStdout, Execution, ExecutionId};
pub(crate) use manager::BoxManager;
pub use network::{
BoxConnection, BoxReader, BoxTunnel, BoxWriter, NetworkHandle, SocketAddress, TunnelForwarder,
};
pub use snapshot::SnapshotHandle;
pub use state::{BoxState, BoxStatus, HealthState, HealthStatus};
pub(crate) use box_impl::SharedBoxImpl;
pub(crate) use init::BoxBuilder;
pub(crate) use local_snapshot::LocalSnapshotBackend;
use std::path::Path;
use std::sync::Arc;
use crate::metrics::BoxMetrics;
use crate::runtime::backend::{BoxBackend, BoxNetworkBackend, SnapshotBackend};
use crate::runtime::options::{BoxArchive, CloneOptions, ExportOptions};
use crate::{BoxID, BoxInfo};
use boxlite_shared::errors::{BoxliteError, BoxliteResult};
pub use config::BoxConfig;
pub struct LiteBox {
id: BoxID,
name: Option<String>,
box_backend: Arc<dyn BoxBackend>,
network_backend: Arc<dyn BoxNetworkBackend>,
snapshot_backend: Arc<dyn SnapshotBackend>,
}
impl LiteBox {
pub(crate) fn new(
box_backend: Arc<dyn BoxBackend>,
network_backend: Arc<dyn BoxNetworkBackend>,
snapshot_backend: Arc<dyn SnapshotBackend>,
) -> Self {
let id = box_backend.id().clone();
let name = box_backend.name().map(|s| s.to_string());
Self {
id,
name,
box_backend,
network_backend,
snapshot_backend,
}
}
pub fn id(&self) -> &BoxID {
&self.id
}
pub fn name(&self) -> Option<&str> {
self.name.as_deref()
}
pub async fn info(&self) -> BoxliteResult<BoxInfo> {
self.box_backend.info().await
}
pub async fn start(&self) -> BoxliteResult<()> {
self.box_backend.start().await
}
pub async fn exec(&self, command: BoxCommand) -> BoxliteResult<Execution> {
self.box_backend.exec(command).await
}
pub async fn attach(&self, options: AttachOptions) -> BoxliteResult<Execution> {
self.box_backend.attach(options).await
}
pub async fn metrics(&self) -> BoxliteResult<BoxMetrics> {
self.box_backend.metrics().await
}
pub async fn stop(&self) -> BoxliteResult<()> {
self.box_backend.stop().await
}
pub async fn copy_into(
&self,
host_src: impl AsRef<Path>,
container_dst: impl AsRef<str>,
opts: copy::CopyOptions,
) -> BoxliteResult<()> {
self.box_backend
.copy_into(host_src.as_ref(), container_dst.as_ref(), opts)
.await
}
pub async fn copy_out(
&self,
container_src: impl AsRef<str>,
host_dst: impl AsRef<Path>,
opts: copy::CopyOptions,
) -> BoxliteResult<()> {
self.box_backend
.copy_out(container_src.as_ref(), host_dst.as_ref(), opts)
.await
}
pub fn copy_in_stream<S>(
&self,
stream: S,
container_dst: &str,
source: copy::CopySourceKind,
opts: copy::CopyOptions,
) -> futures::future::BoxFuture<'static, BoxliteResult<()>>
where
S: futures::Stream<Item = std::io::Result<Vec<u8>>> + Send + 'static,
{
let backend = self
.box_backend
.clone()
.as_any_arc()
.downcast::<box_impl::BoxImpl>();
let dst = container_dst.to_string();
Box::pin(async move {
let backend = backend.map_err(|_| {
BoxliteError::Unsupported("streaming copy-in requires the local backend".into())
})?;
backend.copy_in_stream(stream, dst, source, opts).await
})
}
pub fn copy_out_stream(
&self,
container_src: &str,
opts: copy::CopyOptions,
) -> futures::future::BoxFuture<
'static,
BoxliteResult<(boxlite_shared::BoxByteStream, copy::CopySourceKind)>,
> {
let backend = self
.box_backend
.clone()
.as_any_arc()
.downcast::<box_impl::BoxImpl>();
let src = container_src.to_string();
Box::pin(async move {
let backend = backend.map_err(|_| {
BoxliteError::Unsupported("streaming copy-out requires the local backend".into())
})?;
backend.copy_out_stream(src, opts).await
})
}
pub fn network(&self) -> NetworkHandle {
NetworkHandle::new(Arc::clone(&self.network_backend))
}
pub fn snapshots(&self) -> SnapshotHandle {
SnapshotHandle::new(Arc::clone(&self.snapshot_backend))
}
pub async fn clone_box(
&self,
options: CloneOptions,
name: Option<String>,
) -> BoxliteResult<LiteBox> {
self.box_backend.clone_box(options, name).await
}
pub async fn clone_boxes(
&self,
options: CloneOptions,
count: usize,
names: Vec<String>,
) -> BoxliteResult<Vec<LiteBox>> {
self.box_backend.clone_boxes(options, count, names).await
}
pub async fn export(&self, options: ExportOptions, dest: &Path) -> BoxliteResult<BoxArchive> {
self.box_backend.export_box(options, dest).await
}
}
const _: () = {
const fn assert_send_sync<T: Send + Sync>() {}
let _ = assert_send_sync::<LiteBox>;
};