diff --git a/src/tools/kata-ctl/Cargo.toml b/src/tools/kata-ctl/Cargo.toml index 303335cbaa..eef1f5fbb9 100644 --- a/src/tools/kata-ctl/Cargo.toml +++ b/src/tools/kata-ctl/Cargo.toml @@ -11,7 +11,8 @@ edition = "2021" [dependencies] anyhow = "1.0.31" -clap = "2.33.0" +clap = { version = "3.2.20", features = ["derive", "cargo"] } +thiserror = "1.0.35" [dev-dependencies] semver = "1.0.12" diff --git a/src/tools/kata-ctl/Makefile b/src/tools/kata-ctl/Makefile index 23d16e385a..e11af38457 100644 --- a/src/tools/kata-ctl/Makefile +++ b/src/tools/kata-ctl/Makefile @@ -20,7 +20,7 @@ COMMIT := $(if $(shell git status --porcelain --untracked-files=no 2>/dev/null | # Exported to allow cargo to see it export KATA_CTL_VERSION := $(if $(COMMIT),$(VERSION)-$(COMMIT),$(VERSION)) -GENERATED_CODE = src/version.rs +GENERATED_CODE = src/ops/version.rs GENERATED_REPLACEMENTS= \ KATA_CTL_VERSION diff --git a/src/tools/kata-ctl/src/arch/mod.rs b/src/tools/kata-ctl/src/arch/mod.rs index c18fb0c094..e72bcc4537 100644 --- a/src/tools/kata-ctl/src/arch/mod.rs +++ b/src/tools/kata-ctl/src/arch/mod.rs @@ -17,7 +17,7 @@ pub mod s390x; #[cfg(target_arch = "x86_64")] pub mod x86_64; -pub fn check(global_args: clap::ArgMatches) -> Result<()> { +pub fn check() -> Result<()> { #[cfg(target_arch = "aarch64")] let result = aarch64::check(); @@ -28,7 +28,7 @@ pub fn check(global_args: clap::ArgMatches) -> Result<()> { let result = s390x::check(); #[cfg(target_arch = "x86_64")] - let result = x86_64::check(global_args); + let result = x86_64::check(); #[cfg(not(any( target_arch = "aarch64", diff --git a/src/tools/kata-ctl/src/arch/x86_64/mod.rs b/src/tools/kata-ctl/src/arch/x86_64/mod.rs index 5618a44512..9c761d1187 100644 --- a/src/tools/kata-ctl/src/arch/x86_64/mod.rs +++ b/src/tools/kata-ctl/src/arch/x86_64/mod.rs @@ -41,7 +41,7 @@ mod arch_specific { } - pub fn check(_global_args: clap::ArgMatches) -> Result<()> { + pub fn check() -> Result<()> { println!("INFO: check: x86_64"); let _cpu_result = check_cpu(); diff --git a/src/tools/kata-ctl/src/args.rs b/src/tools/kata-ctl/src/args.rs new file mode 100644 index 0000000000..4c8bf51fcd --- /dev/null +++ b/src/tools/kata-ctl/src/args.rs @@ -0,0 +1,90 @@ +// Copyright (c) 2022 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +use clap::{ + Args, + Parser, + Subcommand +}; + +use thiserror::Error; + +#[derive(Parser, Debug)] +#[clap(name = "kata-ctl", author, about="Kata Containers control tool")] +pub struct KataCtlCli { + #[clap(subcommand)] + pub command: Commands, +} + +#[derive(Debug, Subcommand)] +pub enum Commands { + /// Tests if system can run Kata Containers + Check(CheckArgument), + + /// Directly assign a volume to Kata Containers to manage + DirectVolume, + + /// Display settings + Env, + + /// Enter into guest by debug console + Exec, + + /// Manage vm factory + Factory, + + /// Manages iptables + Iptables(IptablesCommand), + + /// Gather metrics associated with infrastructure used to run a sandbox + Metrics(MetricsCommand), + + /// Display version details + Version, +} + +#[derive(Debug,Args,Error)] +#[error("Argument is not valid")] +pub struct CheckArgument { + #[clap(subcommand)] + pub command: CheckSubCommand, +} + +#[derive(Debug, Subcommand)] +pub enum CheckSubCommand { + /// Runs all checks + All, + + /// Runs all checks but excluding network checks. + NoNetworkChecks, + + /// Only compare the current and latest available versions + CheckVersionOnly, +} + +#[derive(Debug,Args)] +pub struct MetricsCommand { + #[clap(subcommand)] + pub metrics_cmd: MetricsSubCommand, +} + +#[derive(Debug, Subcommand)] +pub enum MetricsSubCommand { + /// Arguments for metrics + MetricsArgs, +} + +// #[derive(Parser, Debug)] +#[derive(Debug, Args)] +pub struct IptablesCommand { + #[clap(subcommand)] + pub iptables: IpTablesArguments, +} + +#[derive(Debug, Subcommand)] +pub enum IpTablesArguments { + /// Configure iptables + Metrics, +} diff --git a/src/tools/kata-ctl/src/check.rs b/src/tools/kata-ctl/src/check.rs index 9317b903a1..6a3788d959 100644 --- a/src/tools/kata-ctl/src/check.rs +++ b/src/tools/kata-ctl/src/check.rs @@ -86,7 +86,11 @@ pub fn check_cpu_attribs(cpu_info: &str, required_attribs: &'static [&'static st } pub fn run_network_checks() -> Result<()> { - unimplemented!("Tests using network checks not implemented"); + Ok(()) +} + +pub fn check_version() -> Result<()> { + Ok(()) } #[cfg(test)] @@ -110,4 +114,3 @@ mod tests { assert_eq!(expected, actual); } } - diff --git a/src/tools/kata-ctl/src/main.rs b/src/tools/kata-ctl/src/main.rs index 484c78a8aa..5fb21b049c 100644 --- a/src/tools/kata-ctl/src/main.rs +++ b/src/tools/kata-ctl/src/main.rs @@ -3,116 +3,44 @@ // SPDX-License-Identifier: Apache-2.0 // -use anyhow::{anyhow, Result}; -use clap::{crate_name, App, Arg, SubCommand}; -use std::process::exit; - +mod args; mod arch; mod check; -mod utils; -mod version; +mod ops; -const DESCRIPTION_TEXT: &str = r#"DESCRIPTION: - kata-ctl description placeholder."#; +use clap::Parser; +use anyhow::Result; +use std::process::exit; -const ABOUT_TEXT: &str = "Kata Containers control tool"; +use args::{ + KataCtlCli, + Commands +}; -const NAME: &str = "kata-ctl"; - -fn run_checks(global_args: clap::ArgMatches) -> Result<()> { - let args = global_args - .subcommand_matches("check") - .ok_or_else(|| anyhow!("BUG: missing sub-command arguments"))?; - - let no_network_check = args.is_present("no-network-checks"); - - // run architecture-agnostic tests - if !no_network_check { - // run code that uses network checks - let _network_checks = check::run_network_checks(); - } - - // run architecture-specific tests - let _all_checks = arch::check(global_args); - - Ok(()) -} +use ops::check_ops::{ + handle_check, + handle_check_volume, + handle_env, + handle_exec, + handle_factory, + handle_iptables, + handle_metrics, + handle_version +}; fn real_main() -> Result<()> { - let name = crate_name!(); - let version = version::get(); - let app = App::new(name) - .version(&*version) - .about(ABOUT_TEXT) - .long_about(DESCRIPTION_TEXT) - .subcommand( - SubCommand::with_name("check") - .about("tests if system can run Kata Containers") - .arg( - Arg::with_name("no-network-checks") - .long("no-network-checks") - .help("run check with no network checks") - .takes_value(false), - ), - ) - .subcommand( - SubCommand::with_name("direct-volume") - .about("directly assign a volume to Kata Containers to manage"), - ) - .subcommand(SubCommand::with_name("env").about("display settings. Default to TOML")) - .subcommand(SubCommand::with_name("exec").about("enter into guest by debug console")) - .subcommand(SubCommand::with_name("factory").about("manage vm factory")) - .subcommand( - SubCommand::with_name("help").about("shows a list of commands or help for one command"), - ) - .subcommand(SubCommand::with_name("iptables").about("")) - .subcommand( - SubCommand::with_name("metrics") - .about("gather metrics associated with infrastructure used to run a sandbox"), - ) - .subcommand(SubCommand::with_name("version").about("display version details")); + let args = KataCtlCli::parse(); - let args = app.get_matches(); - - let subcmd = args - .subcommand_name() - .ok_or_else(|| anyhow!("need sub-command"))?; - - match subcmd { - "check" => { - match run_checks(args) { - Ok(_result) => println!("check may not be fully implemented"), - Err(err) => println!("{}", err), - } - Ok(()) - } - "direct-volume" => { - unimplemented!("Not implemented"); - } - "env" => { - unimplemented!("Not implemented"); - } - "exec" => { - unimplemented!("Not implemented"); - } - "factory" => { - unimplemented!("Not implemented"); - } - "help" => { - unimplemented!("Not implemented"); - } - "iptables" => { - unimplemented!("Not implemented"); - } - "metrics" => { - unimplemented!("Not implemented"); - } - "version" => { - println!("{} version {} (type: rust)", NAME, version); - Ok(()) - } - _ => return Err(anyhow!(format!("invalid sub-command: {:?}", subcmd))), + match args.command { + Commands::Check(args) => handle_check(args), + Commands::DirectVolume => handle_check_volume(), + Commands::Env => handle_env(), + Commands::Exec => handle_exec(), + Commands::Factory => handle_factory(), + Commands::Iptables(args) => handle_iptables(args), + Commands::Metrics(args) => handle_metrics(args), + Commands::Version => handle_version(), } } diff --git a/src/tools/kata-ctl/src/utils.rs b/src/tools/kata-ctl/src/ops.rs similarity index 69% rename from src/tools/kata-ctl/src/utils.rs rename to src/tools/kata-ctl/src/ops.rs index 59289ad4a9..3e0f9a4e32 100644 --- a/src/tools/kata-ctl/src/utils.rs +++ b/src/tools/kata-ctl/src/ops.rs @@ -2,3 +2,6 @@ // // SPDX-License-Identifier: Apache-2.0 // + +pub mod check_ops; +pub mod version; diff --git a/src/tools/kata-ctl/src/ops/check_ops.rs b/src/tools/kata-ctl/src/ops/check_ops.rs new file mode 100644 index 0000000000..a35c2c15d5 --- /dev/null +++ b/src/tools/kata-ctl/src/ops/check_ops.rs @@ -0,0 +1,75 @@ +// Copyright (c) 2022 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +use crate::arch; +use crate::check; +use crate::ops::version; + +use crate::args::{ + CheckArgument, + CheckSubCommand, + IptablesCommand, + MetricsCommand +}; + +use anyhow::Result; + +const NAME: &str = "kata-ctl"; + +pub fn handle_check(checkcmd: CheckArgument) -> Result<()> { + let command = checkcmd.command; + + match command { + CheckSubCommand::All => { + // run architecture-specific tests + arch::check()?; + + // run code that uses network checks + check::run_network_checks()?; + } + + CheckSubCommand::NoNetworkChecks => { + // run architecture-specific tests + arch::check()?; + } + + CheckSubCommand::CheckVersionOnly => { + // retrieve latest release + check::check_version()?; + } + } + + Ok(()) +} + +pub fn handle_check_volume() -> Result<()> { + Ok(()) +} + +pub fn handle_env() -> Result<()> { + Ok(()) +} + +pub fn handle_exec() -> Result<()> { + Ok(()) +} + +pub fn handle_factory() -> Result<()> { + Ok(()) +} + +pub fn handle_iptables(args: IptablesCommand) -> Result<()> { + Ok(()) +} + +pub fn handle_metrics(args: MetricsCommand) -> Result<()> { + Ok(()) +} + +pub fn handle_version() -> Result<()> { + let version = version::get().unwrap(); + println!("{} version {:?} (type: rust)", NAME, version); + Ok(()) +} diff --git a/src/tools/kata-ctl/src/version.rs.in b/src/tools/kata-ctl/src/ops/version.rs.in similarity index 65% rename from src/tools/kata-ctl/src/version.rs.in rename to src/tools/kata-ctl/src/ops/version.rs.in index b17824a1c7..16b3c7e7f3 100644 --- a/src/tools/kata-ctl/src/version.rs.in +++ b/src/tools/kata-ctl/src/ops/version.rs.in @@ -11,8 +11,14 @@ use clap::crate_version; const KATA_CTL_VERSION: &str = "@KATA_CTL_VERSION@"; -pub fn get() -> String { - format!("{}-{}", KATA_CTL_VERSION, crate_version!()) +pub fn get() -> Result { + if KATA_CTL_VERSION.trim().is_empty() { + return Err("Unable to retrieve kata Version. Check that Kata is properly installed".to_string()); + } + else { + let version=format!("{}-{}", KATA_CTL_VERSION, crate_version!()); + return Ok(version); + } } #[cfg(test)]