From deea90ff8396ee5bfa0859c76c72e7b42cf76890 Mon Sep 17 00:00:00 2001 From: jiaxiao zhou Date: Thu, 3 Aug 2023 22:09:12 +0000 Subject: [PATCH] feat(runc-shim): add a version flag Signed-off-by: jiaxiao zhou --- crates/runc-shim/build.rs | 39 ++++++++++++++++++++++++++ crates/runc-shim/src/main.rs | 18 +++++++++++- crates/shim/src/args.rs | 17 ++---------- crates/shim/src/lib.rs | 2 +- crates/shim/src/synchronous/mod.rs | 44 ++++++++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 crates/runc-shim/build.rs diff --git a/crates/runc-shim/build.rs b/crates/runc-shim/build.rs new file mode 100644 index 0000000..5184c60 --- /dev/null +++ b/crates/runc-shim/build.rs @@ -0,0 +1,39 @@ +/* + 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. +*/ + +use std::{process::Command, str::from_utf8}; + +fn main() { + let output = match Command::new("git").arg("rev-parse").arg("HEAD").output() { + Ok(output) => output, + Err(_) => { + return; + } + }; + let mut hash = from_utf8(&output.stdout).unwrap().trim().to_string(); + + let output_dirty = match Command::new("git").arg("diff").arg("--exit-code").output() { + Ok(output) => output, + Err(_) => { + return; + } + }; + + if !output_dirty.status.success() { + hash.push_str(".m"); + } + println!("cargo:rustc-env=CARGO_GIT_HASH={}", hash); +} diff --git a/crates/runc-shim/src/main.rs b/crates/runc-shim/src/main.rs index d75e70d..e5b180f 100644 --- a/crates/runc-shim/src/main.rs +++ b/crates/runc-shim/src/main.rs @@ -14,7 +14,9 @@ limitations under the License. */ -use containerd_shim::asynchronous::run; +use std::env; + +use containerd_shim::{asynchronous::run, parse}; mod common; mod console; @@ -27,7 +29,21 @@ mod task; use service::Service; +fn parse_version() { + let os_args: Vec<_> = env::args_os().collect(); + let flags = parse(&os_args[1..]).unwrap(); + if flags.version { + println!("{}:", os_args[0].to_string_lossy()); + println!(" Version: {}", env!("CARGO_PKG_VERSION")); + println!(" Revision: {}", env!("CARGO_GIT_HASH")); + println!(); + + std::process::exit(0); + } +} + #[tokio::main] async fn main() { + parse_version(); run::("io.containerd.runc.v2-rs", None).await; } diff --git a/crates/shim/src/args.rs b/crates/shim/src/args.rs index e67618b..325f479 100644 --- a/crates/shim/src/args.rs +++ b/crates/shim/src/args.rs @@ -39,15 +39,17 @@ pub struct Flags { /// Shim action (start / delete). /// See pub action: String, + /// Version of the shim. + pub version: bool, } /// Parses command line arguments passed to the shim. -/// This func replicates https://github.com/containerd/containerd/blob/master/runtime/v2/shim/shim.go#L110 pub fn parse>(args: &[S]) -> Result { let mut flags = Flags::default(); let args: Vec = go_flag::parse_args(args, |f| { f.add_flag("debug", &mut flags.debug); + f.add_flag("v", &mut flags.version); f.add_flag("namespace", &mut flags.namespace); f.add_flag("id", &mut flags.id); f.add_flag("socket", &mut flags.socket); @@ -61,12 +63,6 @@ pub fn parse>(args: &[S]) -> Result { flags.action = action.into(); } - if flags.namespace.is_empty() { - return Err(Error::InvalidArgument(String::from( - "Shim namespace cannot be empty", - ))); - } - Ok(flags) } @@ -125,11 +121,4 @@ mod tests { assert_eq!(flags.action, "start"); assert_eq!(flags.id, ""); } - - #[test] - fn no_namespace() { - let empty: [String; 0] = []; - let result = parse(&empty).err(); - assert!(result.is_some()) - } } diff --git a/crates/shim/src/lib.rs b/crates/shim/src/lib.rs index 9f88a9f..2ec2f8f 100644 --- a/crates/shim/src/lib.rs +++ b/crates/shim/src/lib.rs @@ -65,7 +65,7 @@ pub use crate::synchronous::*; pub mod error; mod args; -pub use args::Flags; +pub use args::{parse, Flags}; #[cfg(feature = "async")] pub mod asynchronous; pub mod cgroup; diff --git a/crates/shim/src/synchronous/mod.rs b/crates/shim/src/synchronous/mod.rs index b199390..5309747 100644 --- a/crates/shim/src/synchronous/mod.rs +++ b/crates/shim/src/synchronous/mod.rs @@ -201,6 +201,12 @@ where let os_args: Vec<_> = env::args_os().collect(); let flags = args::parse(&os_args[1..])?; + if flags.namespace.is_empty() { + return Err(Error::InvalidArgument(String::from( + "Shim namespace cannot be empty", + ))); + } + let ttrpc_address = env::var(TTRPC_ADDRESS)?; // Create shim instance @@ -593,4 +599,42 @@ mod tests { panic!("{:?}", err); } } + + struct Nop {} + + struct NopTask {} + impl Task for NopTask {} + + impl Shim for Nop { + type T = NopTask; + + fn new(_runtime_id: &str, _args: &Flags, _config: &mut Config) -> Self { + Nop {} + } + + fn start_shim(&mut self, _opts: StartOpts) -> Result { + Ok("".to_string()) + } + + fn delete_shim(&mut self) -> Result { + Ok(DeleteResponse::default()) + } + + fn wait(&mut self) {} + + fn create_task_service(&self, _publisher: RemotePublisher) -> Self::T { + NopTask {} + } + } + + #[test] + fn no_namespace() { + let runtime_id = "test"; + let res = bootstrap::(runtime_id, None); + assert!(res.is_err()); + assert!(res + .unwrap_err() + .to_string() + .contains("Shim namespace cannot be empty")); + } }