agent-ctl: Replace removed clap functions

When moving from clap v2 to v4 a bunch of
functions have been removed, so update the code
to handle these replacements

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
This commit is contained in:
stevenhorsman 2025-06-11 14:47:39 +01:00
parent e11fc3334e
commit e204847df5
3 changed files with 62 additions and 43 deletions

View File

@ -721,6 +721,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive",
] ]
[[package]] [[package]]
@ -735,6 +736,18 @@ dependencies = [
"strsim", "strsim",
] ]
[[package]]
name = "clap_derive"
version = "4.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.87",
]
[[package]] [[package]]
name = "clap_lex" name = "clap_lex"
version = "0.7.5" version = "0.7.5"
@ -2292,7 +2305,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"windows-targets 0.52.6", "windows-targets 0.48.0",
] ]
[[package]] [[package]]
@ -5122,7 +5135,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.48.0",
] ]
[[package]] [[package]]

View File

@ -15,7 +15,7 @@ protocols = { path = "../../libs/protocols", features = ["with-serde"] }
rustjail = { path = "../../agent/rustjail" } rustjail = { path = "../../agent/rustjail" }
oci-spec = { version = "0.6.8", features = ["runtime"] } oci-spec = { version = "0.6.8", features = ["runtime"] }
clap = "4.5.40" clap = { version = "4.5.40", features = ["derive", "cargo"] }
lazy_static = "1.4.0" lazy_static = "1.4.0"
anyhow = "1.0.31" anyhow = "1.0.31"
hex = "0.4.2" hex = "0.4.2"
@ -43,7 +43,11 @@ serde = { version = "1.0.131", features = ["derive"] }
serde_json = "1.0.73" serde_json = "1.0.73"
# Image pull/unpack # Image pull/unpack
image-rs = { git = "https://github.com/confidential-containers/guest-components", rev = "v0.10.0", features = ["snapshot-overlayfs", "oci-client-rustls", "signature-cosign-rustls"] } image-rs = { git = "https://github.com/confidential-containers/guest-components", rev = "v0.10.0", features = [
"snapshot-overlayfs",
"oci-client-rustls",
"signature-cosign-rustls",
] }
safe-path = { path = "../../libs/safe-path" } safe-path = { path = "../../libs/safe-path" }

View File

@ -1,14 +1,14 @@
// Copyright (c) 2020 Intel Corporation // Copyright (c) 2020 Intel Corporation
// Copyright (c) 2025 IBM Corporation
// //
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// //
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
use crate::types::Config; use crate::types::Config;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use clap::{crate_name, crate_version, App, Arg, SubCommand}; use clap::{crate_name, crate_version, Arg, Command};
use std::io; use std::io;
use std::process::exit; use std::process::exit;
@ -137,11 +137,12 @@ fn connect(name: &str, global_args: clap::ArgMatches) -> Result<()> {
.subcommand_matches("connect") .subcommand_matches("connect")
.ok_or_else(|| anyhow!("BUG: missing sub-command arguments"))?; .ok_or_else(|| anyhow!("BUG: missing sub-command arguments"))?;
let interactive = args.is_present("interactive"); let interactive = args.contains_id("interactive");
let ignore_errors = args.is_present("ignore-errors"); let ignore_errors = args.contains_id("ignore-errors");
let server_address = args let server_address = args
.value_of("server-address") .get_one::<String>("server-address")
.map(|s| s.as_str())
.ok_or_else(|| anyhow!("need server adddress"))? .ok_or_else(|| anyhow!("need server adddress"))?
.to_string(); .to_string();
@ -149,13 +150,15 @@ fn connect(name: &str, global_args: clap::ArgMatches) -> Result<()> {
if !interactive { if !interactive {
commands = args commands = args
.values_of("cmd") .get_many::<String>("cmd")
.ok_or_else(|| anyhow!("need commands to send to the server"))? .ok_or_else(|| anyhow!("need commands to send to the server"))?
.map(|s| s.as_str())
.collect(); .collect();
} }
let log_level_name = global_args let log_level_name = global_args
.value_of("log-level") .get_one::<String>("log-level")
.map(|s| s.as_str())
.ok_or_else(|| anyhow!("cannot get log level"))?; .ok_or_else(|| anyhow!("cannot get log level"))?;
let log_level = logging::level_name_to_slog_level(log_level_name).map_err(|e| anyhow!(e))?; let log_level = logging::level_name_to_slog_level(log_level_name).map_err(|e| anyhow!(e))?;
@ -163,21 +166,26 @@ fn connect(name: &str, global_args: clap::ArgMatches) -> Result<()> {
let writer = io::stdout(); let writer = io::stdout();
let (logger, _guard) = logging::create_logger(name, crate_name!(), log_level, writer); let (logger, _guard) = logging::create_logger(name, crate_name!(), log_level, writer);
let timeout_nano: i64 = match args.value_of("timeout") { let timeout_nano: i64 = match args.get_one::<String>("timeout").map(|s| s.as_str()) {
Some(t) => utils::human_time_to_ns(t)?, Some(t) => utils::human_time_to_ns(t)?,
None => 0, None => 0,
}; };
let hybrid_vsock_port = args let hybrid_vsock_port = args
.value_of("hybrid-vsock-port") .get_one::<String>("hybrid-vsock-port")
.map(|s| s.as_str())
.ok_or_else(|| anyhow!("Need Hybrid VSOCK port number"))? .ok_or_else(|| anyhow!("Need Hybrid VSOCK port number"))?
.parse::<u64>() .parse::<u64>()
.map_err(|e| anyhow!("VSOCK port number must be an integer: {:?}", e))?; .map_err(|e| anyhow!("VSOCK port number must be an integer: {:?}", e))?;
let bundle_dir = args.value_of("bundle-dir").unwrap_or("").to_string(); let bundle_dir = args
.get_one::<String>("bundle-dir")
.map(|s| s.as_str())
.unwrap_or("")
.to_string();
let hybrid_vsock = args.is_present("hybrid-vsock"); let hybrid_vsock = args.contains_id("hybrid-vsock");
let no_auto_values = args.is_present("no-auto-values"); let no_auto_values = args.contains_id("no-auto-values");
let cfg = Config { let cfg = Config {
server_address, server_address,
@ -203,95 +211,89 @@ fn real_main() -> Result<()> {
DEFAULT_KATA_AGENT_API_VSOCK_PORT DEFAULT_KATA_AGENT_API_VSOCK_PORT
); );
let app = App::new(name) let app = Command::new(name)
.version(crate_version!()) .version(crate_version!())
.about(ABOUT_TEXT) .about(ABOUT_TEXT)
.long_about(DESCRIPTION_TEXT) .long_about(DESCRIPTION_TEXT)
.after_help(WARNING_TEXT) .after_help(WARNING_TEXT)
.arg( .arg(
Arg::with_name("log-level") Arg::new("log-level")
.long("log-level") .long("log-level")
.short("l") .short('l')
.help("specific log level") .help("specific log level")
.default_value(logging::slog_level_to_level_name(DEFAULT_LOG_LEVEL).map_err(|e| anyhow!(e))?) .default_value(logging::slog_level_to_level_name(DEFAULT_LOG_LEVEL).map_err(|e| anyhow!(e))?)
.possible_values(&logging::get_log_levels()) .value_parser(logging::get_log_levels())
.takes_value(true)
.required(false), .required(false),
) )
.subcommand( .subcommand(
SubCommand::with_name("connect") Command::new("connect")
.about("Connect to agent") .about("Connect to agent")
.after_help(WARNING_TEXT) .after_help(WARNING_TEXT)
.arg( .arg(
Arg::with_name("bundle-dir") Arg::new("bundle-dir")
.long("bundle-dir") .long("bundle-dir")
.help("OCI bundle directory") .help("OCI bundle directory")
.takes_value(true)
.value_name("directory"), .value_name("directory"),
) )
.arg( .arg(
Arg::with_name("cmd") Arg::new("cmd")
.long("cmd") .long("cmd")
.short("c") .short('c')
.takes_value(true) .num_args(0..)
.multiple(true)
.help("API command (with optional arguments) to send to the server"), .help("API command (with optional arguments) to send to the server"),
) )
.arg( .arg(
Arg::with_name("ignore-errors") Arg::new("ignore-errors")
.long("ignore-errors") .long("ignore-errors")
.help("Don't exit on first error"), .help("Don't exit on first error"),
) )
.arg( .arg(
Arg::with_name("hybrid-vsock") Arg::new("hybrid-vsock")
.long("hybrid-vsock") .long("hybrid-vsock")
.help("Treat a unix:// server address as a Hybrid VSOCK one"), .help("Treat a unix:// server address as a Hybrid VSOCK one"),
) )
.arg( .arg(
Arg::with_name("hybrid-vsock-port") Arg::new("hybrid-vsock-port")
.long("hybrid-vsock-port") .long("hybrid-vsock-port")
.help(&hybrid_vsock_port_help) .help(&hybrid_vsock_port_help)
.default_value(DEFAULT_KATA_AGENT_API_VSOCK_PORT) .default_value(DEFAULT_KATA_AGENT_API_VSOCK_PORT)
.takes_value(true)
.value_name("PORT") .value_name("PORT")
) )
.arg( .arg(
Arg::with_name("interactive") Arg::new("interactive")
.short("i") .short('i')
.long("interactive") .long("interactive")
.help("Allow interactive client"), .help("Allow interactive client"),
) )
.arg( .arg(
Arg::with_name("no-auto-values") Arg::new("no-auto-values")
.short("n") .short('n')
.long("no-auto-values") .long("no-auto-values")
.help("Disable automatic generation of values for sandbox ID, container ID, etc"), .help("Disable automatic generation of values for sandbox ID, container ID, etc"),
) )
.arg( .arg(
Arg::with_name("server-address") Arg::new("server-address")
.long("server-address") .long("server-address")
.help("server URI (vsock:// or unix://)") .help("server URI (vsock:// or unix://)")
.takes_value(true)
.value_name("URI"), .value_name("URI"),
) )
.arg( .arg(
Arg::with_name("timeout") Arg::new("timeout")
.long("timeout") .long("timeout")
.help("timeout value as nanoseconds or using human-readable suffixes (0 [forever], 99ns, 30us, 2ms, 5s, 7m, etc)") .help("timeout value as nanoseconds or using human-readable suffixes (0 [forever], 99ns, 30us, 2ms, 5s, 7m, etc)")
.takes_value(true)
.value_name("human-time"), .value_name("human-time"),
) )
) )
.subcommand( .subcommand(
SubCommand::with_name("generate-cid") Command::new("generate-cid")
.about("Create a random container ID") .about("Create a random container ID")
) )
.subcommand( .subcommand(
SubCommand::with_name("generate-sid") Command::new("generate-sid")
.about("Create a random sandbox ID") .about("Create a random sandbox ID")
) )
.subcommand( .subcommand(
SubCommand::with_name("examples") Command::new("examples")
.about("Show usage examples") .about("Show usage examples")
); );