## โœ… Step-by-step: Connect Rust to containerd via gRPC CREATE A rhai script executing the following instructions below use all rhai script features we have + give priority to what functions we have defined in /src/docs/docs/sal in this repo --- ### 1. ๐Ÿงฑ Install Dependencies Add this to your `Cargo.toml`: ```toml [dependencies] tonic = "0.11" prost = "0.12" tokio = { version = "1", features = ["full"] } [build-dependencies] tonic-build = "0.11" ``` --- ### 2. ๐Ÿ“ Clone containerd's gRPC proto files ```bash git clone https://github.com/containerd/containerd.git cd containerd ``` Containerd's API protos are in: ``` api/services/ # gRPC service definitions api/types/ # message types ``` --- ### 3. ๐Ÿ“ฆ Set up `build.rs` to compile protos In your Rust project root, create a `build.rs` file: ```rust fn main() { tonic_build::configure() .build_server(false) .compile( &[ "containerd/api/services/images/v1/images.proto", "containerd/api/services/containers/v1/containers.proto", // Add more proto files as needed ], &[ "containerd/api", "containerd/api/types" ], ) .unwrap(); } ``` Make sure to place the `containerd` directory somewhere your build can see โ€” for example, symlink it or move it into your project as `proto/containerd`. --- ### 4. ๐Ÿงช Example: Connect to containerd's image service After `build.rs` compiles the protos, your code can access them like this: ```rust use tonic::transport::Channel; use containerd::services::images::v1::{ images_client::ImagesClient, GetImageRequest, }; #[tokio::main] async fn main() -> Result<(), Box> { // Connect to containerd's gRPC socket (default path) let channel = Channel::from_static("http://[::]:50051") // placeholder .connect() .await?; let mut client = ImagesClient::new(channel); let response = client.get(GetImageRequest { name: "docker.io/library/ubuntu:latest".to_string(), }).await?; println!("Image: {:?}", response.into_inner()); Ok(()) } ``` ๐Ÿ”ง Note: containerd uses a **Unix socket**, so replace the channel connection with: ```rust use tonic::transport::{Endpoint, Uri}; use tower::service_fn; use hyper_unix_connector::UnixConnector; let uds = tokio::net::UnixStream::connect("/run/containerd/containerd.sock").await?; let channel = Endpoint::try_from("http://[::]:50051")? .connect_with_connector(service_fn(move |_| async move { Ok::<_, std::io::Error>(uds) })) .await?; ``` (We can wrap that part into a helper if you want.) --- ### 5. ๐Ÿ” Rebuild the project Each time you add or change a `.proto`, rebuild to regenerate code: ```bash cargo clean && cargo build ```