kata-ctl: switch to use clap derive for CLI handling

Switch from the functional version of `clap` to the declarative
methodology.

Signed-off-by: David Esparza <david.esparza.borquez@intel.com>
Commit-edited-by: James O. D. Hunt <james.o.hunt@intel.com>
This commit is contained in:
David Esparza 2022-09-14 07:32:21 -05:00 committed by James O. D. Hunt
parent 018aa899cb
commit eb5423cb7f
10 changed files with 216 additions and 110 deletions

View File

@ -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"

View File

@ -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

View File

@ -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",

View File

@ -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();

View File

@ -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,
}

View File

@ -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);
}
}

View File

@ -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(),
}
}

View File

@ -2,3 +2,6 @@
//
// SPDX-License-Identifier: Apache-2.0
//
pub mod check_ops;
pub mod version;

View File

@ -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(())
}

View File

@ -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<String, String> {
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)]