diff --git a/crates/runh/README.md b/crates/runh/README.md index 54b0292..fbee76f 100644 --- a/crates/runh/README.md +++ b/crates/runh/README.md @@ -1,32 +1,26 @@ -# Rust bindings for runc CLI +# Rust bindings for runh CLI -[![Crates.io](https://img.shields.io/crates/v/runc)](https://crates.io/crates/runc) -[![docs.rs](https://img.shields.io/docsrs/runc)](https://docs.rs/runc/latest/runc/) -[![Crates.io](https://img.shields.io/crates/l/containerd-shim)](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) - -A crate for consuming the runc binary in your Rust applications, similar to [go-runc](https://github.com/containerd/go-runc) for Go. -This crate is based on archived [rust-runc](https://github.com/pwFoo/rust-runc). +A crate for consuming the runh binary in your Rust applications. ## Usage Both sync/async version is available. -You can build runc client with `RuncConfig` in method chaining style. +You can build runh client with `RunhConfig` in method chaining style. 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. ```rust,ignore #[tokio::main] async fn main() { - let config = runc::GlobalOpts::new() + let config = runh::GlobalOpts::new() .root("./new_root") .debug(false) .log("/path/to/logfile.json") - .log_format(runc::LogFormat::Json) + .log_format(runh::LogFormat::Json) .rootless(true); let client = config.build_async().unwrap(); - let opts = runc::options::CreateOpts::new() + let opts = runh::options::CreateOpts::new() .pid_file("/path/to/pid/file") .no_pivot(true); @@ -41,6 +35,5 @@ async fn main() { - state - kill - delete -- Exec is **not** available in `RuncAsyncClient` now. +- Exec is **not** available in `RunhAsyncClient` now. - Console utilites are **not** available - - see [Go version](https://github.com/containerd/go-runc/blob/main/console.go) diff --git a/crates/runh/src/container.rs b/crates/runh/src/container.rs index 0f846c7..4851f18 100644 --- a/crates/runh/src/container.rs +++ b/crates/runh/src/container.rs @@ -38,7 +38,7 @@ use std::collections::HashMap; use serde::{Deserialize, Serialize}; use time::{serde::timestamp, OffsetDateTime}; -/// Information for runc container +/// Information for runh container #[derive(Debug, Serialize, Deserialize)] pub struct Container { pub id: String, diff --git a/crates/runh/src/error.rs b/crates/runh/src/error.rs index ac437ad..c4495b3 100644 --- a/crates/runh/src/error.rs +++ b/crates/runh/src/error.rs @@ -54,7 +54,7 @@ pub enum Error { #[error(transparent)] ProcessSpawnFailed(io::Error), - #[error("Error occured in runc: {0}")] + #[error("Error occured in runh: {0}")] InvalidCommand(io::Error), #[error("Runh command failed: status={status}, stdout=\"{stdout}\", stderr=\"{stderr}\"")] @@ -71,10 +71,10 @@ pub enum Error { #[error("Runh command timed out: {0}")] CommandTimeout(tokio::time::error::Elapsed), - #[error("Unable to parse runc version")] + #[error("Unable to parse runh version")] InvalidVersion, - #[error("Unable to locate the runc")] + #[error("Unable to locate the runh")] NotFound, #[error("Error occurs with fs: {0}")] @@ -113,7 +113,7 @@ pub enum Error { #[error("Sorry, this part of api is not implemented: {0}")] Unimplemented(String), - #[error("Error occured in runc client: {0}")] + #[error("Error occured in runh client: {0}")] Other(Box), #[error("Failed to set cmd io: {0}")] diff --git a/crates/runh/src/events.rs b/crates/runh/src/events.rs index 9bf7125..c9a9b35 100644 --- a/crates/runh/src/events.rs +++ b/crates/runh/src/events.rs @@ -37,7 +37,7 @@ use std::collections::HashMap; use serde::{Deserialize, Serialize}; -/// Event type generated by runc +/// Event type generated by runh #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all(serialize = "lowercase", deserialize = "lowercase"))] pub enum EventType { diff --git a/crates/runh/src/io.rs b/crates/runh/src/io.rs index 9758ec3..40121fc 100644 --- a/crates/runh/src/io.rs +++ b/crates/runh/src/io.rs @@ -73,7 +73,7 @@ pub trait Io: Debug + Send + Sync { /// Read side of stdin, write side of stdout and write side of stderr should be provided to command. fn set(&self, cmd: &mut Command) -> Result<()>; - /// Only close write side (should be stdout/err "from" runc process) + /// Only close write side (should be stdout/err "from" runh process) fn close_after_start(&self); } diff --git a/crates/runh/src/lib.rs b/crates/runh/src/lib.rs index 730ba8e..426c178 100644 --- a/crates/runh/src/lib.rs +++ b/crates/runh/src/lib.rs @@ -35,7 +35,7 @@ #![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 runh binary in your Rust applications, similar to //! [go-runc](https://github.com/containerd/go-runc) for Go. use std::{ fmt::{self, Debug, Display}, @@ -73,7 +73,7 @@ pub struct Response { #[derive(Debug, Clone)] pub struct Version { - pub runc_version: Option, + pub runh_version: Option, pub spec_version: Option, pub commit: Option, } @@ -117,7 +117,7 @@ impl Runh { .stdout(Stdio::piped()) .stderr(Stdio::piped()); - // NOTIFY_SOCKET introduces a special behavior in runc but should only be set if invoked from systemd + // NOTIFY_SOCKET introduces a special behavior in runh but should only be set if invoked from systemd cmd.args(&args).env_remove("NOTIFY_SOCKET"); Ok(cmd) @@ -490,7 +490,7 @@ impl Runh { Ok(()) } - /// List all containers associated with this runc instance + /// List all containers associated with this runh instance pub async fn list(&self) -> Result> { let args = ["list".to_string(), "--format=json".to_string()]; let res = self.launch(self.command(&args)?, true).await?; @@ -671,7 +671,7 @@ mod tests { GlobalOpts::new() .command("/bin/echo") .build() - .expect("unable to create runc instance") + .expect("unable to create runh instance") } fn dummy_process() -> Process { @@ -691,113 +691,113 @@ mod tests { #[test] fn test_create() { let opts = CreateOpts::new(); - let ok_runc = ok_client(); - let response = ok_runc + let ok_runh = ok_client(); + let response = ok_runh .create("fake-id", "fake-bundle", Some(&opts)) .expect("true failed."); assert_ne!(response.pid, 0); assert!(response.status.success()); assert!(response.output.is_empty()); - let fail_runc = fail_client(); - match fail_runc.create("fake-id", "fake-bundle", Some(&opts)) { - Ok(_) => panic!("fail_runc returned exit status 0."), + let fail_runh = fail_client(); + match fail_runh.create("fake-id", "fake-bundle", Some(&opts)) { + Ok(_) => panic!("fail_runh returned exit status 0."), Err(Error::CommandFailed { status, stdout, stderr, }) => { if status.code().unwrap() == 1 && stdout.is_empty() && stderr.is_empty() { - eprintln!("fail_runc succeeded."); + eprintln!("fail_runh succeeded."); } else { - panic!("unexpected outputs from fail_runc.") + panic!("unexpected outputs from fail_runh.") } } - Err(e) => panic!("unexpected error from fail_runc: {:?}", e), + Err(e) => panic!("unexpected error from fail_runh: {:?}", e), } } #[test] fn test_run() { let opts = CreateOpts::new(); - let ok_runc = ok_client(); - let response = ok_runc + let ok_runh = ok_client(); + let response = ok_runh .run("fake-id", "fake-bundle", Some(&opts)) .expect("true failed."); assert_ne!(response.pid, 0); assert!(response.status.success()); assert!(response.output.is_empty()); - let fail_runc = fail_client(); - match fail_runc.run("fake-id", "fake-bundle", Some(&opts)) { - Ok(_) => panic!("fail_runc returned exit status 0."), + let fail_runh = fail_client(); + match fail_runh.run("fake-id", "fake-bundle", Some(&opts)) { + Ok(_) => panic!("fail_runh returned exit status 0."), Err(Error::CommandFailed { status, stdout, stderr, }) => { if status.code().unwrap() == 1 && stdout.is_empty() && stderr.is_empty() { - eprintln!("fail_runc succeeded."); + eprintln!("fail_runh succeeded."); } else { - panic!("unexpected outputs from fail_runc.") + panic!("unexpected outputs from fail_runh.") } } - Err(e) => panic!("unexpected error from fail_runc: {:?}", e), + Err(e) => panic!("unexpected error from fail_runh: {:?}", e), } } #[test] fn test_exec() { let opts = ExecOpts::new(); - let ok_runc = ok_client(); + let ok_runh = ok_client(); let proc = dummy_process(); - ok_runc + ok_runh .exec("fake-id", &proc, Some(&opts)) .expect("true failed."); - eprintln!("ok_runc succeeded."); + eprintln!("ok_runh succeeded."); - let fail_runc = fail_client(); - match fail_runc.exec("fake-id", &proc, Some(&opts)) { - Ok(_) => panic!("fail_runc returned exit status 0."), + let fail_runh = fail_client(); + match fail_runh.exec("fake-id", &proc, Some(&opts)) { + Ok(_) => panic!("fail_runh returned exit status 0."), Err(Error::CommandFailed { status, stdout, stderr, }) => { if status.code().unwrap() == 1 && stdout.is_empty() && stderr.is_empty() { - eprintln!("fail_runc succeeded."); + eprintln!("fail_runh succeeded."); } else { - panic!("unexpected outputs from fail_runc.") + panic!("unexpected outputs from fail_runh.") } } - Err(e) => panic!("unexpected error from fail_runc: {:?}", e), + Err(e) => panic!("unexpected error from fail_runh: {:?}", e), } } #[test] fn test_delete() { let opts = DeleteOpts::new(); - let ok_runc = ok_client(); - ok_runc + let ok_runh = ok_client(); + ok_runh .delete("fake-id", Some(&opts)) .expect("true failed."); - eprintln!("ok_runc succeeded."); + eprintln!("ok_runh succeeded."); - let fail_runc = fail_client(); - match fail_runc.delete("fake-id", Some(&opts)) { - Ok(_) => panic!("fail_runc returned exit status 0."), + let fail_runh = fail_client(); + match fail_runh.delete("fake-id", Some(&opts)) { + Ok(_) => panic!("fail_runh returned exit status 0."), Err(Error::CommandFailed { status, stdout, stderr, }) => { if status.code().unwrap() == 1 && stdout.is_empty() && stderr.is_empty() { - eprintln!("fail_runc succeeded."); + eprintln!("fail_runh succeeded."); } else { - panic!("unexpected outputs from fail_runc.") + panic!("unexpected outputs from fail_runh.") } } - Err(e) => panic!("unexpected error from fail_runc: {:?}", e), + Err(e) => panic!("unexpected error from fail_runh: {:?}", e), } } @@ -806,8 +806,8 @@ mod tests { // test create cmd with inherit Io, expect empty cmd output let mut opts = CreateOpts::new(); opts.io = Some(Arc::new(InheritedStdIo::new().unwrap())); - let echo_runc = echo_client(); - let response = echo_runc + let echo_runh = echo_client(); + let response = echo_runh .create("fake-id", "fake-bundle", Some(&opts)) .expect("echo failed."); assert_ne!(response.pid, 0); @@ -817,8 +817,8 @@ mod tests { // test create cmd with pipe Io, expect nonempty cmd output let mut opts = CreateOpts::new(); opts.io = Some(Arc::new(PipedStdIo::new().unwrap())); - let echo_runc = echo_client(); - let response = echo_runc + let echo_runh = echo_client(); + let response = echo_runh .create("fake-id", "fake-bundle", Some(&opts)) .expect("echo failed."); assert_ne!(response.pid, 0); @@ -842,29 +842,29 @@ mod tests { GlobalOpts::new() .command("/bin/true") .build() - .expect("unable to create runc instance") + .expect("unable to create runh instance") } fn fail_client() -> Runh { GlobalOpts::new() .command("/bin/false") .build() - .expect("unable to create runc instance") + .expect("unable to create runh instance") } fn echo_client() -> Runh { GlobalOpts::new() .command("/bin/echo") .build() - .expect("unable to create runc instance") + .expect("unable to create runh instance") } #[tokio::test] async fn test_async_create() { let opts = CreateOpts::new(); - let ok_runc = ok_client(); + let ok_runh = ok_client(); let ok_task = tokio::spawn(async move { - let response = ok_runc + let response = ok_runh .create("fake-id", "fake-bundle", Some(&opts)) .await .expect("true failed."); @@ -874,25 +874,25 @@ mod tests { }); let opts = CreateOpts::new(); - let fail_runc = fail_client(); + let fail_runh = fail_client(); let fail_task = tokio::spawn(async move { - match fail_runc + match fail_runh .create("fake-id", "fake-bundle", Some(&opts)) .await { - Ok(_) => panic!("fail_runc returned exit status 0."), + Ok(_) => panic!("fail_runh returned exit status 0."), Err(Error::CommandFailed { status, stdout, stderr, }) => { if status.code().unwrap() == 1 && stdout.is_empty() && stderr.is_empty() { - eprintln!("fail_runc succeeded."); + eprintln!("fail_runh succeeded."); } else { - panic!("unexpected outputs from fail_runc.") + panic!("unexpected outputs from fail_runh.") } } - Err(e) => panic!("unexpected error from fail_runc: {:?}", e), + Err(e) => panic!("unexpected error from fail_runh: {:?}", e), } }); @@ -902,28 +902,28 @@ mod tests { #[tokio::test] async fn test_async_start() { - let ok_runc = ok_client(); + let ok_runh = ok_client(); let ok_task = tokio::spawn(async move { - ok_runc.start("fake-id").await.expect("true failed."); - eprintln!("ok_runc succeeded."); + ok_runh.start("fake-id").await.expect("true failed."); + eprintln!("ok_runh succeeded."); }); - let fail_runc = fail_client(); + let fail_runh = fail_client(); let fail_task = tokio::spawn(async move { - match fail_runc.start("fake-id").await { - Ok(_) => panic!("fail_runc returned exit status 0."), + match fail_runh.start("fake-id").await { + Ok(_) => panic!("fail_runh returned exit status 0."), Err(Error::CommandFailed { status, stdout, stderr, }) => { if status.code().unwrap() == 1 && stdout.is_empty() && stderr.is_empty() { - eprintln!("fail_runc succeeded."); + eprintln!("fail_runh succeeded."); } else { - panic!("unexpected outputs from fail_runc.") + panic!("unexpected outputs from fail_runh.") } } - Err(e) => panic!("unexpected error from fail_runc: {:?}", e), + Err(e) => panic!("unexpected error from fail_runh: {:?}", e), } }); @@ -934,35 +934,35 @@ mod tests { #[tokio::test] async fn test_async_run() { let opts = CreateOpts::new(); - let ok_runc = ok_client(); + let ok_runh = ok_client(); tokio::spawn(async move { - ok_runc + ok_runh .create("fake-id", "fake-bundle", Some(&opts)) .await .expect("true failed."); - eprintln!("ok_runc succeeded."); + eprintln!("ok_runh succeeded."); }); let opts = CreateOpts::new(); - let fail_runc = fail_client(); + let fail_runh = fail_client(); tokio::spawn(async move { - match fail_runc + match fail_runh .create("fake-id", "fake-bundle", Some(&opts)) .await { - Ok(_) => panic!("fail_runc returned exit status 0."), + Ok(_) => panic!("fail_runh returned exit status 0."), Err(Error::CommandFailed { status, stdout, stderr, }) => { if status.code().unwrap() == 1 && stdout.is_empty() && stderr.is_empty() { - eprintln!("fail_runc succeeded."); + eprintln!("fail_runh succeeded."); } else { - panic!("unexpected outputs from fail_runc.") + panic!("unexpected outputs from fail_runh.") } } - Err(e) => panic!("unexpected error from fail_runc: {:?}", e), + Err(e) => panic!("unexpected error from fail_runh: {:?}", e), } }) .await @@ -972,32 +972,32 @@ mod tests { #[tokio::test] async fn test_async_delete() { let opts = DeleteOpts::new(); - let ok_runc = ok_client(); + let ok_runh = ok_client(); tokio::spawn(async move { - ok_runc + ok_runh .delete("fake-id", Some(&opts)) .await .expect("true failed."); - eprintln!("ok_runc succeeded."); + eprintln!("ok_runh succeeded."); }); let opts = DeleteOpts::new(); - let fail_runc = fail_client(); - tokio::spawn(async move { - match fail_runc.delete("fake-id", Some(&opts)).await { - Ok(_) => panic!("fail_runc returned exit status 0."), + let fail_runh = fail_client(); + tokio::spawn(asynh move { + match fail_runh.delete("fake-id", Some(&opts)).await { + Ok(_) => panic!("fail_runh returned exit status 0."), Err(Error::CommandFailed { status, stdout, stderr, }) => { if status.code().unwrap() == 1 && stdout.is_empty() && stderr.is_empty() { - eprintln!("fail_runc succeeded."); + eprintln!("fail_runh succeeded."); } else { - panic!("unexpected outputs from fail_runc.") + panic!("unexpected outputs from fail_runh.") } } - Err(e) => panic!("unexpected error from fail_runc: {:?}", e), + Err(e) => panic!("unexpected error from fail_runh: {:?}", e), } }) .await @@ -1009,8 +1009,8 @@ mod tests { // test create cmd with inherit Io, expect empty cmd output let mut opts = CreateOpts::new(); opts.io = Some(Arc::new(InheritedStdIo::new().unwrap())); - let echo_runc = echo_client(); - let response = echo_runc + let echo_runh = echo_client(); + let response = echo_runh .create("fake-id", "fake-bundle", Some(&opts)) .await .expect("echo failed:"); @@ -1021,7 +1021,7 @@ mod tests { // test create cmd with pipe Io, expect nonempty cmd output let mut opts = CreateOpts::new(); opts.io = Some(Arc::new(PipedStdIo::new().unwrap())); - let response = echo_runc + let response = echo_runh .create("fake-id", "fake-bundle", Some(&opts)) .await .expect("echo failed:");