Merge pull request #208 from mxpv/docs

Simplify doc management and update READMEs
This commit is contained in:
Maksym Pavlenko 2023-10-04 11:24:21 -07:00 committed by GitHub
commit a0e042a46e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 152 additions and 166 deletions

View File

@ -30,7 +30,7 @@ jobs:
- run: cargo clippy --all-targets -- -D warnings - run: cargo clippy --all-targets -- -D warnings
- run: cargo clippy --all-targets --all-features -- -D warnings - run: cargo clippy --all-targets --all-features -- -D warnings
- run: cargo doc --no-deps - run: cargo doc --no-deps --features docs
env: env:
RUSTDOCFLAGS: -Dwarnings RUSTDOCFLAGS: -Dwarnings

View File

@ -34,9 +34,13 @@ tonic-build.workspace = true
[features] [features]
connect = ["tokio", "tower"] connect = ["tokio", "tower"]
docs = []
# Technically Tonic doesn't require Tokio and Tower dependencies here. # Technically Tonic doesn't require Tokio and Tower dependencies here.
# However we need them to implement `connect` helper and it's highly unlikely # However we need them to implement `connect` helper and it's highly unlikely
# that Tonic will be used with any other async runtime (see https://github.com/hyperium/tonic/issues/152) # that Tonic will be used with any other async runtime (see https://github.com/hyperium/tonic/issues/152)
# So we enable `connect` feature by default (use `--no-default-features` otherwise). # So we enable `connect` feature by default (use `--no-default-features` otherwise).
default = ["connect"] default = ["connect"]
[package.metadata.docs.rs]
features = ["docs"]

View File

@ -10,11 +10,15 @@ This crate implements a GRPC client to query containerd APIs.
## Example ## Example
```rust ```rust
use containerd_client::{connect, services::v1::version_client::VersionClient};
async fn query_version() {
// Launch containerd at /run/containerd/containerd.sock // Launch containerd at /run/containerd/containerd.sock
let channel = connect("/run/containerd/containerd.sock").await?; let channel = connect("/run/containerd/containerd.sock").await.unwrap();
let mut client = VersionClient::new(channel); let mut client = VersionClient::new(channel);
let resp = client.version(()).await?; let resp = client.version(()).await.unwrap();
println!("Response: {:?}", resp.get_ref()); println!("Response: {:?}", resp.get_ref());
}
``` ```

View File

@ -14,12 +14,11 @@
limitations under the License. limitations under the License.
*/ */
#![cfg_attr(feature = "docs", doc = include_str!("../README.md"))]
// No way to derive Eq with tonic :( // No way to derive Eq with tonic :(
// See https://github.com/hyperium/tonic/issues/1056 // See https://github.com/hyperium/tonic/issues/1056
#![allow(clippy::derive_partial_eq_without_eq)] #![allow(clippy::derive_partial_eq_without_eq)]
//! A GRPC client to query containerd's API.
pub use tonic; pub use tonic;
/// Generated `containerd.types` types. /// Generated `containerd.types` types.

View File

@ -3,7 +3,7 @@ name = "containerd-shim-logging"
version = "0.1.1" version = "0.1.1"
authors = [ authors = [
"Maksym Pavlenko <pavlenko.maksym@gmail.com>", "Maksym Pavlenko <pavlenko.maksym@gmail.com>",
"The containerd Authors" "The containerd Authors",
] ]
description = "Logger extension for containerd v2 runtime" description = "Logger extension for containerd v2 runtime"
keywords = ["containerd", "shim", "containers"] keywords = ["containerd", "shim", "containers"]
@ -13,3 +13,9 @@ edition.workspace = true
license.workspace = true license.workspace = true
repository.workspace = true repository.workspace = true
homepage.workspace = true homepage.workspace = true
[features]
docs = []
[package.metadata.docs.rs]
features = ["docs"]

View File

@ -14,14 +14,7 @@
limitations under the License. limitations under the License.
*/ */
//! Helper library to implement custom shim loggers for containerd. #![cfg_attr(feature = "docs", doc = include_str!("../README.md"))]
//!
//! # Runtime
//! containerd shims may support pluggable logging via stdio URIs. Binary logging has the ability to
//! forward a container's STDIO to an external binary for consumption.
//!
//! This crates replicates APIs provided by Go [version](https://github.com/containerd/containerd/blob/main/runtime/v2/README.md#logging).
//!
use std::{env, fmt, fs, os::unix::io::FromRawFd, process}; use std::{env, fmt, fs, os::unix::io::FromRawFd, process};

View File

@ -1,10 +1,7 @@
[package] [package]
name = "runc" name = "runc"
version = "0.2.0" version = "0.2.0"
authors = [ authors = ["Yuna Tomida <ytomida.mmm@gmail.com>", "The containerd Authors"]
"Yuna Tomida <ytomida.mmm@gmail.com>",
"The containerd Authors",
]
description = "A crate for consuming the runc binary in your Rust applications" description = "A crate for consuming the runc binary in your Rust applications"
keywords = ["containerd", "containers", "runc"] keywords = ["containerd", "containers", "runc"]
categories = ["api-bindings", "asynchronous"] categories = ["api-bindings", "asynchronous"]
@ -16,6 +13,7 @@ homepage.workspace = true
[features] [features]
async = ["tokio", "async-trait", "futures", "tokio-pipe"] async = ["tokio", "async-trait", "futures", "tokio-pipe"]
docs = []
[dependencies] [dependencies]
libc.workspace = true libc.workspace = true
@ -37,3 +35,6 @@ async-trait = { workspace = true, optional = true }
futures = { workspace = true, optional = true } futures = { workspace = true, optional = true }
tokio = { workspace = true, features = ["full"], optional = true } tokio = { workspace = true, features = ["full"], optional = true }
tokio-pipe = { version = "0.2.10", optional = true } tokio-pipe = { version = "0.2.10", optional = true }
[package.metadata.docs.rs]
features = ["docs"]

View File

@ -14,12 +14,10 @@ You can build runc client with `RuncConfig` in method chaining style.
Call `build()` or `build_async()` to get client. Call `build()` or `build_async()` to get client.
Note that async client depends on [tokio](https://github.com/tokio-rs/tokio), then please use it on tokio runtime. Note that async client depends on [tokio](https://github.com/tokio-rs/tokio), then please use it on tokio runtime.
```rust ```rust,ignore
use runc;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let config = runc::Config::new() let config = runc::GlobalOpts::new()
.root("./new_root") .root("./new_root")
.debug(false) .debug(false)
.log("/path/to/logfile.json") .log("/path/to/logfile.json")

View File

@ -33,6 +33,8 @@
* limitations under the License. * limitations under the License.
*/ */
#![cfg_attr(feature = "docs", doc = include_str!("../README.md"))]
//! A crate for consuming the runc binary in your Rust applications, similar to //! A crate for consuming the runc binary in your Rust applications, similar to
//! [go-runc](https://github.com/containerd/go-runc) for Go. //! [go-runc](https://github.com/containerd/go-runc) for Go.
use std::{ use std::{

View File

@ -18,6 +18,7 @@ homepage.workspace = true
default = [] default = []
async = ["ttrpc/async", "async-trait"] async = ["ttrpc/async", "async-trait"]
sandbox = [] sandbox = []
docs = []
[[example]] [[example]]
name = "shim-proto-server" name = "shim-proto-server"
@ -61,5 +62,10 @@ ttrpc-codegen = "0.4"
[dev-dependencies] [dev-dependencies]
ctrlc = { version = "3.0", features = ["termination"] } ctrlc = { version = "3.0", features = ["termination"] }
log.workspace = true log.workspace = true
simple_logger = { version = "4.0", default-features = false, features = ["stderr"]} simple_logger = { version = "4.0", default-features = false, features = [
"stderr",
] }
tokio = { workspace = true, features = ["full"] } tokio = { workspace = true, features = ["full"] }
[package.metadata.docs.rs]
features = ["docs"]

View File

@ -5,13 +5,28 @@
[![Crates.io](https://img.shields.io/crates/l/containerd-shim-protos)](https://github.com/containerd/rust-extensions/blob/main/LICENSE) [![Crates.io](https://img.shields.io/crates/l/containerd-shim-protos)](https://github.com/containerd/rust-extensions/blob/main/LICENSE)
[![CI](https://github.com/containerd/rust-extensions/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/containerd/rust-extensions/actions/workflows/ci.yml) [![CI](https://github.com/containerd/rust-extensions/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/containerd/rust-extensions/actions/workflows/ci.yml)
TTRPC bindings for containerd's shim events and interfaces. `containerd-shim-protos` contains TTRPC bindings and client/server code to interact with containerd's runtime v2 shims.
## Runtime
This crate is mainly expected to be useful to interact with containerd's shim runtime.
Runtime v2 introduces a first class shim API for runtime authors to integrate with containerd.
The shim API is minimal and scoped to the execution lifecycle of a container.
To learn how containerd's shim v2 runtime works in details, please refer to the [documentation](https://github.com/containerd/containerd/blob/main/runtime/v2/README.md).
## Design ## Design
The `containerd-shim-protos` crate provides [Protobuf](https://github.com/protocolbuffers/protobuf.git) message The `containerd-shim-protos` crate provides [Protobuf](https://github.com/protocolbuffers/protobuf.git) message
and [TTRPC](https://github.com/containerd/ttrpc.git) service definitions for the and [TTRPC](https://github.com/containerd/ttrpc.git) service definitions for the
[Containerd shim v2](https://github.com/containerd/containerd/blob/main/api/runtime/task/v2/shim.proto) protocol. [Containerd shim v2](https://github.com/containerd/containerd/blob/main/runtime/v2/task/shim.proto) protocol.
The message and service definitions are auto-generated from protobuf source files under `vendor/`
by using [ttrpc-codegen](https://github.com/containerd/ttrpc-rust/tree/master/ttrpc-codegen). So please do not
edit those auto-generated source files.
If upgrading/modification is needed, please follow the steps:
- Synchronize the latest protobuf source files from the upstream projects into directory 'vendor/'.
- Re-generate the source files by `cargo build --features=generate_bindings`.
- Commit the synchronized protobuf source files and auto-generated source files, keeping them in synchronization.
## Usage ## Usage
Add `containerd-shim-client` as a dependency in your `Cargo.toml` Add `containerd-shim-client` as a dependency in your `Cargo.toml`
@ -23,18 +38,20 @@ containerd-shim-protos = "0.4"
Basic client code looks as follows: Basic client code looks as follows:
```rust ```rust,no_run
let client = client::Client::connect(socket_path)?; use containerd_shim_protos as client;
let client = client::Client::connect("unix:///containerd-shim/shim.sock").expect("Failed to connect to shim");
let task_client = client::TaskClient::new(client); let task_client = client::TaskClient::new(client);
let context = client::ttrpc::context::with_timeout(0); let context = client::ttrpc::context::with_timeout(0);
let req = client::api::ConnectRequest { let req = client::api::ConnectRequest {
id: pid, id: String::from("1"),
..Default::default() ..Default::default()
}; };
let resp = task_client.connect(context, &req)?; let resp = task_client.connect(context, &req).expect("Connect request failed");
``` ```
## Example ## Example

View File

@ -14,52 +14,7 @@
limitations under the License. limitations under the License.
*/ */
//! `containerd-shim-protos` contains TTRPC bindings and client/server code to interact with #![cfg_attr(feature = "docs", doc = include_str!("../README.md"))]
//! containerd's runtime v2 shims.
//!
//! # Runtime
//! This crate is mainly expected to be useful to interact with containerd's shim runtime.
//! Runtime v2 introduces a first class shim API for runtime authors to integrate with containerd.
//! The shim API is minimal and scoped to the execution lifecycle of a container.
//!
//! To learn how containerd's shim v2 runtime works in details, please refer to the [documentation](https://github.com/containerd/containerd/blob/main/runtime/v2/README.md).
//!
//! # Design
//! The `containerd-shim-protos` crate provides [Protobuf](https://github.com/protocolbuffers/protobuf.git) message
//! and [TTRPC](https://github.com/containerd/ttrpc.git) service definitions for the
//! [Containerd shim v2](https://github.com/containerd/containerd/blob/main/runtime/v2/task/shim.proto) protocol.
//!
//! The message and service definitions are auto-generated from protobuf source files under `vendor/`
//! by using [ttrpc-codegen](https://github.com/containerd/ttrpc-rust/tree/master/ttrpc-codegen). So please do not
//! edit those auto-generated source files.
//!
//! If upgrading/modification is needed, please follow the steps:
//! - Synchronize the latest protobuf source files from the upstream projects into directory 'vendor/'.
//! - Re-generate the source files by `cargo build --features=generate_bindings`.
//! - Commit the synchronized protobuf source files and auto-generated source files, keeping them in synchronization.
//!
//! # Examples
//!
//! Here is a quick example how to use the crate:
//! ```no_run
//! use containerd_shim_protos as client;
//!
//! use client::api;
//! use client::ttrpc::context::Context;
//!
//! // Create TTRPC client
//! let client = client::Client::connect("unix:///socket.sock").unwrap();
//!
//! // Get task client
//! let task_client = client::TaskClient::new(client);
//! let context = Context::default();
//!
//! // Send request and receive response
//! let request = api::ConnectRequest::default();
//! let response = task_client.connect(Context::default(), &request);
//! ```
//!
#![allow(warnings)] #![allow(warnings)]
pub use protobuf; pub use protobuf;

View File

@ -22,6 +22,7 @@ async = [
"signal-hook-tokio", "signal-hook-tokio",
"tokio", "tokio",
] ]
docs = []
[[example]] [[example]]
name = "skeleton_async" name = "skeleton_async"
@ -50,7 +51,9 @@ time.workspace = true
# Async dependencies # Async dependencies
async-trait = { workspace = true, optional = true } async-trait = { workspace = true, optional = true }
futures = { workspace = true, optional = true } futures = { workspace = true, optional = true }
signal-hook-tokio = { version = "0.3.1", optional = true, features = ["futures-v0_3"]} signal-hook-tokio = { version = "0.3.1", optional = true, features = [
"futures-v0_3",
] }
tokio = { workspace = true, features = ["full"], optional = true } tokio = { workspace = true, features = ["full"], optional = true }
[target.'cfg(target_os = "linux")'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
@ -74,3 +77,6 @@ windows-sys = {version = "0.48.0", features = [
[dev-dependencies] [dev-dependencies]
tempfile = "3.6" tempfile = "3.6"
[package.metadata.docs.rs]
features = ["docs"]

View File

@ -10,48 +10,77 @@ Rust crate to ease runtime v2 shim implementation.
It replicates same [shim.Run](https://github.com/containerd/containerd/blob/dbef1d56d7ebc05bc4553d72c419ed5ce025b05d/runtime/v2/example/cmd/main.go) It replicates same [shim.Run](https://github.com/containerd/containerd/blob/dbef1d56d7ebc05bc4553d72c419ed5ce025b05d/runtime/v2/example/cmd/main.go)
API offered by containerd's shim v2 runtime implementation written in Go. API offered by containerd's shim v2 runtime implementation written in Go.
## Runtime
Runtime v2 introduces a first class shim API for runtime authors to integrate with containerd.
The shim API is minimal and scoped to the execution lifecycle of a container.
This crate simplifies shim v2 runtime development for containerd. It handles common tasks such
as command line parsing, setting up shim's TTRPC server, logging, events, etc.
Clients are expected to implement [Shim] and [Task] traits with task handling routines.
This generally replicates same API as in Go [version](https://github.com/containerd/containerd/blob/main/runtime/v2/example/cmd/main.go).
Once implemented, shim's bootstrap code is as easy as:
```text
shim::run::<Service>("io.containerd.empty.v1")
```
## Look and feel ## Look and feel
The API is very similar to the one offered by Go version: The API is very similar to the one offered by Go version:
```rust ```rust,no_run
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)] #[derive(Clone)]
struct Service { struct Service {
exit: ExitSignal, exit: Arc<ExitSignal>,
} }
impl shim::Shim for Service { #[async_trait]
type Error = shim::Error; impl Shim for Service {
type T = Service; type T = Service;
fn new( async fn new(_runtime_id: &str, _args: &Flags, _config: &mut Config) -> Self {
_runtime_id: &str,
_id: &str,
_namespace: &str,
_publisher: shim::RemotePublisher,
_config: &mut shim::Config,
) -> Self {
Service { Service {
exit: ExitSignal::default(), exit: Arc::new(ExitSignal::default()),
} }
} }
fn start_shim(&mut self, opts: shim::StartOpts) -> Result<String, shim::Error> { async fn start_shim(&mut self, opts: StartOpts) -> Result<String, Error> {
let address = shim::spawn(opts, Vec::new())?; let grouping = opts.id.clone();
let address = spawn(opts, &grouping, Vec::new()).await?;
Ok(address) Ok(address)
} }
fn wait(&mut self) { async fn delete_shim(&mut self) -> Result<DeleteResponse, Error> {
self.exit.wait(); Ok(DeleteResponse::new())
} }
fn get_task_service(&self) -> Self::T { async fn wait(&mut self) {
self.exit.wait().await;
}
async fn create_task_service(&self, _publisher: RemotePublisher) -> Self::T {
self.clone() self.clone()
} }
} }
impl shim::Task for Service { #[async_trait]
fn connect( impl Task for Service {
async fn connect(
&self, &self,
_ctx: &TtrpcContext, _ctx: &TtrpcContext,
_req: api::ConnectRequest, _req: api::ConnectRequest,
@ -63,15 +92,20 @@ impl shim::Task for Service {
}) })
} }
fn shutdown(&self, _ctx: &TtrpcContext, _req: api::ShutdownRequest) -> TtrpcResult<api::Empty> { async fn shutdown(
&self,
_ctx: &TtrpcContext,
_req: api::ShutdownRequest,
) -> TtrpcResult<api::Empty> {
info!("Shutdown request"); info!("Shutdown request");
self.exit.signal(); // Signal to shutdown shim server self.exit.signal();
Ok(api::Empty::default()) Ok(api::Empty::default())
} }
} }
fn main() { #[tokio::main]
shim::run::<Service>("io.containerd.empty.v1") async fn main() {
run::<Service>("io.containerd.empty.v1", None).await;
} }
``` ```
@ -97,7 +131,7 @@ $ sudo ctr run --rm --runtime ./target/debug/examples/skeleton docker.io/library
Or manually: Or manually:
``` ```bash
$ touch log $ touch log
# Run containerd in background # Run containerd in background

View File

@ -14,23 +14,7 @@
limitations under the License. limitations under the License.
*/ */
//! A library to implement custom runtime v2 shims for containerd. #![cfg_attr(feature = "docs", doc = include_str!("../README.md"))]
//!
//! # Runtime
//! Runtime v2 introduces a first class shim API for runtime authors to integrate with containerd.
//! The shim API is minimal and scoped to the execution lifecycle of a container.
//!
//! This crate simplifies shim v2 runtime development for containerd. It handles common tasks such
//! as command line parsing, setting up shim's TTRPC server, logging, events, etc.
//!
//! Clients are expected to implement [Shim] and [Task] traits with task handling routines.
//! This generally replicates same API as in Go [version](https://github.com/containerd/containerd/blob/main/runtime/v2/example/cmd/main.go).
//!
//! Once implemented, shim's bootstrap code is as easy as:
//! ```text
//! shim::run::<Service>("io.containerd.empty.v1")
//! ```
//!
use std::{collections::hash_map::DefaultHasher, fs::File, hash::Hasher, path::PathBuf}; use std::{collections::hash_map::DefaultHasher, fs::File, hash::Hasher, path::PathBuf};
#[cfg(unix)] #[cfg(unix)]

View File

@ -14,6 +14,9 @@ license.workspace = true
repository.workspace = true repository.workspace = true
homepage.workspace = true homepage.workspace = true
[features]
docs = []
[dependencies] [dependencies]
async-stream = "0.3.3" async-stream = "0.3.3"
futures.workspace = true futures.workspace = true
@ -34,3 +37,6 @@ simple_logger = { version = "4.0", default-features = false }
[build-dependencies] [build-dependencies]
tonic-build.workspace = true tonic-build.workspace = true
[package.metadata.docs.rs]
features = ["docs"]

View File

@ -43,13 +43,19 @@ $ ctr i pull --snapshotter custom docker.io/library/hello-world:latest
Snapshotters are required to implement `Snapshotter` trait (which is very similar to containerd's Snapshotters are required to implement `Snapshotter` trait (which is very similar to containerd's
[Snapshotter](https://github.com/containerd/containerd/blob/main/snapshots/snapshotter.go) interface). [Snapshotter](https://github.com/containerd/containerd/blob/main/snapshots/snapshotter.go) interface).
```rust ```rust,ignore
use std::collections::HashMap;
use containerd_snapshots as snapshots;
use containerd_snapshots::{api, Info, Usage};
use log::info;
#[derive(Default)] #[derive(Default)]
struct Example; struct Example;
#[snapshots::tonic::async_trait] #[snapshots::tonic::async_trait]
impl snapshots::Snapshotter for Example { impl snapshots::Snapshotter for Example {
type Error = (); type Error = snapshots::tonic::Status;
async fn stat(&self, key: String) -> Result<Info, Self::Error> { async fn stat(&self, key: String) -> Result<Info, Self::Error> {
info!("Stat: {}", key); info!("Stat: {}", key);
@ -73,8 +79,7 @@ impl snapshots::Snapshotter for Example {
The library provides `snapshots::server` for convenience to wrap the implementation into a GRPC server, so it can The library provides `snapshots::server` for convenience to wrap the implementation into a GRPC server, so it can
be used with `tonic` like this: be used with `tonic` like this:
```rust ```rust,ignore
use snapshots::tonic::transport::Server; use snapshots::tonic::transport::Server;
Server::builder() Server::builder()

View File

@ -14,41 +14,7 @@
limitations under the License. limitations under the License.
*/ */
//! Remote snapshotter extension for containerd. #![cfg_attr(feature = "docs", doc = include_str!("../README.md"))]
//!
//! 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
//! [crate::Snapshotter] trait to implement.
//!
//! # 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:
//! ```toml
//! [proxy_plugins]
//! [proxy_plugins.custom]
//! type = "snapshot"
//! address = "/tmp/snap2.sock"
//! ```
//! Start containerd daemon:
//! ```bash
//! containerd --config /path/config.toml
//! ```
//!
//! Run remote snapshotter instance:
//! ```bash
//! $ cargo run --example snapshotter /tmp/snap2.sock
//! ```
//! Now specify `custom` snapshotter when pulling an image with `ctr`:
//! ```bash
//! $ ctr i pull --snapshotter custom docker.io/library/hello-world:latest
//! ```
//!
// No way to derive Eq with tonic :( // No way to derive Eq with tonic :(
// See https://github.com/hyperium/tonic/issues/1056 // See https://github.com/hyperium/tonic/issues/1056
#![allow(clippy::derive_partial_eq_without_eq)] #![allow(clippy::derive_partial_eq_without_eq)]