-
Notifications
You must be signed in to change notification settings - Fork 86
runc client #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
runc client #22
Changes from all commits
d34fa45
7c2b93f
2663849
43cf334
8bbd4e7
8f3e556
eddd107
522e26f
6e17be8
18b5b99
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| [package] | ||
| name = "runc" | ||
| version = "0.1.0" | ||
| authors = ["Yuna Tomida <ytomida.mmm@gmail.com>", "The containerd Authors"] | ||
| edition = "2018" | ||
| license = "Apache-2.0" | ||
| repository = "https://github.com/containerd/rust-extensions" | ||
| keywords = ["containerd", "containers", "runc"] | ||
| description = "A crate for consuming the runc binary in your Rust applications" | ||
| homepage = "https://containerd.io" | ||
|
|
||
|
|
||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
| [dependencies] | ||
| async-trait = "0.1.52" | ||
| futures = "0.3.19" | ||
| libc = "0.2.112" | ||
| log = "0.4.14" | ||
| nix = "0.23.1" | ||
| oci-spec = "0.5.4" | ||
| path-absolutize = "3.0.11" | ||
| rand = "0.8.4" | ||
| serde = { version = "1.0.133", features = ["derive"] } | ||
| serde_json = "1.0.74" | ||
| tempfile = "3.3.0" | ||
| thiserror = "1.0.30" | ||
| time = { version = "0.3.7", features = ["serde", "std"] } | ||
| tokio = { version = "1.15.0", features = ["full"] } | ||
| uuid = { version = "0.8.2", features = ["v4"] } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| # Rust binding for runc client | ||
|
|
||
| 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). | ||
|
|
||
| ## Usage | ||
| Both sync/async version is available. | ||
| You can build runc client with `RuncConfig` 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 | ||
| use runc; | ||
|
|
||
| #[tokio::main] | ||
| async fn main() { | ||
| let config = runc::Config::new() | ||
| .root("./new_root") | ||
| .debug(false) | ||
| .log("/path/to/logfile.json") | ||
| .log_format(runc::LogFormat::Json) | ||
| .rootless(true); | ||
|
|
||
| let client = config.build_async().unwrap(); | ||
|
|
||
| let opts = runc::options::CreateOpts::new() | ||
| .pid_file("/path/to/pid/file") | ||
| .no_pivot(true); | ||
|
|
||
| client.create("container-id", "path/to/bundle", Some(&opts)).unwrap(); | ||
| } | ||
| ``` | ||
|
|
||
| ## Limitations | ||
| - Supported commands are only: | ||
| - create | ||
| - start | ||
| - state | ||
| - kill | ||
| - delete | ||
| - Exec is **not** available in `RuncAsyncClient` now. | ||
| - Console utilites are **not** available | ||
| - see [Go version](https://github.com/containerd/go-runc/blob/main/console.go) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| /* | ||
| Copyright The containerd Authors. | ||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||
| you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| */ | ||
|
|
||
| // Forked from https://github.com/pwFoo/rust-runc/blob/313e6ae5a79b54455b0a242a795c69adf035141a/src/lib.rs | ||
|
|
||
| /* | ||
| * Copyright 2020 fsyncd, Berlin, Germany. | ||
| * Additional material, copyright of the containerd authors. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| use std::collections::HashMap; | ||
|
|
||
| use serde::{Deserialize, Serialize}; | ||
| use time::serde::timestamp; | ||
| use time::OffsetDateTime; | ||
|
|
||
| /// Information for runc container | ||
| #[derive(Debug, Serialize, Deserialize)] | ||
| pub struct Container { | ||
| pub id: String, | ||
| pub pid: usize, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. u32? Response's pid is u32.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's right, thank you! |
||
| pub status: String, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| pub bundle: String, | ||
| pub rootfs: String, | ||
| #[serde(with = "timestamp")] | ||
| pub created: OffsetDateTime, | ||
| pub annotations: HashMap<String, String>, | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
| #[test] | ||
| fn serde_test() { | ||
| let j = r#" | ||
| { | ||
| "id": "fake", | ||
| "pid": 1000, | ||
| "status": "RUNNING", | ||
| "bundle": "/path/to/bundle", | ||
| "rootfs": "/path/to/rootfs", | ||
| "created": 1431684000, | ||
| "annotations": { | ||
| "foo": "bar" | ||
| } | ||
| }"#; | ||
|
|
||
| let c: Container = serde_json::from_str(j).unwrap(); | ||
| assert_eq!(c.id, "fake"); | ||
| assert_eq!(c.pid, 1000); | ||
| assert_eq!(c.status, "RUNNING"); | ||
| assert_eq!(c.bundle, "/path/to/bundle"); | ||
| assert_eq!(c.rootfs, "/path/to/rootfs"); | ||
| assert_eq!( | ||
| c.created, | ||
| OffsetDateTime::from_unix_timestamp(1431684000).unwrap() | ||
| ); | ||
| assert_eq!(c.annotations.get("foo"), Some(&"bar".to_string())); | ||
| assert_eq!(c.annotations.get("bar"), None); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| /* | ||
| Copyright The containerd Authors. | ||
|
|
||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||
| you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| */ | ||
|
|
||
| // Forked from https://github.com/pwFoo/rust-runc/blob/313e6ae5a79b54455b0a242a795c69adf035141a/src/lib.rs | ||
|
|
||
| /* | ||
| * Copyright 2020 fsyncd, Berlin, Germany. | ||
| * Additional material, copyright of the containerd authors. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| use std::env; | ||
| use std::io; | ||
| use std::process::ExitStatus; | ||
|
|
||
| use thiserror::Error; | ||
|
|
||
| #[derive(Error, Debug)] | ||
| pub enum Error { | ||
| #[error("Unable to extract test files: {0}")] | ||
| BundleExtractFailed(io::Error), | ||
|
|
||
| #[error("Invalid path: {0}")] | ||
| InvalidPath(io::Error), | ||
|
|
||
| #[error(transparent)] | ||
| JsonDeserializationFailed(#[from] serde_json::error::Error), | ||
|
|
||
| #[error("Missing container statistics")] | ||
| MissingContainerStats, | ||
|
|
||
| #[error(transparent)] | ||
| ProcessSpawnFailed(io::Error), | ||
|
|
||
| #[error("Error occured in runc: {0}")] | ||
| InvalidCommand(io::Error), | ||
|
|
||
| #[error("Runc command failed: status={status}, stdout=\"{stdout}\", stderr=\"{stderr}\"")] | ||
| CommandFailed { | ||
| status: ExitStatus, | ||
| stdout: String, | ||
| stderr: String, | ||
| }, | ||
|
|
||
| #[error("Runc IO unavailable: {0}")] | ||
| UnavailableIO(io::Error), | ||
|
|
||
| #[error("Runc command timed out: {0}")] | ||
| CommandTimeout(tokio::time::error::Elapsed), | ||
|
|
||
| #[error("Unable to parse runc version")] | ||
| InvalidVersion, | ||
|
|
||
| #[error("Unable to locate the runc")] | ||
| NotFound, | ||
|
|
||
| #[error("Error occurs with fs: {0}")] | ||
| FileSystemError(io::Error), | ||
|
|
||
| #[error("Failed to spec file: {0}")] | ||
| SpecFileCreationFailed(io::Error), | ||
|
|
||
| #[error(transparent)] | ||
| SpecFileCleanupFailed(io::Error), | ||
|
|
||
| #[error("Failed to find valid path for spec file")] | ||
| SpecFileNotFound, | ||
|
|
||
| #[error("Top command is missing a pid header")] | ||
| TopMissingPidHeader, | ||
|
|
||
| #[error("Top command returned an empty response")] | ||
| TopShortResponseError, | ||
|
|
||
| #[error("Unix socket connection error: {0}")] | ||
| UnixSocketConnectionFailed(io::Error), | ||
|
|
||
| #[error("Unable to bind to unix socket: {0}")] | ||
| UnixSocketBindFailed(io::Error), | ||
|
|
||
| #[error("Unix socket failed to receive pty")] | ||
| UnixSocketReceiveMessageFailed, | ||
|
|
||
| #[error("Unix socket unexpectedly closed")] | ||
| UnixSocketClosed, | ||
|
|
||
| #[error("Failed to handle environment variable: {0}")] | ||
| EnvError(env::VarError), | ||
|
|
||
| #[error("Sorry, this part of api is not implemented: {0}")] | ||
| Unimplemented(String), | ||
|
|
||
| #[error("Error occured in runc client: {0}")] | ||
| Other(Box<dyn std::error::Error + Send>), | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the test set the environment variable if so?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, usually set by pam_systemd (which is missing in GHA)