#![cfg_attr(feature = "docs", doc = include_str!("../README.md"))]
#![allow(clippy::derive_partial_eq_without_eq)]
pub use tonic;
pub mod types {
tonic::include_proto!("containerd.types");
pub mod v1 {
tonic::include_proto!("containerd.v1.types");
}
}
pub mod google {
pub mod rpc {
tonic::include_proto!("google.rpc");
}
}
pub mod services {
#[allow(clippy::tabs_in_doc_comments)]
#[allow(rustdoc::invalid_rust_codeblocks)]
#[allow(rustdoc::invalid_html_tags)]
pub mod v1 {
tonic::include_proto!("containerd.services.containers.v1");
tonic::include_proto!("containerd.services.content.v1");
tonic::include_proto!("containerd.services.diff.v1");
tonic::include_proto!("containerd.services.events.v1");
tonic::include_proto!("containerd.services.images.v1");
tonic::include_proto!("containerd.services.introspection.v1");
tonic::include_proto!("containerd.services.leases.v1");
tonic::include_proto!("containerd.services.namespaces.v1");
tonic::include_proto!("containerd.services.streaming.v1");
tonic::include_proto!("containerd.services.tasks.v1");
tonic::include_proto!("containerd.services.transfer.v1");
pub mod sandbox {
tonic::include_proto!("containerd.services.sandbox.v1");
}
pub mod snapshots {
tonic::include_proto!("containerd.services.snapshots.v1");
}
tonic::include_proto!("containerd.services.version.v1");
}
}
pub mod events {
tonic::include_proto!("containerd.events");
}
#[cfg(feature = "connect")]
pub async fn connect(
path: impl AsRef<std::path::Path>,
) -> Result<tonic::transport::Channel, tonic::transport::Error> {
use tonic::transport::Endpoint;
let path = path.as_ref().to_path_buf();
let channel = Endpoint::try_from("http://[::]")?
.connect_with_connector(tower::service_fn(move |_| {
let path = path.clone();
async move {
#[cfg(unix)]
{
Ok::<_, std::io::Error>(hyper_util::rt::TokioIo::new(
tokio::net::UnixStream::connect(path).await?,
))
}
#[cfg(windows)]
{
let client = tokio::net::windows::named_pipe::ClientOptions::new()
.open(&path)
.map_err(|e| std::io::Error::from(e))?;
Ok::<_, std::io::Error>(hyper_util::rt::TokioIo::new(client))
}
}
}))
.await?;
Ok(channel)
}
#[macro_export]
macro_rules! with_namespace {
($req : ident, $ns: expr) => {{
let mut req = Request::new($req);
let md = req.metadata_mut();
md.insert("containerd-namespace", $ns.parse().unwrap());
req
}};
}
use services::v1::{
containers_client::ContainersClient,
content_client::ContentClient,
diff_client::DiffClient,
events_client::EventsClient,
images_client::ImagesClient,
introspection_client::IntrospectionClient,
leases_client::LeasesClient,
namespaces_client::NamespacesClient,
sandbox::{controller_client::ControllerClient, store_client::StoreClient},
snapshots::snapshots_client::SnapshotsClient,
streaming_client::StreamingClient,
tasks_client::TasksClient,
transfer_client::TransferClient,
version_client::VersionClient,
};
use tonic::transport::{Channel, Error};
pub struct Client {
channel: Channel,
}
impl From<Channel> for Client {
fn from(value: Channel) -> Self {
Self { channel: value }
}
}
impl Client {
#[cfg(feature = "connect")]
pub async fn from_path(path: impl AsRef<std::path::Path>) -> Result<Self, Error> {
let channel = connect(path).await?;
Ok(Self { channel })
}
#[inline]
pub fn channel(&self) -> Channel {
self.channel.clone()
}
#[inline]
pub fn version(&self) -> VersionClient<Channel> {
VersionClient::new(self.channel())
}
#[inline]
pub fn tasks(&self) -> TasksClient<Channel> {
TasksClient::new(self.channel())
}
#[inline]
pub fn transfer(&self) -> TransferClient<Channel> {
TransferClient::new(self.channel())
}
#[inline]
pub fn sandbox_store(&self) -> StoreClient<Channel> {
StoreClient::new(self.channel())
}
#[inline]
pub fn streaming(&self) -> StreamingClient<Channel> {
StreamingClient::new(self.channel())
}
#[inline]
pub fn sandbox_controller(&self) -> ControllerClient<Channel> {
ControllerClient::new(self.channel())
}
#[inline]
pub fn snapshots(&self) -> SnapshotsClient<Channel> {
SnapshotsClient::new(self.channel())
}
#[inline]
pub fn namespaces(&self) -> NamespacesClient<Channel> {
NamespacesClient::new(self.channel())
}
#[inline]
pub fn leases(&self) -> LeasesClient<Channel> {
LeasesClient::new(self.channel())
}
#[inline]
pub fn introspection(&self) -> IntrospectionClient<Channel> {
IntrospectionClient::new(self.channel())
}
#[inline]
pub fn images(&self) -> ImagesClient<Channel> {
ImagesClient::new(self.channel())
}
#[inline]
pub fn events(&self) -> EventsClient<Channel> {
EventsClient::new(self.channel())
}
#[inline]
pub fn diff(&self) -> DiffClient<Channel> {
DiffClient::new(self.channel())
}
#[inline]
pub fn content(&self) -> ContentClient<Channel> {
ContentClient::new(self.channel())
}
#[inline]
pub fn containers(&self) -> ContainersClient<Channel> {
ContainersClient::new(self.channel())
}
}
#[cfg(test)]
mod tests {
use prost_types::Any;
use crate::events::ContainerCreate;
#[test]
fn any_roundtrip() {
let original = ContainerCreate {
id: "test".to_string(),
image: "test".to_string(),
runtime: None,
};
let any = Any::from_msg(&original).expect("should not fail to encode");
let decoded: ContainerCreate = any.to_msg().expect("should not fail to decode");
assert_eq!(original, decoded)
}
}