125 lines
2.8 KiB
Markdown
125 lines
2.8 KiB
Markdown
|
|
|
|
## ✅ 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<dyn std::error::Error>> {
|
|
// 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
|
|
```
|