210 lines
5.4 KiB
Plaintext
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
|
|
--------------------------------------
|
|
`); |