From 002b18054d82e594a50c2bb0c0fd6fd837c370dd Mon Sep 17 00:00:00 2001 From: Chelsea Mafrica Date: Wed, 13 Jul 2022 00:52:36 -0700 Subject: [PATCH 01/17] kata-ctl: Add initial rust code for kata-ctl Use agent-ctl tool rust code as an example for a skeleton for the new kata-ctl tool. Signed-off-by: Chelsea Mafrica --- src/tools/kata-ctl/.gitignore | 1 + src/tools/kata-ctl/Cargo.lock | 122 ++++++++++++++++++++++++++++++ src/tools/kata-ctl/Cargo.toml | 14 ++++ src/tools/kata-ctl/Makefile | 33 ++++++++ src/tools/kata-ctl/README.md | 15 ++++ src/tools/kata-ctl/src/main.rs | 129 ++++++++++++++++++++++++++++++++ src/tools/kata-ctl/src/utils.rs | 8 ++ 7 files changed, 322 insertions(+) create mode 100644 src/tools/kata-ctl/.gitignore create mode 100644 src/tools/kata-ctl/Cargo.lock create mode 100644 src/tools/kata-ctl/Cargo.toml create mode 100644 src/tools/kata-ctl/Makefile create mode 100644 src/tools/kata-ctl/README.md create mode 100644 src/tools/kata-ctl/src/main.rs create mode 100644 src/tools/kata-ctl/src/utils.rs diff --git a/src/tools/kata-ctl/.gitignore b/src/tools/kata-ctl/.gitignore new file mode 100644 index 0000000000..57872d0f1e --- /dev/null +++ b/src/tools/kata-ctl/.gitignore @@ -0,0 +1 @@ +/vendor/ diff --git a/src/tools/kata-ctl/Cargo.lock b/src/tools/kata-ctl/Cargo.lock new file mode 100644 index 0000000000..84da4ddc66 --- /dev/null +++ b/src/tools/kata-ctl/Cargo.lock @@ -0,0 +1,122 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "kata-ctl" +version = "0.0.0" +dependencies = [ + "anyhow", + "clap", +] + +[[package]] +name = "libc" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/src/tools/kata-ctl/Cargo.toml b/src/tools/kata-ctl/Cargo.toml new file mode 100644 index 0000000000..c3ec304ac0 --- /dev/null +++ b/src/tools/kata-ctl/Cargo.toml @@ -0,0 +1,14 @@ +# Copyright (c) 2022 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +[package] +name = "kata-ctl" +version = "0.0.0" +authors = ["The Kata Containers community "] +edition = "2021" + +[dependencies] +clap = "2.33.0" +anyhow = "1.0.31" diff --git a/src/tools/kata-ctl/Makefile b/src/tools/kata-ctl/Makefile new file mode 100644 index 0000000000..c050d6d477 --- /dev/null +++ b/src/tools/kata-ctl/Makefile @@ -0,0 +1,33 @@ +# Copyright (c) 2022 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +include ../../../utils.mk + +.DEFAULT_GOAL := default +default: build + +build: + @RUSTFLAGS="$(EXTRA_RUSTFLAGS) --deny warnings" cargo build --target $(TRIPLE) --$(BUILD_TYPE) + +clean: + cargo clean + +vendor: + cargo vendor + +test: + +install: + @RUSTFLAGS="$(EXTRA_RUSTFLAGS) --deny warnings" cargo install --target $(TRIPLE) --path . + +check: standard_rust_check + +.PHONY: \ + build \ + check \ + clean \ + install \ + test \ + vendor diff --git a/src/tools/kata-ctl/README.md b/src/tools/kata-ctl/README.md new file mode 100644 index 0000000000..1e441d58b2 --- /dev/null +++ b/src/tools/kata-ctl/README.md @@ -0,0 +1,15 @@ +# Kata Containers control tool + +## Overview + +## Audience and environment + +## History + +## Full details + +## Code summary + +## Run the tool + +### Prerequisites diff --git a/src/tools/kata-ctl/src/main.rs b/src/tools/kata-ctl/src/main.rs new file mode 100644 index 0000000000..9b3c0bf2e7 --- /dev/null +++ b/src/tools/kata-ctl/src/main.rs @@ -0,0 +1,129 @@ +// Copyright (c) 2022 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +use anyhow::{anyhow, Result}; +use clap::{crate_name, crate_version, App, Arg, SubCommand}; +use std::process::exit; + +mod utils; + +const DESCRIPTION_TEXT: &str = r#"DESCRIPTION: + kata-ctl description placeholder."#; + +const ABOUT_TEXT: &str = "Kata Containers control tool"; + +fn real_main() -> Result<()> { + let name = crate_name!(); + + let app = App::new(name) + .version(crate_version!()) + .about(ABOUT_TEXT) + .long_about(DESCRIPTION_TEXT) + .subcommand( + SubCommand::with_name("check") + .about("tests if system can run Kata Containers") + ) + .subcommand( + SubCommand::with_name("command-example") + .about("(remove when other subcommands have sufficient detail)") + .arg( + Arg::with_name("arg-example-1") + .long("arg-example-1") + .help("arg example for command-example") + .takes_value(true) + ) + ) + .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 = app.get_matches(); + + let subcmd = args + .subcommand_name() + .ok_or_else(|| anyhow!("need sub-command"))?; + + match subcmd { + "command-example" => { + println!("{}", utils::command_example(args)); + Ok(()) + } + "check" => { + println!("Not implemented"); + Ok(()) + } + "direct-volume" => { + println!("Not implemented"); + Ok(()) + } + "env" => { + println!("Not implemented"); + Ok(()) + } + "exec" => { + println!("Not implemented"); + Ok(()) + } + "factory" => { + println!("Not implemented"); + Ok(()) + } + "help" => { + println!("Not implemented"); + Ok(()) + } + "iptables" => { + println!("Not implemented"); + Ok(()) + } + "metrics" => { + println!("Not implemented"); + Ok(()) + } + "version" => { + println!("Not implemented"); + Ok(()) + } + _ => return Err(anyhow!(format!("invalid sub-command: {:?}", subcmd))), + } + +} + +fn main() { + if let Err(e) = real_main() { + eprintln!("ERROR: {:#?}", e); + exit(1); + } +} diff --git a/src/tools/kata-ctl/src/utils.rs b/src/tools/kata-ctl/src/utils.rs new file mode 100644 index 0000000000..b779c2147b --- /dev/null +++ b/src/tools/kata-ctl/src/utils.rs @@ -0,0 +1,8 @@ +// Copyright (c) 2022 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +pub fn command_example(_global_args: clap::ArgMatches) -> String { + "test utils command".to_string() +} From d0b33e9a32cddee11b14f06b09af651189148ad3 Mon Sep 17 00:00:00 2001 From: David Esparza Date: Wed, 20 Jul 2022 19:26:32 -0500 Subject: [PATCH 02/17] versions: Add kata-ctl version entry As we're switching to using the rust version of the kata-ctl, lets provide with its own entry in the kata-ctl command line. Signed-off-by: David Esparza Commit-edited-by: James O. D. Hunt --- src/tools/kata-ctl/Cargo.toml | 2 +- src/tools/kata-ctl/Makefile | 36 +++++++++++++++++++++++++--- src/tools/kata-ctl/VERSION | 1 + src/tools/kata-ctl/src/main.rs | 10 +++++--- src/tools/kata-ctl/src/version.rs.in | 16 +++++++++++++ 5 files changed, 58 insertions(+), 7 deletions(-) create mode 120000 src/tools/kata-ctl/VERSION create mode 100644 src/tools/kata-ctl/src/version.rs.in diff --git a/src/tools/kata-ctl/Cargo.toml b/src/tools/kata-ctl/Cargo.toml index c3ec304ac0..582ae631b7 100644 --- a/src/tools/kata-ctl/Cargo.toml +++ b/src/tools/kata-ctl/Cargo.toml @@ -5,7 +5,7 @@ [package] name = "kata-ctl" -version = "0.0.0" +version = "0.0.1" authors = ["The Kata Containers community "] edition = "2021" diff --git a/src/tools/kata-ctl/Makefile b/src/tools/kata-ctl/Makefile index c050d6d477..899c891a6a 100644 --- a/src/tools/kata-ctl/Makefile +++ b/src/tools/kata-ctl/Makefile @@ -5,14 +5,44 @@ include ../../../utils.mk +PROJECT_NAME = Kata Containers +PROJECT_URL = https://github.com/kata-containers +PROJECT_COMPONENT = kata-ctl + +TARGET = $(PROJECT_COMPONENT) + +VERSION_FILE := ./VERSION +VERSION := $(shell grep -v ^\# $(VERSION_FILE)) +COMMIT_NO := $(shell git rev-parse HEAD 2>/dev/null || true) +COMMIT_NO_SHORT := $(shell git rev-parse --short HEAD 2>/dev/null || true) +COMMIT := $(if $(shell git status --porcelain --untracked-files=no 2>/dev/null || true),${COMMIT_NO}-dirty,${COMMIT_NO}) + +# Exported to allow cargo to see it +export KATA_CTL_VERSION := $(if $(COMMIT),$(VERSION)-$(COMMIT),$(VERSION)) + +GENERATED_CODE = src/version.rs + +GENERATED_REPLACEMENTS= \ + KATA_CTL_VERSION + +GENERATED_FILES := $(GENERATED_CODE) + .DEFAULT_GOAL := default -default: build + +default: $(TARGET) build + +$(TARGET): $(GENERATED_CODE) build: - @RUSTFLAGS="$(EXTRA_RUSTFLAGS) --deny warnings" cargo build --target $(TRIPLE) --$(BUILD_TYPE) + @RUSTFLAGS="$(EXTRA_RUSTFLAGS) --deny warnings" cargo build --target $(TRIPLE) $(if $(findstring release,$(BUILD_TYPE)),--release) $(EXTRA_RUSTFEATURES) + +$(GENERATED_FILES): %: %.in + @sed $(foreach r,$(GENERATED_REPLACEMENTS),-e 's|@$r@|$($r)|g') "$<" > "$@" + clean: - cargo clean + @cargo clean + @rm -f $(GENERATED_FILES) vendor: cargo vendor diff --git a/src/tools/kata-ctl/VERSION b/src/tools/kata-ctl/VERSION new file mode 120000 index 0000000000..d62dc733ef --- /dev/null +++ b/src/tools/kata-ctl/VERSION @@ -0,0 +1 @@ +../../../VERSION \ No newline at end of file diff --git a/src/tools/kata-ctl/src/main.rs b/src/tools/kata-ctl/src/main.rs index 9b3c0bf2e7..7368c667e5 100644 --- a/src/tools/kata-ctl/src/main.rs +++ b/src/tools/kata-ctl/src/main.rs @@ -4,21 +4,25 @@ // use anyhow::{anyhow, Result}; -use clap::{crate_name, crate_version, App, Arg, SubCommand}; +use clap::{crate_name, App, Arg, SubCommand}; use std::process::exit; mod utils; +mod version; const DESCRIPTION_TEXT: &str = r#"DESCRIPTION: kata-ctl description placeholder."#; const ABOUT_TEXT: &str = "Kata Containers control tool"; +const NAME: &str = "kata-ctl"; + fn real_main() -> Result<()> { let name = crate_name!(); + let version = version::get(); let app = App::new(name) - .version(crate_version!()) + .version(&*version) .about(ABOUT_TEXT) .long_about(DESCRIPTION_TEXT) .subcommand( @@ -113,7 +117,7 @@ fn real_main() -> Result<()> { Ok(()) } "version" => { - println!("Not implemented"); + println!("{} version {} (type: rust)", NAME, version); Ok(()) } _ => return Err(anyhow!(format!("invalid sub-command: {:?}", subcmd))), diff --git a/src/tools/kata-ctl/src/version.rs.in b/src/tools/kata-ctl/src/version.rs.in new file mode 100644 index 0000000000..77b79d035f --- /dev/null +++ b/src/tools/kata-ctl/src/version.rs.in @@ -0,0 +1,16 @@ +// Copyright (c) 2020 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +// +// WARNING: This file is auto-generated - DO NOT EDIT! +// + +use clap::crate_version; + +const KATA_CTL_VERSION: &str = "@KATA_CTL_VERSION@"; + +pub fn get() -> String { + format!("{}-{}", KATA_CTL_VERSION, crate_version!()) +} From 303fc8b1183594585eb5ff37786b2de2acd41b95 Mon Sep 17 00:00:00 2001 From: David Esparza Date: Wed, 27 Jul 2022 11:31:23 -0500 Subject: [PATCH 03/17] kata-ctl: Add unit tests cases Add more unit tests cases to --version argument. Signed-off-by: David Esparza Commit-edited-by: James O. D. Hunt --- src/tools/kata-ctl/Cargo.lock | 122 --------------------------- src/tools/kata-ctl/Cargo.toml | 5 +- src/tools/kata-ctl/Makefile | 1 + src/tools/kata-ctl/src/version.rs.in | 19 ++++- 4 files changed, 23 insertions(+), 124 deletions(-) delete mode 100644 src/tools/kata-ctl/Cargo.lock diff --git a/src/tools/kata-ctl/Cargo.lock b/src/tools/kata-ctl/Cargo.lock deleted file mode 100644 index 84da4ddc66..0000000000 --- a/src/tools/kata-ctl/Cargo.lock +++ /dev/null @@ -1,122 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - -[[package]] -name = "anyhow" -version = "1.0.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim", - "textwrap", - "unicode-width", - "vec_map", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "kata-ctl" -version = "0.0.0" -dependencies = [ - "anyhow", - "clap", -] - -[[package]] -name = "libc" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" - -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/src/tools/kata-ctl/Cargo.toml b/src/tools/kata-ctl/Cargo.toml index 582ae631b7..303335cbaa 100644 --- a/src/tools/kata-ctl/Cargo.toml +++ b/src/tools/kata-ctl/Cargo.toml @@ -10,5 +10,8 @@ authors = ["The Kata Containers community "] edition = "2021" [dependencies] -clap = "2.33.0" anyhow = "1.0.31" +clap = "2.33.0" + +[dev-dependencies] +semver = "1.0.12" diff --git a/src/tools/kata-ctl/Makefile b/src/tools/kata-ctl/Makefile index 899c891a6a..23d16e385a 100644 --- a/src/tools/kata-ctl/Makefile +++ b/src/tools/kata-ctl/Makefile @@ -48,6 +48,7 @@ vendor: cargo vendor test: + @RUSTFLAGS="$(EXTRA_RUSTFLAGS) --deny warnings" cargo test --target $(TRIPLE) $(if $(findstring release,$(BUILD_TYPE)),--release) $(EXTRA_RUSTFEATURES) install: @RUSTFLAGS="$(EXTRA_RUSTFLAGS) --deny warnings" cargo install --target $(TRIPLE) --path . diff --git a/src/tools/kata-ctl/src/version.rs.in b/src/tools/kata-ctl/src/version.rs.in index 77b79d035f..b17824a1c7 100644 --- a/src/tools/kata-ctl/src/version.rs.in +++ b/src/tools/kata-ctl/src/version.rs.in @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Intel Corporation +// Copyright (c) 2022 Intel Corporation // // SPDX-License-Identifier: Apache-2.0 // @@ -14,3 +14,20 @@ const KATA_CTL_VERSION: &str = "@KATA_CTL_VERSION@"; pub fn get() -> String { format!("{}-{}", KATA_CTL_VERSION, crate_version!()) } + +#[cfg(test)] +mod tests { + use super::*; + use semver::{Version}; + + #[test] + fn test_get() { + let version = get(); + let v = Version::parse(&version).unwrap(); + + assert!(!v.major.to_string().is_empty()); + assert!(!v.minor.to_string().is_empty()); + assert!(!v.patch.to_string().is_empty()); + assert!(!v.pre.to_string().is_empty()); + } +} From 8e7bb8521c3516aff7ff5be5f279a5e00e8734e1 Mon Sep 17 00:00:00 2001 From: Chelsea Mafrica Date: Wed, 17 Aug 2022 02:56:28 -0700 Subject: [PATCH 04/17] kata-ctl: add code for framework for arch Add framework for different architectures for check. In the existing kata-runtime check, the network checks do not appear to be architecture-specific while the kernel module, cpu, and kvm checks do have separate implementations for different architectures. Signed-off-by: Chelsea Mafrica --- src/tools/kata-ctl/src/arch/aarch64/mod.rs | 15 +++++ src/tools/kata-ctl/src/arch/mod.rs | 42 ++++++++++++++ .../kata-ctl/src/arch/powerpc64le/mod.rs | 15 +++++ src/tools/kata-ctl/src/arch/s390x/mod.rs | 15 +++++ src/tools/kata-ctl/src/arch/x86_64/mod.rs | 17 ++++++ src/tools/kata-ctl/src/check.rs | 12 ++++ src/tools/kata-ctl/src/main.rs | 56 ++++++++++++------- src/tools/kata-ctl/src/utils.rs | 4 -- 8 files changed, 152 insertions(+), 24 deletions(-) create mode 100644 src/tools/kata-ctl/src/arch/aarch64/mod.rs create mode 100644 src/tools/kata-ctl/src/arch/mod.rs create mode 100644 src/tools/kata-ctl/src/arch/powerpc64le/mod.rs create mode 100644 src/tools/kata-ctl/src/arch/s390x/mod.rs create mode 100644 src/tools/kata-ctl/src/arch/x86_64/mod.rs create mode 100644 src/tools/kata-ctl/src/check.rs diff --git a/src/tools/kata-ctl/src/arch/aarch64/mod.rs b/src/tools/kata-ctl/src/arch/aarch64/mod.rs new file mode 100644 index 0000000000..6df39ce748 --- /dev/null +++ b/src/tools/kata-ctl/src/arch/aarch64/mod.rs @@ -0,0 +1,15 @@ +// Copyright (c) 2022 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +#[cfg(target_arch = "aarch64")] +pub use arch_specific::*; + +mod arch_specific { + use anyhow::Result; + + pub fn check() -> Result<()> { + unimplemented!("Check not implemented in aarch64") + } +} diff --git a/src/tools/kata-ctl/src/arch/mod.rs b/src/tools/kata-ctl/src/arch/mod.rs new file mode 100644 index 0000000000..ee6f926f75 --- /dev/null +++ b/src/tools/kata-ctl/src/arch/mod.rs @@ -0,0 +1,42 @@ +// Copyright (c) 2022 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +use anyhow::{Result}; + +#[cfg(target_arch = "aarch64")] +pub mod aarch64; + +#[cfg(target_arch = "powerpc64le")] +pub mod powerpc64le; + +#[cfg(target_arch = "s390x")] +pub mod s390x; + +#[cfg(target_arch = "x86_64")] +pub mod x86_64; + +pub fn check(global_args: clap::ArgMatches) -> Result<()> { + #[cfg(target_arch = "aarch64")] + let result = aarch64::check(); + + #[cfg(target_arch = "powerpc64le")] + let result = powerpc64le::check(); + + #[cfg(target_arch = "s390x")] + let result = s390x::check(); + + #[cfg(target_arch = "x86_64")] + let result = x86_64::check(global_args); + + #[cfg(not(any( + target_arch = "aarch64", + target_arch = "powerpc64le", + target_arch = "s390x", + target_arch = "x86_64" + )))] + panic!("unknown architecture"); + + result +} diff --git a/src/tools/kata-ctl/src/arch/powerpc64le/mod.rs b/src/tools/kata-ctl/src/arch/powerpc64le/mod.rs new file mode 100644 index 0000000000..a87ab02f8c --- /dev/null +++ b/src/tools/kata-ctl/src/arch/powerpc64le/mod.rs @@ -0,0 +1,15 @@ +// Copyright (c) 2022 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +#[cfg(target_arch = "powerpc64le")] +pub use arch_specific::*; + +mod arch_specific { + use anyhow::Result; + + pub fn check() -> Result<()> { + unimplemented!("Check not implemented in powerpc64le"); + } +} diff --git a/src/tools/kata-ctl/src/arch/s390x/mod.rs b/src/tools/kata-ctl/src/arch/s390x/mod.rs new file mode 100644 index 0000000000..7f6a424c3b --- /dev/null +++ b/src/tools/kata-ctl/src/arch/s390x/mod.rs @@ -0,0 +1,15 @@ +// Copyright (c) 2022 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +#[cfg(target_arch = "s390x")] +pub use arch_specific::*; + +mod arch_specific { + use anyhow::Result; + + pub fn check() -> Result<()> { + unimplemented!("Check not implemented in s390x"); + } +} diff --git a/src/tools/kata-ctl/src/arch/x86_64/mod.rs b/src/tools/kata-ctl/src/arch/x86_64/mod.rs new file mode 100644 index 0000000000..2f27dc2a44 --- /dev/null +++ b/src/tools/kata-ctl/src/arch/x86_64/mod.rs @@ -0,0 +1,17 @@ +// Copyright (c) 2022 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +#[cfg(target_arch = "x86_64")] +pub use arch_specific::*; + +mod arch_specific { + use anyhow::Result; + + pub fn check(_global_args: clap::ArgMatches) -> Result<()> { + println!("INFO: check: x86_64"); + + Ok(()) + } +} diff --git a/src/tools/kata-ctl/src/check.rs b/src/tools/kata-ctl/src/check.rs new file mode 100644 index 0000000000..be39e31e06 --- /dev/null +++ b/src/tools/kata-ctl/src/check.rs @@ -0,0 +1,12 @@ +// Copyright (c) 2022 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +// Contains checks that are not architecture-specific + +use anyhow::{Result}; + +pub fn run_network_checks() -> Result<()> { + unimplemented!("Tests using network checks not implemented"); +} diff --git a/src/tools/kata-ctl/src/main.rs b/src/tools/kata-ctl/src/main.rs index 7368c667e5..9338b4bd61 100644 --- a/src/tools/kata-ctl/src/main.rs +++ b/src/tools/kata-ctl/src/main.rs @@ -9,6 +9,8 @@ use std::process::exit; mod utils; mod version; +mod arch; +mod check; const DESCRIPTION_TEXT: &str = r#"DESCRIPTION: kata-ctl description placeholder."#; @@ -17,6 +19,25 @@ const ABOUT_TEXT: &str = "Kata Containers control tool"; 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(()) +} + fn real_main() -> Result<()> { let name = crate_name!(); let version = version::get(); @@ -28,15 +49,11 @@ fn real_main() -> Result<()> { .subcommand( SubCommand::with_name("check") .about("tests if system can run Kata Containers") - ) - .subcommand( - SubCommand::with_name("command-example") - .about("(remove when other subcommands have sufficient detail)") .arg( - Arg::with_name("arg-example-1") - .long("arg-example-1") - .help("arg example for command-example") - .takes_value(true) + Arg::with_name("no-network-checks") + .long("no-network-checks") + .help("run check with no network checks") + .takes_value(false) ) ) .subcommand( @@ -80,40 +97,39 @@ fn real_main() -> Result<()> { .ok_or_else(|| anyhow!("need sub-command"))?; match subcmd { - "command-example" => { - println!("{}", utils::command_example(args)); - Ok(()) - } "check" => { - println!("Not implemented"); + match run_checks(args) { + Ok(_result) => println!("check may not be fully implemented"), + Err(err) => println!("{}", err), + } Ok(()) } "direct-volume" => { - println!("Not implemented"); + unimplemented!("Not implemented"); Ok(()) } "env" => { - println!("Not implemented"); + unimplemented!("Not implemented"); Ok(()) } "exec" => { - println!("Not implemented"); + unimplemented!("Not implemented"); Ok(()) } "factory" => { - println!("Not implemented"); + unimplemented!("Not implemented"); Ok(()) } "help" => { - println!("Not implemented"); + unimplemented!("Not implemented"); Ok(()) } "iptables" => { - println!("Not implemented"); + unimplemented!("Not implemented"); Ok(()) } "metrics" => { - println!("Not implemented"); + unimplemented!("Not implemented"); Ok(()) } "version" => { diff --git a/src/tools/kata-ctl/src/utils.rs b/src/tools/kata-ctl/src/utils.rs index b779c2147b..59289ad4a9 100644 --- a/src/tools/kata-ctl/src/utils.rs +++ b/src/tools/kata-ctl/src/utils.rs @@ -2,7 +2,3 @@ // // SPDX-License-Identifier: Apache-2.0 // - -pub fn command_example(_global_args: clap::ArgMatches) -> String { - "test utils command".to_string() -} From cca7e32b54ec88938b9a1694e0a718b9eb1dafcd Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Wed, 17 Aug 2022 18:04:20 +0100 Subject: [PATCH 05/17] kata-ctl: Lint fixes to allow the branch to be built Remove return value for branches that call `unimplemented!()`. Signed-off-by: James O. D. Hunt --- src/tools/kata-ctl/src/main.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/tools/kata-ctl/src/main.rs b/src/tools/kata-ctl/src/main.rs index 9338b4bd61..17875bb0be 100644 --- a/src/tools/kata-ctl/src/main.rs +++ b/src/tools/kata-ctl/src/main.rs @@ -106,31 +106,24 @@ fn real_main() -> Result<()> { } "direct-volume" => { unimplemented!("Not implemented"); - Ok(()) } "env" => { unimplemented!("Not implemented"); - Ok(()) } "exec" => { unimplemented!("Not implemented"); - Ok(()) } "factory" => { unimplemented!("Not implemented"); - Ok(()) } "help" => { unimplemented!("Not implemented"); - Ok(()) } "iptables" => { unimplemented!("Not implemented"); - Ok(()) } "metrics" => { unimplemented!("Not implemented"); - Ok(()) } "version" => { println!("{} version {} (type: rust)", NAME, version); From b63ba66dc347377e5d4e2376f13349128b986c2d Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Wed, 17 Aug 2022 18:05:16 +0100 Subject: [PATCH 06/17] kata-ctl: Formatting tweaks Automatic format updates. Signed-off-by: James O. D. Hunt --- src/tools/kata-ctl/src/main.rs | 52 +++++++++++----------------------- 1 file changed, 17 insertions(+), 35 deletions(-) diff --git a/src/tools/kata-ctl/src/main.rs b/src/tools/kata-ctl/src/main.rs index 17875bb0be..484c78a8aa 100644 --- a/src/tools/kata-ctl/src/main.rs +++ b/src/tools/kata-ctl/src/main.rs @@ -7,10 +7,10 @@ use anyhow::{anyhow, Result}; use clap::{crate_name, App, Arg, SubCommand}; use std::process::exit; -mod utils; -mod version; mod arch; mod check; +mod utils; +mod version; const DESCRIPTION_TEXT: &str = r#"DESCRIPTION: kata-ctl description placeholder."#; @@ -48,47 +48,30 @@ fn real_main() -> Result<()> { .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) - ) + .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") + .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("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::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") + .about("gather metrics associated with infrastructure used to run a sandbox"), ) - .subcommand( - SubCommand::with_name("version") - .about("display version details") - - ); + .subcommand(SubCommand::with_name("version").about("display version details")); let args = app.get_matches(); @@ -131,7 +114,6 @@ fn real_main() -> Result<()> { } _ => return Err(anyhow!(format!("invalid sub-command: {:?}", subcmd))), } - } fn main() { From 7c9f9a5a1dae3f9c2c16748b6d5af9fc134abe65 Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Wed, 17 Aug 2022 18:06:29 +0100 Subject: [PATCH 07/17] kata-ctl: Make arch test run at compile time Changed the `panic!()` call to a `compile_error!()` one to ensure it fires at compile time rather than runtime. Signed-off-by: James O. D. Hunt --- src/tools/kata-ctl/src/arch/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/kata-ctl/src/arch/mod.rs b/src/tools/kata-ctl/src/arch/mod.rs index ee6f926f75..c18fb0c094 100644 --- a/src/tools/kata-ctl/src/arch/mod.rs +++ b/src/tools/kata-ctl/src/arch/mod.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 // -use anyhow::{Result}; +use anyhow::Result; #[cfg(target_arch = "aarch64")] pub mod aarch64; @@ -36,7 +36,7 @@ pub fn check(global_args: clap::ArgMatches) -> Result<()> { target_arch = "s390x", target_arch = "x86_64" )))] - panic!("unknown architecture"); + compile_error!("unknown architecture"); result } From 018aa899cb81c8e041454c200ada22ffced63245 Mon Sep 17 00:00:00 2001 From: Chelsea Mafrica Date: Wed, 24 Aug 2022 08:25:22 -0700 Subject: [PATCH 08/17] kata-ctl: Add cpu check Add architecture-specific code for x86_64 and generic calls handling checks for CPU flags and attributes. Signed-off-by: Chelsea Mafrica --- src/tools/kata-ctl/src/arch/x86_64/mod.rs | 38 +++++++- src/tools/kata-ctl/src/check.rs | 103 +++++++++++++++++++++- 2 files changed, 139 insertions(+), 2 deletions(-) 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 2f27dc2a44..5618a44512 100644 --- a/src/tools/kata-ctl/src/arch/x86_64/mod.rs +++ b/src/tools/kata-ctl/src/arch/x86_64/mod.rs @@ -7,11 +7,47 @@ pub use arch_specific::*; mod arch_specific { - use anyhow::Result; + use anyhow::{anyhow, Result}; + use crate::check; + + const PROC_CPUINFO: &str = "/proc/cpuinfo"; + const CPUINFO_DELIMITER: &str = "\nprocessor"; + const CPUINFO_FLAGS_TAG: &str = "flags"; + const CPU_FLAGS_INTEL: &'static [&'static str] = &["lm", "sse4_1", "vmx"]; + const CPU_ATTRIBS_INTEL: &'static [&'static str] = &["GenuineIntel"]; + + // check cpu + fn check_cpu() -> Result<()> { + println!("INFO: check CPU: x86_64"); + + let cpu_info = check::get_single_cpu_info(PROC_CPUINFO, CPUINFO_DELIMITER)?; + + let cpu_flags = check::get_cpu_flags(&cpu_info, CPUINFO_FLAGS_TAG) + .map_err(|e| anyhow!("Error parsing CPU flags, file {:?}, {:?}", PROC_CPUINFO, e))?; + + // perform checks + // TODO: Perform checks based on hypervisor type + // TODO: Add more information to output (see kata-check in go tool); adjust formatting + let missing_cpu_attributes = check::check_cpu_attribs(&cpu_info, CPU_ATTRIBS_INTEL)?; + if missing_cpu_attributes.len() > 0 { + eprintln!("WARNING: Missing CPU attributes {:?}", missing_cpu_attributes); + } + let missing_cpu_flags = check::check_cpu_flags(&cpu_flags, CPU_FLAGS_INTEL)?; + if missing_cpu_flags.len() > 0 { + eprintln!("WARNING: Missing CPU flags {:?}", missing_cpu_flags); + } + + Ok(()) + } + pub fn check(_global_args: clap::ArgMatches) -> Result<()> { println!("INFO: check: x86_64"); + let _cpu_result = check_cpu(); + + // TODO: collect outcome of tests to determine if checks pass or not + Ok(()) } } diff --git a/src/tools/kata-ctl/src/check.rs b/src/tools/kata-ctl/src/check.rs index be39e31e06..9317b903a1 100644 --- a/src/tools/kata-ctl/src/check.rs +++ b/src/tools/kata-ctl/src/check.rs @@ -5,8 +5,109 @@ // Contains checks that are not architecture-specific -use anyhow::{Result}; +use anyhow::{anyhow, Result}; +use std::fs; + +fn get_cpu_info(cpu_info_file: &str) -> Result { + let contents = fs::read_to_string(cpu_info_file)?; + Ok(contents) +} + +// get_single_cpu_info returns the contents of the first cpu from +// the specified cpuinfo file by parsing based on a specified delimiter +pub fn get_single_cpu_info(cpu_info_file: &str, substring: &str) -> Result { + let contents = get_cpu_info(cpu_info_file)?; + + if contents.is_empty() { + return Err(anyhow!("cpu_info string is empty"))?; + } + + let subcontents: Vec<&str> = contents.split(substring).collect(); + let result = subcontents + .first() + .ok_or("error splitting contents of cpuinfo") + .map_err(|e| anyhow!(e))? + .to_string(); + + Ok(result) +} + +// get_cpu_flags returns a string of cpu flags from cpuinfo, passed in +// as a string +pub fn get_cpu_flags(cpu_info: &str, cpu_flags_tag: &str) -> Result { + if cpu_info.is_empty() { + return Err(anyhow!("cpu_info string is empty"))?; + } + + let subcontents: Vec<&str> = cpu_info.split("\n").collect(); + for line in subcontents { + if line.starts_with(cpu_flags_tag) { + let line_data: Vec<&str> = line.split(":").collect(); + let flags = line_data + .last() + .ok_or("error splitting flags in cpuinfo") + .map_err(|e| anyhow!(e))? + .to_string(); + return Ok(flags); + } + } + + Ok("".to_string()) +} + +// get_missing_strings searches for required (strings) in data and returns +// a vector containing the missing strings +fn get_missing_strings(data: &str, required: &'static [&'static str]) -> Result> { + let data_vec: Vec <&str> = data.split_whitespace().collect(); + + let mut missing: Vec = Vec::new(); + + for item in required { + if !data_vec.contains(&item) { + missing.push(item.to_string()); + } + } + + Ok(missing) +} + +pub fn check_cpu_flags(retrieved_flags: &str, required_flags: &'static [&'static str]) -> Result> { + let missing_flags = get_missing_strings(retrieved_flags, required_flags)?; + + Ok(missing_flags) +} + +pub fn check_cpu_attribs(cpu_info: &str, required_attribs: &'static [&'static str]) -> Result> { + let mut cpu_info_processed = cpu_info.replace("\t", ""); + cpu_info_processed = cpu_info_processed.replace("\n", " "); + + let missing_attribs = get_missing_strings(&cpu_info_processed, required_attribs)?; + Ok(missing_attribs) +} pub fn run_network_checks() -> Result<()> { unimplemented!("Tests using network checks not implemented"); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_get_cpu_info_empty_input() { + let expected = "No such file or directory (os error 2)"; + let actual = get_cpu_info("").err().unwrap().to_string(); + assert_eq!(expected, actual); + + let actual = get_single_cpu_info("", "\nprocessor").err().unwrap().to_string(); + assert_eq!(expected, actual); + } + + #[test] + fn test_get_cpu_flags_empty_input() { + let expected = "cpu_info string is empty"; + let actual = get_cpu_flags("", "").err().unwrap().to_string(); + assert_eq!(expected, actual); + } +} + From eb5423cb7fd2b1d0655f5b58427834e5c6a322f7 Mon Sep 17 00:00:00 2001 From: David Esparza Date: Wed, 14 Sep 2022 07:32:21 -0500 Subject: [PATCH 09/17] 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 Commit-edited-by: James O. D. Hunt --- src/tools/kata-ctl/Cargo.toml | 3 +- src/tools/kata-ctl/Makefile | 2 +- src/tools/kata-ctl/src/arch/mod.rs | 4 +- src/tools/kata-ctl/src/arch/x86_64/mod.rs | 2 +- src/tools/kata-ctl/src/args.rs | 90 ++++++++++++ src/tools/kata-ctl/src/check.rs | 7 +- src/tools/kata-ctl/src/main.rs | 130 ++++-------------- src/tools/kata-ctl/src/{utils.rs => ops.rs} | 3 + src/tools/kata-ctl/src/ops/check_ops.rs | 75 ++++++++++ .../kata-ctl/src/{ => ops}/version.rs.in | 10 +- 10 files changed, 216 insertions(+), 110 deletions(-) create mode 100644 src/tools/kata-ctl/src/args.rs rename src/tools/kata-ctl/src/{utils.rs => ops.rs} (69%) create mode 100644 src/tools/kata-ctl/src/ops/check_ops.rs rename src/tools/kata-ctl/src/{ => ops}/version.rs.in (65%) 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)] From 133690434cdc16394a86ec02aee1d25865aebfcd Mon Sep 17 00:00:00 2001 From: David Esparza Date: Wed, 5 Oct 2022 09:09:47 -0500 Subject: [PATCH 10/17] kata-ctl: implement CLI argument --check-version-only This kata-ctl argument returns the latest stable Kata release by hitting github.com. Adds check-version unit tests. Fixes: #11 Signed-off-by: David Esparza --- src/tools/kata-ctl/Cargo.toml | 2 + src/tools/kata-ctl/src/check.rs | 79 +++++++++++++++++++++++- src/tools/kata-ctl/src/ops/version.rs.in | 2 +- 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/tools/kata-ctl/Cargo.toml b/src/tools/kata-ctl/Cargo.toml index eef1f5fbb9..ba73db270a 100644 --- a/src/tools/kata-ctl/Cargo.toml +++ b/src/tools/kata-ctl/Cargo.toml @@ -12,6 +12,8 @@ edition = "2021" [dependencies] anyhow = "1.0.31" clap = { version = "3.2.20", features = ["derive", "cargo"] } +reqwest = { version = "0.11", features = ["json", "blocking"] } +serde_json = "1.0.85" thiserror = "1.0.35" [dev-dependencies] diff --git a/src/tools/kata-ctl/src/check.rs b/src/tools/kata-ctl/src/check.rs index 6a3788d959..7900ed364c 100644 --- a/src/tools/kata-ctl/src/check.rs +++ b/src/tools/kata-ctl/src/check.rs @@ -5,8 +5,14 @@ // Contains checks that are not architecture-specific -use anyhow::{anyhow, Result}; + use std::fs; +use serde_json::Value; +use std::collections::HashMap; +use anyhow::{anyhow, Result}; +use reqwest::header::{CONTENT_TYPE,USER_AGENT}; + +const KATA_GITHUB_URL: &str = "https://api.github.com/repos/kata-containers/kata-containers/releases/latest"; fn get_cpu_info(cpu_info_file: &str) -> Result { let contents = fs::read_to_string(cpu_info_file)?; @@ -89,13 +95,50 @@ pub fn run_network_checks() -> Result<()> { Ok(()) } +fn get_kata_version_by_url(url: &str) -> std::result::Result { + let content = reqwest::blocking::Client::new() + .get(url) + .header(CONTENT_TYPE, "application/json") + .header(USER_AGENT, "kata") + .send()? + .json::>()?; + + let version = content["tag_name"].as_str().unwrap(); + Ok(version.to_string()) +} + +fn handle_reqwest_error(e: reqwest::Error) -> anyhow::Error { + if e.is_connect() { + return anyhow!(e).context("http connection failure: connection refused"); + } + + if e.is_timeout() { + return anyhow!(e).context("http connection failure: connection timeout"); + } + + if e.is_builder() { + return anyhow!(e).context("http connection failure: url malformed"); + } + + if e.is_decode() { + return anyhow!(e).context("http connection failure: unable to decode response body"); + } + + anyhow!(e).context("unknown http connection failure: {:?}") +} + pub fn check_version() -> Result<()> { + let version = get_kata_version_by_url(KATA_GITHUB_URL).map_err(|e| handle_reqwest_error(e))?; + + println!("Version: {}", version); + Ok(()) } #[cfg(test)] mod tests { use super::*; + use semver::Version; #[test] fn test_get_cpu_info_empty_input() { @@ -113,4 +156,38 @@ mod tests { let actual = get_cpu_flags("", "").err().unwrap().to_string(); assert_eq!(expected, actual); } + + #[test] + fn check_version_by_empty_url() { + const TEST_URL: &str = "http:"; + let expected = "builder error: empty host"; + let actual = get_kata_version_by_url(TEST_URL).err().unwrap().to_string(); + assert_eq!(expected, actual); + } + + #[test] + fn check_version_by_garbage_url() { + const TEST_URL: &str = "_localhost_"; + let expected = "builder error: relative URL without a base"; + let actual = get_kata_version_by_url(TEST_URL).err().unwrap().to_string(); + assert_eq!(expected, actual); + } + + #[test] + fn check_version_by_invalid_url() { + const TEST_URL: &str = "http://localhost :80"; + let expected = "builder error: invalid domain character"; + let actual = get_kata_version_by_url(TEST_URL).err().unwrap().to_string(); + assert_eq!(expected, actual); + } + + #[test] + fn check_latest_version() { + let version = get_kata_version_by_url(KATA_GITHUB_URL).unwrap(); + + let v = Version::parse(&version).unwrap(); + assert!(!v.major.to_string().is_empty()); + assert!(!v.minor.to_string().is_empty()); + assert!(!v.patch.to_string().is_empty()); + } } diff --git a/src/tools/kata-ctl/src/ops/version.rs.in b/src/tools/kata-ctl/src/ops/version.rs.in index 16b3c7e7f3..c207b0ea3e 100644 --- a/src/tools/kata-ctl/src/ops/version.rs.in +++ b/src/tools/kata-ctl/src/ops/version.rs.in @@ -28,7 +28,7 @@ mod tests { #[test] fn test_get() { - let version = get(); + let version = get().unwrap(); let v = Version::parse(&version).unwrap(); assert!(!v.major.to_string().is_empty()); From c23584994a8dc2f594d60e775f4d8ee4e45b08b0 Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Mon, 10 Oct 2022 09:46:36 +0100 Subject: [PATCH 11/17] kata-ctl: clippy: Resolve warnings and reformat Resolved a couple of clippy warnings and applied standard `rustfmt`. Signed-off-by: James O. D. Hunt --- src/tools/kata-ctl/src/arch/x86_64/mod.rs | 8 ++-- src/tools/kata-ctl/src/args.rs | 14 +++---- src/tools/kata-ctl/src/check.rs | 45 ++++++++++++++--------- src/tools/kata-ctl/src/main.rs | 20 +++------- src/tools/kata-ctl/src/ops/check_ops.rs | 11 ++---- 5 files changed, 45 insertions(+), 53 deletions(-) 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 9c761d1187..379f8b6e5a 100644 --- a/src/tools/kata-ctl/src/arch/x86_64/mod.rs +++ b/src/tools/kata-ctl/src/arch/x86_64/mod.rs @@ -7,8 +7,8 @@ pub use arch_specific::*; mod arch_specific { - use anyhow::{anyhow, Result}; use crate::check; + use anyhow::{anyhow, Result}; const PROC_CPUINFO: &str = "/proc/cpuinfo"; const CPUINFO_DELIMITER: &str = "\nprocessor"; @@ -30,7 +30,10 @@ mod arch_specific { // TODO: Add more information to output (see kata-check in go tool); adjust formatting let missing_cpu_attributes = check::check_cpu_attribs(&cpu_info, CPU_ATTRIBS_INTEL)?; if missing_cpu_attributes.len() > 0 { - eprintln!("WARNING: Missing CPU attributes {:?}", missing_cpu_attributes); + eprintln!( + "WARNING: Missing CPU attributes {:?}", + missing_cpu_attributes + ); } let missing_cpu_flags = check::check_cpu_flags(&cpu_flags, CPU_FLAGS_INTEL)?; if missing_cpu_flags.len() > 0 { @@ -40,7 +43,6 @@ mod arch_specific { Ok(()) } - pub fn check() -> Result<()> { println!("INFO: check: x86_64"); diff --git a/src/tools/kata-ctl/src/args.rs b/src/tools/kata-ctl/src/args.rs index 4c8bf51fcd..449bcb5e9d 100644 --- a/src/tools/kata-ctl/src/args.rs +++ b/src/tools/kata-ctl/src/args.rs @@ -3,16 +3,12 @@ // SPDX-License-Identifier: Apache-2.0 // -use clap::{ - Args, - Parser, - Subcommand -}; +use clap::{Args, Parser, Subcommand}; use thiserror::Error; #[derive(Parser, Debug)] -#[clap(name = "kata-ctl", author, about="Kata Containers control tool")] +#[clap(name = "kata-ctl", author, about = "Kata Containers control tool")] pub struct KataCtlCli { #[clap(subcommand)] pub command: Commands, @@ -45,7 +41,7 @@ pub enum Commands { Version, } -#[derive(Debug,Args,Error)] +#[derive(Debug, Args, Error)] #[error("Argument is not valid")] pub struct CheckArgument { #[clap(subcommand)] @@ -64,7 +60,7 @@ pub enum CheckSubCommand { CheckVersionOnly, } -#[derive(Debug,Args)] +#[derive(Debug, Args)] pub struct MetricsCommand { #[clap(subcommand)] pub metrics_cmd: MetricsSubCommand, @@ -73,7 +69,7 @@ pub struct MetricsCommand { #[derive(Debug, Subcommand)] pub enum MetricsSubCommand { /// Arguments for metrics - MetricsArgs, + MetricsArgs, } // #[derive(Parser, Debug)] diff --git a/src/tools/kata-ctl/src/check.rs b/src/tools/kata-ctl/src/check.rs index 7900ed364c..4e96eee5b9 100644 --- a/src/tools/kata-ctl/src/check.rs +++ b/src/tools/kata-ctl/src/check.rs @@ -5,14 +5,14 @@ // Contains checks that are not architecture-specific - -use std::fs; +use anyhow::{anyhow, Result}; +use reqwest::header::{CONTENT_TYPE, USER_AGENT}; use serde_json::Value; use std::collections::HashMap; -use anyhow::{anyhow, Result}; -use reqwest::header::{CONTENT_TYPE,USER_AGENT}; +use std::fs; -const KATA_GITHUB_URL: &str = "https://api.github.com/repos/kata-containers/kata-containers/releases/latest"; +const KATA_GITHUB_URL: &str = + "https://api.github.com/repos/kata-containers/kata-containers/releases/latest"; fn get_cpu_info(cpu_info_file: &str) -> Result { let contents = fs::read_to_string(cpu_info_file)?; @@ -22,7 +22,7 @@ fn get_cpu_info(cpu_info_file: &str) -> Result { // get_single_cpu_info returns the contents of the first cpu from // the specified cpuinfo file by parsing based on a specified delimiter pub fn get_single_cpu_info(cpu_info_file: &str, substring: &str) -> Result { - let contents = get_cpu_info(cpu_info_file)?; + let contents = get_cpu_info(cpu_info_file)?; if contents.is_empty() { return Err(anyhow!("cpu_info string is empty"))?; @@ -64,9 +64,9 @@ pub fn get_cpu_flags(cpu_info: &str, cpu_flags_tag: &str) -> Result { // get_missing_strings searches for required (strings) in data and returns // a vector containing the missing strings fn get_missing_strings(data: &str, required: &'static [&'static str]) -> Result> { - let data_vec: Vec <&str> = data.split_whitespace().collect(); + let data_vec: Vec<&str> = data.split_whitespace().collect(); - let mut missing: Vec = Vec::new(); + let mut missing: Vec = Vec::new(); for item in required { if !data_vec.contains(&item) { @@ -77,13 +77,19 @@ fn get_missing_strings(data: &str, required: &'static [&'static str]) -> Result< Ok(missing) } -pub fn check_cpu_flags(retrieved_flags: &str, required_flags: &'static [&'static str]) -> Result> { +pub fn check_cpu_flags( + retrieved_flags: &str, + required_flags: &'static [&'static str], +) -> Result> { let missing_flags = get_missing_strings(retrieved_flags, required_flags)?; Ok(missing_flags) } -pub fn check_cpu_attribs(cpu_info: &str, required_attribs: &'static [&'static str]) -> Result> { +pub fn check_cpu_attribs( + cpu_info: &str, + required_attribs: &'static [&'static str], +) -> Result> { let mut cpu_info_processed = cpu_info.replace("\t", ""); cpu_info_processed = cpu_info_processed.replace("\n", " "); @@ -146,7 +152,10 @@ mod tests { let actual = get_cpu_info("").err().unwrap().to_string(); assert_eq!(expected, actual); - let actual = get_single_cpu_info("", "\nprocessor").err().unwrap().to_string(); + let actual = get_single_cpu_info("", "\nprocessor") + .err() + .unwrap() + .to_string(); assert_eq!(expected, actual); } @@ -162,7 +171,7 @@ mod tests { const TEST_URL: &str = "http:"; let expected = "builder error: empty host"; let actual = get_kata_version_by_url(TEST_URL).err().unwrap().to_string(); - assert_eq!(expected, actual); + assert_eq!(expected, actual); } #[test] @@ -170,7 +179,7 @@ mod tests { const TEST_URL: &str = "_localhost_"; let expected = "builder error: relative URL without a base"; let actual = get_kata_version_by_url(TEST_URL).err().unwrap().to_string(); - assert_eq!(expected, actual); + assert_eq!(expected, actual); } #[test] @@ -178,16 +187,16 @@ mod tests { const TEST_URL: &str = "http://localhost :80"; let expected = "builder error: invalid domain character"; let actual = get_kata_version_by_url(TEST_URL).err().unwrap().to_string(); - assert_eq!(expected, actual); + assert_eq!(expected, actual); } #[test] fn check_latest_version() { let version = get_kata_version_by_url(KATA_GITHUB_URL).unwrap(); - let v = Version::parse(&version).unwrap(); - assert!(!v.major.to_string().is_empty()); - assert!(!v.minor.to_string().is_empty()); - assert!(!v.patch.to_string().is_empty()); + let v = Version::parse(&version).unwrap(); + assert!(!v.major.to_string().is_empty()); + assert!(!v.minor.to_string().is_empty()); + assert!(!v.patch.to_string().is_empty()); } } diff --git a/src/tools/kata-ctl/src/main.rs b/src/tools/kata-ctl/src/main.rs index 5fb21b049c..30e4b5eb7a 100644 --- a/src/tools/kata-ctl/src/main.rs +++ b/src/tools/kata-ctl/src/main.rs @@ -3,33 +3,23 @@ // SPDX-License-Identifier: Apache-2.0 // -mod args; mod arch; +mod args; mod check; mod ops; -use clap::Parser; use anyhow::Result; +use clap::Parser; use std::process::exit; -use args::{ - KataCtlCli, - Commands -}; +use args::{Commands, KataCtlCli}; use ops::check_ops::{ - handle_check, - handle_check_volume, - handle_env, - handle_exec, - handle_factory, - handle_iptables, - handle_metrics, - handle_version + handle_check, handle_check_volume, handle_env, handle_exec, handle_factory, handle_iptables, + handle_metrics, handle_version, }; fn real_main() -> Result<()> { - let args = KataCtlCli::parse(); match args.command { diff --git a/src/tools/kata-ctl/src/ops/check_ops.rs b/src/tools/kata-ctl/src/ops/check_ops.rs index a35c2c15d5..b97cb6b05d 100644 --- a/src/tools/kata-ctl/src/ops/check_ops.rs +++ b/src/tools/kata-ctl/src/ops/check_ops.rs @@ -7,12 +7,7 @@ use crate::arch; use crate::check; use crate::ops::version; -use crate::args::{ - CheckArgument, - CheckSubCommand, - IptablesCommand, - MetricsCommand -}; +use crate::args::{CheckArgument, CheckSubCommand, IptablesCommand, MetricsCommand}; use anyhow::Result; @@ -60,11 +55,11 @@ pub fn handle_factory() -> Result<()> { Ok(()) } -pub fn handle_iptables(args: IptablesCommand) -> Result<()> { +pub fn handle_iptables(_args: IptablesCommand) -> Result<()> { Ok(()) } -pub fn handle_metrics(args: MetricsCommand) -> Result<()> { +pub fn handle_metrics(_args: MetricsCommand) -> Result<()> { Ok(()) } From 15c343cbf2f441daf9da7acda09c361566610828 Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Mon, 10 Oct 2022 10:26:25 +0100 Subject: [PATCH 12/17] kata-ctl: Don't rely on system ssl libs Build using the rust TLS implementation rather than the system ones. This resolves the `reqwest` crate build failure: it doesn't appear to build against the native libssl libraries due to Kata defaulting to using the musl libc. Fixes: #5387. Signed-off-by: James O. D. Hunt --- src/tools/kata-ctl/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/kata-ctl/Cargo.toml b/src/tools/kata-ctl/Cargo.toml index ba73db270a..bf42c93584 100644 --- a/src/tools/kata-ctl/Cargo.toml +++ b/src/tools/kata-ctl/Cargo.toml @@ -12,7 +12,7 @@ edition = "2021" [dependencies] anyhow = "1.0.31" clap = { version = "3.2.20", features = ["derive", "cargo"] } -reqwest = { version = "0.11", features = ["json", "blocking"] } +reqwest = { version = "0.11", default-features = false, features = ["json", "blocking", "rustls-tls"] } serde_json = "1.0.85" thiserror = "1.0.35" From 781e604c39d85ffad476b03ef5ca2dd8f6e48bd3 Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Mon, 10 Oct 2022 16:49:21 +0100 Subject: [PATCH 13/17] docs: Reference kata-ctl README Add a link to the `kata-ctl` tool's README. Signed-off-by: James O. D. Hunt --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2b0759a2c0..d2b27b97c4 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,7 @@ The table below lists the remaining parts of the project: | [kernel](https://www.kernel.org) | kernel | Linux kernel used by the hypervisor to boot the guest image. Patches are stored [here](tools/packaging/kernel). | | [osbuilder](tools/osbuilder) | infrastructure | Tool to create "mini O/S" rootfs and initrd images and kernel for the hypervisor. | | [`agent-ctl`](src/tools/agent-ctl) | utility | Tool that provides low-level access for testing the agent. | +| [`kata-ctl`](src/tools/kata-ctl) | utility | Tool that provides advanced commands and debug facilities. | | [`trace-forwarder`](src/tools/trace-forwarder) | utility | Agent tracing helper. | | [`runk`](src/tools/runk) | utility | Standard OCI container runtime based on the agent. | | [`ci`](https://github.com/kata-containers/ci) | CI | Continuous Integration configuration files and scripts. | From f7010b80614d0858e21bd661f95a4847ee00c77a Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Mon, 10 Oct 2022 10:09:56 +0100 Subject: [PATCH 14/17] kata-ctl: docs: Write basic documentation Provide a basic document explaining a little about the `kata-ctl` command. Fixes: #5351. Signed-off-by: James O. D. Hunt --- src/tools/kata-ctl/README.md | 42 ++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/tools/kata-ctl/README.md b/src/tools/kata-ctl/README.md index 1e441d58b2..bf908f60d0 100644 --- a/src/tools/kata-ctl/README.md +++ b/src/tools/kata-ctl/README.md @@ -2,14 +2,48 @@ ## Overview +The `kata-ctl` tool is a rust rewrite of the +[`kata-runtime`](../../runtime/cmd/kata-runtime) +[utility program](../../../docs/design/architecture/README.md#utility-program). + +The program provides a number of utility commands for: + +- Using advanced Kata Containers features. +- Problem determination and debugging. + ## Audience and environment -## History +Users and administrators. -## Full details +## Build the tool -## Code summary +```bash +$ make +``` + +## Install the tool + +```bash +$ make install +``` ## Run the tool -### Prerequisites +```bash +$ kata-ctl ... +``` + +For example, to determine if your system is capable of running Kata +Containers, run: + +```bash +$ kata-ctl check all +``` + +### Full details + +For a usage statement, run: + +```bash +$ kata-ctl --help +``` From 2b345ba29d9ec6d3783f9573a430c66059c31c52 Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Tue, 11 Oct 2022 10:03:55 +0100 Subject: [PATCH 15/17] build: Add kata-ctl to tools list Update the top-level Makefile to build the `kata-ctl` tool by default. Fixes: #4499, #5334. Signed-off-by: James O. D. Hunt --- Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 4d2be6b4d8..e30cf1d980 100644 --- a/Makefile +++ b/Makefile @@ -15,9 +15,10 @@ COMPONENTS += runtime-rs TOOLS = TOOLS += agent-ctl -TOOLS += trace-forwarder -TOOLS += runk +TOOLS += kata-ctl TOOLS += log-parser +TOOLS += runk +TOOLS += trace-forwarder STANDARD_TARGETS = build check clean install test vendor From fb63274747daf1b23544347427d1554ee6ba2f59 Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Wed, 12 Oct 2022 09:58:44 +0100 Subject: [PATCH 16/17] kata-ctl: rustfmt + clippy fixes Make this file conform to the standard rust layout conventions and simplify the code as recommended by `clippy`. Signed-off-by: James O. D. Hunt --- src/tools/kata-ctl/src/arch/x86_64/mod.rs | 8 ++++---- src/tools/kata-ctl/src/check.rs | 14 ++++++-------- src/tools/kata-ctl/src/ops/version.rs.in | 22 +++++++++++----------- 3 files changed, 21 insertions(+), 23 deletions(-) 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 379f8b6e5a..95817981e1 100644 --- a/src/tools/kata-ctl/src/arch/x86_64/mod.rs +++ b/src/tools/kata-ctl/src/arch/x86_64/mod.rs @@ -13,8 +13,8 @@ mod arch_specific { const PROC_CPUINFO: &str = "/proc/cpuinfo"; const CPUINFO_DELIMITER: &str = "\nprocessor"; const CPUINFO_FLAGS_TAG: &str = "flags"; - const CPU_FLAGS_INTEL: &'static [&'static str] = &["lm", "sse4_1", "vmx"]; - const CPU_ATTRIBS_INTEL: &'static [&'static str] = &["GenuineIntel"]; + const CPU_FLAGS_INTEL: &[&str] = &["lm", "sse4_1", "vmx"]; + const CPU_ATTRIBS_INTEL: &[&str] = &["GenuineIntel"]; // check cpu fn check_cpu() -> Result<()> { @@ -29,14 +29,14 @@ mod arch_specific { // TODO: Perform checks based on hypervisor type // TODO: Add more information to output (see kata-check in go tool); adjust formatting let missing_cpu_attributes = check::check_cpu_attribs(&cpu_info, CPU_ATTRIBS_INTEL)?; - if missing_cpu_attributes.len() > 0 { + if !missing_cpu_attributes.is_empty() { eprintln!( "WARNING: Missing CPU attributes {:?}", missing_cpu_attributes ); } let missing_cpu_flags = check::check_cpu_flags(&cpu_flags, CPU_FLAGS_INTEL)?; - if missing_cpu_flags.len() > 0 { + if !missing_cpu_flags.is_empty() { eprintln!("WARNING: Missing CPU flags {:?}", missing_cpu_flags); } diff --git a/src/tools/kata-ctl/src/check.rs b/src/tools/kata-ctl/src/check.rs index 4e96eee5b9..28febb307c 100644 --- a/src/tools/kata-ctl/src/check.rs +++ b/src/tools/kata-ctl/src/check.rs @@ -45,10 +45,10 @@ pub fn get_cpu_flags(cpu_info: &str, cpu_flags_tag: &str) -> Result { return Err(anyhow!("cpu_info string is empty"))?; } - let subcontents: Vec<&str> = cpu_info.split("\n").collect(); + let subcontents: Vec<&str> = cpu_info.split('\n').collect(); for line in subcontents { if line.starts_with(cpu_flags_tag) { - let line_data: Vec<&str> = line.split(":").collect(); + let line_data: Vec<&str> = line.split(':').collect(); let flags = line_data .last() .ok_or("error splitting flags in cpuinfo") @@ -64,12 +64,10 @@ pub fn get_cpu_flags(cpu_info: &str, cpu_flags_tag: &str) -> Result { // get_missing_strings searches for required (strings) in data and returns // a vector containing the missing strings fn get_missing_strings(data: &str, required: &'static [&'static str]) -> Result> { - let data_vec: Vec<&str> = data.split_whitespace().collect(); - let mut missing: Vec = Vec::new(); for item in required { - if !data_vec.contains(&item) { + if !data.split_whitespace().any(|x| x == *item) { missing.push(item.to_string()); } } @@ -90,8 +88,8 @@ pub fn check_cpu_attribs( cpu_info: &str, required_attribs: &'static [&'static str], ) -> Result> { - let mut cpu_info_processed = cpu_info.replace("\t", ""); - cpu_info_processed = cpu_info_processed.replace("\n", " "); + let mut cpu_info_processed = cpu_info.replace('\t', ""); + cpu_info_processed = cpu_info_processed.replace('\n', " "); let missing_attribs = get_missing_strings(&cpu_info_processed, required_attribs)?; Ok(missing_attribs) @@ -134,7 +132,7 @@ fn handle_reqwest_error(e: reqwest::Error) -> anyhow::Error { } pub fn check_version() -> Result<()> { - let version = get_kata_version_by_url(KATA_GITHUB_URL).map_err(|e| handle_reqwest_error(e))?; + let version = get_kata_version_by_url(KATA_GITHUB_URL).map_err(handle_reqwest_error)?; println!("Version: {}", version); diff --git a/src/tools/kata-ctl/src/ops/version.rs.in b/src/tools/kata-ctl/src/ops/version.rs.in index c207b0ea3e..052eccf168 100644 --- a/src/tools/kata-ctl/src/ops/version.rs.in +++ b/src/tools/kata-ctl/src/ops/version.rs.in @@ -13,27 +13,27 @@ const KATA_CTL_VERSION: &str = "@KATA_CTL_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); + Err("Unable to retrieve kata Version. Check that Kata is properly installed".to_string()) + } else { + let version = format!("{}-{}", KATA_CTL_VERSION, crate_version!()); + + Ok(version) } } #[cfg(test)] mod tests { use super::*; - use semver::{Version}; + use semver::Version; #[test] fn test_get() { let version = get().unwrap(); - let v = Version::parse(&version).unwrap(); + let v = Version::parse(&version).unwrap(); - assert!(!v.major.to_string().is_empty()); - assert!(!v.minor.to_string().is_empty()); - assert!(!v.patch.to_string().is_empty()); - assert!(!v.pre.to_string().is_empty()); + assert!(!v.major.to_string().is_empty()); + assert!(!v.minor.to_string().is_empty()); + assert!(!v.patch.to_string().is_empty()); + assert!(!v.pre.to_string().is_empty()); } } From 00a42f69c09a43248339f3aa961a46bce0e45ed6 Mon Sep 17 00:00:00 2001 From: "James O. D. Hunt" Date: Wed, 12 Oct 2022 09:59:49 +0100 Subject: [PATCH 17/17] kata-ctl: cargo: 2021 -> 2018 Revert to the 2018 edition of rust for consistency with other rust components. Signed-off-by: James O. D. Hunt --- src/tools/kata-ctl/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/kata-ctl/Cargo.toml b/src/tools/kata-ctl/Cargo.toml index bf42c93584..094613c343 100644 --- a/src/tools/kata-ctl/Cargo.toml +++ b/src/tools/kata-ctl/Cargo.toml @@ -7,7 +7,7 @@ name = "kata-ctl" version = "0.0.1" authors = ["The Kata Containers community "] -edition = "2021" +edition = "2018" [dependencies] anyhow = "1.0.31"