3 releases (breaking)

0.3.0 Aug 10, 2023
0.2.0 Apr 14, 2023
0.1.0 Dec 17, 2021

#1146 in Asynchronous

42 downloads per month

Apache-2.0

36KB
351 lines

Remote snapshotter extension for containerd

Crates.io docs.rs Crates.io CI

Snapshots crate implements containerd's proxy plugin for snapshotting. It aims hide the underlying complexity of GRPC interfaces, streaming, and request/response conversions and provide one Snapshots trait to implement.

containerd Documentation

Proxy plugins

A proxy plugin is configured using containerd's config file and will be loaded alongside the internal plugins when containerd is started. These plugins are connected to containerd using a local socket serving one of containerd's GRPC API services. Each plugin is configured with a type and name just as internal plugins are.

How to use from containerd

Add the following to containerd's configuration file:

[proxy_plugins]
  [proxy_plugins.custom]
    type = "snapshot"
    address = "/tmp/snap2.sock"

Start daemons and try pulling an image with custom snapshotter:

# Start containerd daemon
$ containerd --config /path/config.toml

# Run remote snapshotter instance
$ cargo run --example snapshotter /tmp/snap2.sock

# Now specify the snapshotter when pulling an image
$ ctr i pull --snapshotter custom docker.io/library/hello-world:latest

Getting started

Snapshotters are required to implement Snapshotter trait (which is very similar to containerd's Snapshotter interface).

#[derive(Default)]
struct Example;

#[snapshots::tonic::async_trait]
impl snapshots::Snapshotter for Example {
    type Error = ();

    async fn stat(&self, key: String) -> Result<Info, Self::Error> {
        info!("Stat: {}", key);
        Ok(Info::default())
    }

    // ...

    async fn commit(
        &self,
        name: String,
        key: String,
        labels: HashMap<String, String>,
    ) -> Result<(), Self::Error> {
        info!("Commit: name={}, key={}, labels={:?}", name, key, labels);
        Ok(())
    }
}

The library provides snapshots::server for convenience to wrap the implementation into a GRPC server, so it can be used with tonic like this:


use snapshots::tonic::transport::Server;

Server::builder()
    .add_service(snapshots::server(example))
    .serve_with_incoming(incoming)
    .await
    .expect("Serve failed");

Dependencies

~5–12MB
~131K SLoC