use std::sync::Arc;
use async_trait::async_trait;
use containerd_shim::{
asynchronous::{run, spawn, ExitSignal, Shim},
publisher::RemotePublisher,
Config, Error, Flags, StartOpts, TtrpcResult,
};
use containerd_shim_protos::{
api, api::DeleteResponse, shim_async::Task, ttrpc::r#async::TtrpcContext,
};
use log::info;
#[derive(Clone)]
struct Service {
exit: Arc<ExitSignal>,
}
#[async_trait]
impl Shim for Service {
type T = Service;
async fn new(_runtime_id: &str, _args: &Flags, _config: &mut Config) -> Self {
Service {
exit: Arc::new(ExitSignal::default()),
}
}
async fn start_shim(&mut self, opts: StartOpts) -> Result<String, Error> {
let grouping = opts.id.clone();
let address = spawn(opts, &grouping, Vec::new()).await?;
Ok(address)
}
async fn delete_shim(&mut self) -> Result<DeleteResponse, Error> {
Ok(DeleteResponse::new())
}
async fn wait(&mut self) {
self.exit.wait().await;
}
async fn create_task_service(&self, _publisher: RemotePublisher) -> Self::T {
self.clone()
}
}
#[async_trait]
impl Task for Service {
async fn connect(
&self,
_ctx: &TtrpcContext,
_req: api::ConnectRequest,
) -> TtrpcResult<api::ConnectResponse> {
info!("Connect request");
Ok(api::ConnectResponse {
version: String::from("example"),
..Default::default()
})
}
async fn shutdown(
&self,
_ctx: &TtrpcContext,
_req: api::ShutdownRequest,
) -> TtrpcResult<api::Empty> {
info!("Shutdown request");
self.exit.signal();
Ok(api::Empty::default())
}
}
#[tokio::main]
async fn main() {
run::<Service>("io.containerd.empty.v1", None).await;
}