rust-extensions/crates/snapshots
Bryant Biggs 468fbc0b4c chore: Move tokio dependency in `snapshots` to dev dependency 2025-06-11 00:09:51 +00:00
..
examples Fix unused fields on Mac 2024-12-31 15:09:58 -08:00
src snapshots: Add handy `Clone`, `Copy` derivations 2024-11-13 21:41:08 +00:00
vendor Update vendor 2025-01-08 18:31:52 +00:00
Cargo.toml chore: Move tokio dependency in `snapshots` to dev dependency 2025-06-11 00:09:51 +00:00
README.md chore: Fix whitespace 2024-07-30 16:54:34 +00:00
build.rs fix: Replace `tonic` deprecated methods to fix clippy warnings 2024-10-05 14:55:48 +00:00
rsync.txt Add update vendor script 2024-02-22 17:49:39 +00:00

README.md

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).

use std::collections::HashMap;

use containerd_snapshots as snapshots;
use containerd_snapshots::{api, Info, Usage};
use log::info;

#[derive(Default)]
struct Example;

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

    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");