sal/src/rhaiexamples/containerd_grpc_setup.rhai
2025-04-05 15:38:43 +02:00

210 lines
5.4 KiB
Plaintext

// containerd_grpc_setup.rhai
//
// This script sets up a Rust project with gRPC connectivity to containerd
// Following the steps from the instructions document
run("apt-get -y protobuf-compiler ");
// Step 1: Set up project directory
let project_dir = "/tmp/containerd-rust-client";
print(`Setting up project in: ${project_dir}`);
// Clean up any existing directory
if exist(project_dir) {
print("Found existing project directory, removing it...");
delete(project_dir);
}
// Create our project directory
mkdir(project_dir);
// Change to the project directory
chdir(project_dir);
// Step 2: Clone containerd's gRPC proto files
print("Cloning containerd repository to get proto files...");
let git_tree = gittree_new(project_dir);
let repos = git_tree.get("https://github.com/containerd/containerd.git");
let repo = repos[0];
print(`Cloned containerd repository to: ${repo.path()}`);
// Step 3: Create necessary project files
print("Creating Cargo.toml file...");
// Using raw string with # for multiline content
let cargo_toml = #"
[package]
name = "containerd-rust-client"
version = "0.1.0"
edition = "2021"
[dependencies]
tonic = "0.11"
prost = "0.12"
tokio = { version = "1", features = ["full"] }
hyper-unix-connector = "0.2.0"
tower = "0.4"
[build-dependencies]
tonic-build = "0.11"
"#;
file_write("Cargo.toml", cargo_toml);
print("Created Cargo.toml file");
// Step 4: Set up build.rs to compile protos
print("Creating build.rs file...");
let build_rs = #"
fn main() {
println!("cargo:rerun-if-changed=containerd/api/services/images/v1/images.proto");
println!("cargo:rerun-if-changed=containerd/api/services/containers/v1/containers.proto");
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",
"containerd/api",
"containerd/api/types"
],
)
.unwrap();
}
"#;
file_write("build.rs", build_rs);
print("Created build.rs file");
// Step 5: Create src directory and main.rs file
mkdir("src");
// Create a helper function for Unix socket connection
print("Creating src/main.rs file...");
let main_rs = #"
use tonic::transport::{Channel, Endpoint, Uri};
use tower::service_fn;
use std::convert::TryFrom;
// The proto-generated modules will be available after build
// use containerd::services::images::v1::{
// images_client::ImagesClient,
// GetImageRequest,
// };
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Connecting to containerd gRPC...");
// Path to containerd socket
let socket_path = "/run/containerd/containerd.sock";
// Connect to the Unix socket
let channel = unix_socket_channel(socket_path).await?;
// Now we'd create a client and use it
// 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());
println!("Connection to containerd socket established successfully!");
println!("This is a template - uncomment the client code after building.");
Ok(())
}
// Helper function to connect to Unix socket
async fn unix_socket_channel(path: &str) -> Result<Channel, Box<dyn std::error::Error>> {
// Use a placeholder URI since Unix sockets don't have URIs
let endpoint = Endpoint::try_from("http://[::]:50051")?;
// The socket path to connect to
let path_to_connect = path.to_string();
// Create a connector function that connects to the Unix socket
let channel = endpoint
.connect_with_connector(service_fn(move |_: Uri| {
let path = path_to_connect.clone();
async move {
tokio::net::UnixStream::connect(path)
.await
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))
}
}))
.await?;
Ok(channel)
}
"#;
file_write("src/main.rs", main_rs);
print("Created src/main.rs file");
// Step 6: Create a README.md file
print("Creating README.md file...");
// Using raw string with # for multiline content containing markdown backticks
let readme = #"# containerd Rust gRPC Client
A Rust client for interacting with containerd via gRPC.
## Prerequisites
- Rust and Cargo installed
- containerd running on your system
## Building
```bash
cargo build
```
## Running
```bash
cargo run
```
## Features
- Connect to containerd via Unix socket
- Query image information
- Work with containers
## Structure
- `src/main.rs` - Example client code
- `build.rs` - Proto compilation script
"#;
file_write("README.md", readme);
print("Created README.md file");
// Step 7: Build the project
print("Building the project...");
let build_result = run("cargo build");
if build_result.success {
print("Project built successfully!");
} else {
print(`Build failed with error: ${build_result.stderr}`);
}
print(`
--------------------------------------
🎉 Setup complete!
Project created at: ${project_dir}
To use the project:
1. cd ${project_dir}
2. cargo run
Note: Make sure containerd is running and the socket exists at /run/containerd/containerd.sock
--------------------------------------
`);