ch-remote: switch to argh

Since argh does not support `--option=value`, we need to change the
integration test code to become `--option value`.

Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
Wei Liu 2023-01-13 00:50:53 +00:00 committed by Rob Bradford
parent 1ba995d952
commit d5558aea2a
4 changed files with 395 additions and 375 deletions

1
Cargo.lock generated
View File

@ -177,6 +177,7 @@ version = "29.0.0"
dependencies = [
"anyhow",
"api_client",
"argh",
"clap",
"dirs",
"epoll",

View File

@ -26,6 +26,7 @@ strip = true
[dependencies]
anyhow = "1.0.68"
api_client = { path = "api_client" }
argh = "0.1.9"
clap = { version = "4.0.32", features = ["wrap_help","cargo","string"] }
epoll = "4.3.1"
event_monitor = { path = "event_monitor" }

View File

@ -7,7 +7,7 @@ use api_client::simple_api_command;
use api_client::simple_api_command_with_fds;
use api_client::simple_api_full_command;
use api_client::Error as ApiClientError;
use clap::{Arg, ArgAction, ArgMatches, Command};
use argh::FromArgs;
use option_parser::{ByteSized, ByteSizedParseError};
use std::fmt;
use std::io::Read;
@ -18,7 +18,6 @@ use std::process;
enum Error {
Connect(std::io::Error),
ApiClient(ApiClientError),
InvalidCpuCount(std::num::ParseIntError),
InvalidMemorySize(ByteSizedParseError),
InvalidBalloonSize(ByteSizedParseError),
AddDeviceConfig(vmm::config::Error),
@ -40,7 +39,6 @@ impl fmt::Display for Error {
match self {
ApiClient(e) => e.fmt(f),
Connect(e) => write!(f, "Error opening HTTP socket: {e}"),
InvalidCpuCount(e) => write!(f, "Error parsing CPU count: {e}"),
InvalidMemorySize(e) => write!(f, "Error parsing memory size: {e:?}"),
InvalidBalloonSize(e) => write!(f, "Error parsing balloon size: {e:?}"),
AddDeviceConfig(e) => write!(f, "Error parsing device syntax: {e}"),
@ -60,16 +58,10 @@ impl fmt::Display for Error {
fn resize_api_command(
socket: &mut UnixStream,
cpus: Option<&str>,
memory: Option<&str>,
balloon: Option<&str>,
desired_vcpus: Option<u8>,
memory: &Option<String>,
balloon: &Option<String>,
) -> Result<(), Error> {
let desired_vcpus: Option<u8> = if let Some(cpus) = cpus {
Some(cpus.parse().map_err(Error::InvalidCpuCount)?)
} else {
None
};
let desired_ram: Option<u64> = if let Some(memory) = memory {
Some(
memory
@ -325,366 +317,387 @@ fn create_api_command(socket: &mut UnixStream, path: &str) -> Result<(), Error>
simple_api_command(socket, "PUT", "create", Some(&data)).map_err(Error::ApiClient)
}
fn do_command(matches: &ArgMatches) -> Result<(), Error> {
let mut socket = UnixStream::connect(matches.get_one::<String>("api-socket").unwrap())
.map_err(Error::Connect)?;
fn do_command(toplevel: &TopLevel) -> Result<(), Error> {
let mut socket =
UnixStream::connect(toplevel.api_socket.as_deref().unwrap()).map_err(Error::Connect)?;
match matches.subcommand_name() {
Some("info") => {
match toplevel.command {
SubCommandEnum::Boot(_) => {
simple_api_command(&mut socket, "PUT", "boot", None).map_err(Error::ApiClient)
}
SubCommandEnum::Delete(_) => {
simple_api_command(&mut socket, "PUT", "delete", None).map_err(Error::ApiClient)
}
SubCommandEnum::ShutdownVmm(_) => {
simple_api_command(&mut socket, "PUT", "shutdown-vmm", None).map_err(Error::ApiClient)
}
SubCommandEnum::Resume(_) => {
simple_api_command(&mut socket, "PUT", "resume", None).map_err(Error::ApiClient)
}
SubCommandEnum::PowerButton(_) => {
simple_api_command(&mut socket, "PUT", "power-button", None).map_err(Error::ApiClient)
}
SubCommandEnum::Reboot(_) => {
simple_api_command(&mut socket, "PUT", "reboot", None).map_err(Error::ApiClient)
}
SubCommandEnum::Pause(_) => {
simple_api_command(&mut socket, "PUT", "pause", None).map_err(Error::ApiClient)
}
SubCommandEnum::Info(_) => {
simple_api_command(&mut socket, "GET", "info", None).map_err(Error::ApiClient)
}
Some("counters") => {
SubCommandEnum::Counters(_) => {
simple_api_command(&mut socket, "GET", "counters", None).map_err(Error::ApiClient)
}
Some("ping") => {
SubCommandEnum::Ping(_) => {
simple_api_full_command(&mut socket, "GET", "vmm.ping", None).map_err(Error::ApiClient)
}
Some("shutdown-vmm") => simple_api_full_command(&mut socket, "PUT", "vmm.shutdown", None)
.map_err(Error::ApiClient),
Some("resize") => resize_api_command(
SubCommandEnum::Shutdown(_) => {
simple_api_full_command(&mut socket, "PUT", "vmm.shutdown", None)
.map_err(Error::ApiClient)
}
SubCommandEnum::Resize(ref config) => {
resize_api_command(&mut socket, config.cpus, &config.memory, &config.balloon)
}
SubCommandEnum::ResizeZone(ref config) => {
resize_zone_api_command(&mut socket, &config.id, &config.size)
}
SubCommandEnum::AddDevice(ref config) => {
add_device_api_command(&mut socket, &config.device_config)
}
SubCommandEnum::RemoveDevice(ref config) => {
remove_device_api_command(&mut socket, &config.device_config)
}
SubCommandEnum::AddDisk(ref config) => {
add_disk_api_command(&mut socket, &config.disk_config)
}
SubCommandEnum::AddFs(ref config) => add_fs_api_command(&mut socket, &config.fs_config),
SubCommandEnum::AddPmem(ref config) => {
add_pmem_api_command(&mut socket, &config.pmem_config)
}
SubCommandEnum::AddNet(ref config) => add_net_api_command(&mut socket, &config.net_config),
SubCommandEnum::AddUserDevice(ref config) => {
add_user_device_api_command(&mut socket, &config.device_config)
}
SubCommandEnum::AddVdpa(ref config) => {
add_vdpa_api_command(&mut socket, &config.vdpa_config)
}
SubCommandEnum::AddVsock(ref config) => {
add_vsock_api_command(&mut socket, &config.vsock_config)
}
SubCommandEnum::Snapshot(ref config) => {
snapshot_api_command(&mut socket, &config.snapshot_config)
}
SubCommandEnum::Restore(ref config) => {
restore_api_command(&mut socket, &config.restore_config)
}
SubCommandEnum::Coredump(ref config) => {
coredump_api_command(&mut socket, &config.coredump_config)
}
SubCommandEnum::SendMigration(ref config) => send_migration_api_command(
&mut socket,
matches
.subcommand_matches("resize")
.unwrap()
.get_one::<String>("cpus")
.map(|x| x as &str),
matches
.subcommand_matches("resize")
.unwrap()
.get_one::<String>("memory")
.map(|x| x as &str),
matches
.subcommand_matches("resize")
.unwrap()
.get_one::<String>("balloon")
.map(|x| x as &str),
&config.send_migration_config,
config.send_migration_local,
),
Some("resize-zone") => resize_zone_api_command(
&mut socket,
matches
.subcommand_matches("resize-zone")
.unwrap()
.get_one::<String>("id")
.unwrap(),
matches
.subcommand_matches("resize-zone")
.unwrap()
.get_one::<String>("size")
.unwrap(),
),
Some("add-device") => add_device_api_command(
&mut socket,
matches
.subcommand_matches("add-device")
.unwrap()
.get_one::<String>("device_config")
.unwrap(),
),
Some("remove-device") => remove_device_api_command(
&mut socket,
matches
.subcommand_matches("remove-device")
.unwrap()
.get_one::<String>("id")
.unwrap(),
),
Some("add-disk") => add_disk_api_command(
&mut socket,
matches
.subcommand_matches("add-disk")
.unwrap()
.get_one::<String>("disk_config")
.unwrap(),
),
Some("add-fs") => add_fs_api_command(
&mut socket,
matches
.subcommand_matches("add-fs")
.unwrap()
.get_one::<String>("fs_config")
.unwrap(),
),
Some("add-pmem") => add_pmem_api_command(
&mut socket,
matches
.subcommand_matches("add-pmem")
.unwrap()
.get_one::<String>("pmem_config")
.unwrap(),
),
Some("add-net") => add_net_api_command(
&mut socket,
matches
.subcommand_matches("add-net")
.unwrap()
.get_one::<String>("net_config")
.unwrap(),
),
Some("add-user-device") => add_user_device_api_command(
&mut socket,
matches
.subcommand_matches("add-user-device")
.unwrap()
.get_one::<String>("device_config")
.unwrap(),
),
Some("add-vdpa") => add_vdpa_api_command(
&mut socket,
matches
.subcommand_matches("add-vdpa")
.unwrap()
.get_one::<String>("vdpa_config")
.unwrap(),
),
Some("add-vsock") => add_vsock_api_command(
&mut socket,
matches
.subcommand_matches("add-vsock")
.unwrap()
.get_one::<String>("vsock_config")
.unwrap(),
),
Some("snapshot") => snapshot_api_command(
&mut socket,
matches
.subcommand_matches("snapshot")
.unwrap()
.get_one::<String>("snapshot_config")
.unwrap(),
),
Some("restore") => restore_api_command(
&mut socket,
matches
.subcommand_matches("restore")
.unwrap()
.get_one::<String>("restore_config")
.unwrap(),
),
Some("coredump") => coredump_api_command(
&mut socket,
matches
.subcommand_matches("coredump")
.unwrap()
.get_one::<String>("coredump_config")
.unwrap(),
),
Some("send-migration") => send_migration_api_command(
&mut socket,
matches
.subcommand_matches("send-migration")
.unwrap()
.get_one::<String>("send_migration_config")
.unwrap(),
matches
.subcommand_matches("send-migration")
.unwrap()
.get_flag("send_migration_local"),
),
Some("receive-migration") => receive_migration_api_command(
&mut socket,
matches
.subcommand_matches("receive-migration")
.unwrap()
.get_one::<String>("receive_migration_config")
.unwrap(),
),
Some("create") => create_api_command(
&mut socket,
matches
.subcommand_matches("create")
.unwrap()
.get_one::<String>("path")
.unwrap(),
),
Some(c) => simple_api_command(&mut socket, "PUT", c, None).map_err(Error::ApiClient),
None => unreachable!(),
SubCommandEnum::ReceiveMigration(ref config) => {
receive_migration_api_command(&mut socket, &config.receive_migration_config)
}
SubCommandEnum::Create(ref config) => create_api_command(&mut socket, &config.vm_config),
SubCommandEnum::Version(_) => {
// Already handled outside of this function
panic!()
}
}
}
#[derive(FromArgs, PartialEq, Debug)]
#[doc = "Remotely control a cloud-hypervisor VMM.\n\nPlease refer to cloud-hypervisor for configuration syntaxes."]
struct TopLevel {
#[argh(subcommand)]
command: SubCommandEnum,
#[argh(option, long = "api-socket")]
/// HTTP API socket path (UNIX domain socket)
api_socket: Option<String>,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
enum SubCommandEnum {
AddDevice(AddDeviceSubcommand),
AddDisk(AddDiskSubcommand),
AddFs(AddFsSubcommand),
AddPmem(AddPmemSubcommand),
AddNet(AddNetSubcommand),
AddUserDevice(AddUserDeviceSubcommand),
AddVdpa(AddVdpaSubcommand),
AddVsock(AddVsockSubcommand),
RemoveDevice(RemoveDeviceSubcommand),
Info(InfoSubcommand),
Counters(CountersSubcommand),
Pause(PauseSubcommand),
Reboot(RebootSubcommand),
PowerButton(PowerButtonSubcommand),
Resume(ResumeSubcommand),
Boot(BootSubcommand),
Delete(DeleteSubcommand),
Shutdown(ShutdownSubcommand),
Ping(PingSubcommand),
ShutdownVmm(ShutdownVmmSubcommand),
Resize(ResizeSubcommand),
ResizeZone(ResizeZoneSubcommand),
Snapshot(SnapshotSubcommand),
Restore(RestoreSubcommand),
Coredump(CoredumpSubcommand),
SendMigration(SendMigrationSubcommand),
ReceiveMigration(ReceiveMigrationSubcommand),
Create(CreateSubcommand),
Version(VersionSubcommand),
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "add-device")]
/// Add VFIO device
struct AddDeviceSubcommand {
#[argh(positional)]
/// device config
device_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "add-disk")]
/// Add block device
struct AddDiskSubcommand {
#[argh(positional)]
/// disk config
disk_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "add-fs")]
/// Add virtio-fs backed fs device
struct AddFsSubcommand {
#[argh(positional)]
/// virtio-fs config
fs_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "add-pmem")]
/// Add virtio-fs backed fs device
struct AddPmemSubcommand {
#[argh(positional)]
/// pmem config
pmem_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "add-net")]
/// Add virtio-fs backed fs device
struct AddNetSubcommand {
#[argh(positional)]
/// net config
net_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "add-user-device")]
/// Add userspace device
struct AddUserDeviceSubcommand {
#[argh(positional)]
/// device config
device_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "add-vdpa")]
/// Add vdpa device
struct AddVdpaSubcommand {
#[argh(positional)]
/// vdpa config
vdpa_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "add-vsock")]
/// Add vsock device
struct AddVsockSubcommand {
#[argh(positional)]
/// vsock config
vsock_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "remove-device")]
/// Remove VFIO device
struct RemoveDeviceSubcommand {
#[argh(positional)]
/// device config
device_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "info")]
/// Information on the VM
struct InfoSubcommand {}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "counters")]
/// Counters from the VM
struct CountersSubcommand {}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "pause")]
/// Pause the VM
struct PauseSubcommand {}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "reboot")]
/// Reboot the VM
struct RebootSubcommand {}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "power-button")]
/// Trigger a power button in the VM
struct PowerButtonSubcommand {}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "resume")]
/// Resume the VM
struct ResumeSubcommand {}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "boot")]
/// Boot a created VM
struct BootSubcommand {}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "delete")]
/// Delete a VM
struct DeleteSubcommand {}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "shutdown")]
/// Shutdown a VM
struct ShutdownSubcommand {}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "ping")]
/// Ping the VMM to check for API server availability
struct PingSubcommand {}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "shutdown-vmm")]
/// Shutdown the VMM
struct ShutdownVmmSubcommand {}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "resize")]
/// Resize the VM
struct ResizeSubcommand {
#[argh(option, long = "cpus")]
/// new VCPUs count
cpus: Option<u8>,
#[argh(option, long = "memory")]
/// new memory size in bytes (supports K/M/G suffix)"
memory: Option<String>,
#[argh(option, long = "balloon")]
/// new balloon size in bytes (supports K/M/G suffix)"
balloon: Option<String>,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "resize-zone")]
/// Resize a memory zone
struct ResizeZoneSubcommand {
#[argh(option, long = "id")]
/// memory zone identifier
id: String,
#[argh(option, long = "size")]
/// new memory size in bytes (supports K/M/G suffix)"
size: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "snapshot")]
/// Create a snapshot from VM
struct SnapshotSubcommand {
#[argh(positional)]
/// destination_url
snapshot_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "restore")]
/// Restore VM from a snapshot
struct RestoreSubcommand {
#[argh(positional)]
/// restore config
restore_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "coredump")]
/// Create a coredump from VM
struct CoredumpSubcommand {
#[argh(positional)]
/// coredump config
coredump_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "send-migration")]
/// Initiate a VM migration
struct SendMigrationSubcommand {
#[argh(switch, long = "local")]
/// local migration
send_migration_local: bool,
#[argh(positional)]
/// destination_url
send_migration_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "receive-migration")]
/// Receive a VM migration
struct ReceiveMigrationSubcommand {
#[argh(positional)]
/// receiver url
receive_migration_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "create")]
/// Create a VM from a JSON configuration
struct CreateSubcommand {
#[argh(positional, default = "String::from(\"-\")")]
/// vm config
vm_config: String,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "version")]
/// Print version information
struct VersionSubcommand {}
fn main() {
let app = Command::new("ch-remote")
.author(env!("CARGO_PKG_AUTHORS"))
.subcommand_required(true)
.about("Remotely control a cloud-hypervisor VMM.")
.arg(
Arg::new("api-socket")
.long("api-socket")
.help("HTTP API socket path (UNIX domain socket).")
.num_args(1)
.required(true),
)
.subcommand(
Command::new("add-device").about("Add VFIO device").arg(
Arg::new("device_config")
.index(1)
.help(vmm::config::DeviceConfig::SYNTAX),
),
)
.subcommand(
Command::new("add-disk").about("Add block device").arg(
Arg::new("disk_config")
.index(1)
.help(vmm::config::DiskConfig::SYNTAX),
),
)
.subcommand(
Command::new("add-fs")
.about("Add virtio-fs backed fs device")
.arg(
Arg::new("fs_config")
.index(1)
.help(vmm::config::FsConfig::SYNTAX),
),
)
.subcommand(
Command::new("add-pmem")
.about("Add persistent memory device")
.arg(
Arg::new("pmem_config")
.index(1)
.help(vmm::config::PmemConfig::SYNTAX),
),
)
.subcommand(
Command::new("add-net").about("Add network device").arg(
Arg::new("net_config")
.index(1)
.help(vmm::config::NetConfig::SYNTAX),
),
)
.subcommand(
Command::new("add-user-device")
.about("Add userspace device")
.arg(
Arg::new("device_config")
.index(1)
.help(vmm::config::UserDeviceConfig::SYNTAX),
),
)
.subcommand(
Command::new("add-vdpa").about("Add vDPA device").arg(
Arg::new("vdpa_config")
.index(1)
.help(vmm::config::VdpaConfig::SYNTAX),
),
)
.subcommand(
Command::new("add-vsock").about("Add vsock device").arg(
Arg::new("vsock_config")
.index(1)
.help(vmm::config::VsockConfig::SYNTAX),
),
)
.subcommand(
Command::new("remove-device")
.about("Remove VFIO device")
.arg(Arg::new("id").index(1).help("<device_id>")),
)
.subcommand(Command::new("info").about("Info on the VM"))
.subcommand(Command::new("counters").about("Counters from the VM"))
.subcommand(Command::new("pause").about("Pause the VM"))
.subcommand(Command::new("reboot").about("Reboot the VM"))
.subcommand(Command::new("power-button").about("Trigger a power button in the VM"))
.subcommand(
Command::new("resize")
.about("Resize the VM")
.arg(
Arg::new("cpus")
.long("cpus")
.help("New vCPUs count")
.num_args(1),
)
.arg(
Arg::new("memory")
.long("memory")
.help("New memory size in bytes (supports K/M/G suffix)")
.num_args(1),
)
.arg(
Arg::new("balloon")
.long("balloon")
.help("New balloon size in bytes (supports K/M/G suffix)")
.num_args(1),
),
)
.subcommand(
Command::new("resize-zone")
.about("Resize a memory zone")
.arg(
Arg::new("id")
.long("id")
.help("Memory zone identifier")
.num_args(1),
)
.arg(
Arg::new("size")
.long("size")
.help("New memory zone size in bytes (supports K/M/G suffix)")
.num_args(1),
),
)
.subcommand(Command::new("resume").about("Resume the VM"))
.subcommand(Command::new("boot").about("Boot a created VM"))
.subcommand(Command::new("delete").about("Delete a VM"))
.subcommand(Command::new("shutdown").about("Shutdown the VM"))
.subcommand(
Command::new("snapshot")
.about("Create a snapshot from VM")
.arg(
Arg::new("snapshot_config")
.index(1)
.help("<destination_url>"),
),
)
.subcommand(
Command::new("restore")
.about("Restore VM from a snapshot")
.arg(
Arg::new("restore_config")
.index(1)
.help(vmm::config::RestoreConfig::SYNTAX),
),
)
.subcommand(
Command::new("coredump")
.about("Create a coredump from VM")
.arg(Arg::new("coredump_config").index(1).help("<file_path>")),
)
.subcommand(
Command::new("send-migration")
.about("Initiate a VM migration")
.arg(
Arg::new("send_migration_config")
.index(1)
.help("<destination_url>"),
)
.arg(
Arg::new("send_migration_local")
.long("local")
.num_args(0)
.action(ArgAction::SetTrue),
),
)
.subcommand(
Command::new("receive-migration")
.about("Receive a VM migration")
.arg(
Arg::new("receive_migration_config")
.index(1)
.help("<receiver_url>"),
),
)
.subcommand(
Command::new("create")
.about("Create VM from a JSON configuration")
.arg(Arg::new("path").index(1).default_value("-")),
)
.subcommand(Command::new("ping").about("Ping the VMM to check for API server availability"))
.subcommand(Command::new("shutdown-vmm").about("Shutdown the VMM"));
let toplevel: TopLevel = argh::from_env();
let matches = app.get_matches();
if matches!(toplevel.command, SubCommandEnum::Version(_)) {
println!("{} {}", env!("CARGO_BIN_NAME"), env!("BUILT_VERSION"));
return;
}
if let Err(e) = do_command(&matches) {
if toplevel.api_socket.is_none() {
println!("Please specify --api-socket");
process::exit(1)
}
if let Err(e) = do_command(&toplevel) {
eprintln!("Error running command: {e}");
process::exit(1)
};

View File

@ -246,7 +246,7 @@ fn curl_command(api_socket: &str, method: &str, url: &str, http_body: Option<&st
fn remote_command(api_socket: &str, command: &str, arg: Option<&str>) -> bool {
let mut cmd = Command::new(clh_command("ch-remote"));
cmd.args([&format!("--api-socket={api_socket}"), command]);
cmd.args(["--api-socket", api_socket, command]);
if let Some(arg) = arg {
cmd.arg(arg);
@ -264,7 +264,7 @@ fn remote_command(api_socket: &str, command: &str, arg: Option<&str>) -> bool {
fn remote_command_w_output(api_socket: &str, command: &str, arg: Option<&str>) -> (bool, Vec<u8>) {
let mut cmd = Command::new(clh_command("ch-remote"));
cmd.args([&format!("--api-socket={api_socket}"), command]);
cmd.args(["--api-socket", api_socket, command]);
if let Some(arg) = arg {
cmd.arg(arg);
@ -283,18 +283,18 @@ fn resize_command(
event_file: Option<&str>,
) -> bool {
let mut cmd = Command::new(clh_command("ch-remote"));
cmd.args([&format!("--api-socket={api_socket}"), "resize"]);
cmd.args(["--api-socket", api_socket, "resize"]);
if let Some(desired_vcpus) = desired_vcpus {
cmd.arg(format!("--cpus={desired_vcpus}"));
cmd.args(["--cpus", &format!("{desired_vcpus}")]);
}
if let Some(desired_ram) = desired_ram {
cmd.arg(format!("--memory={desired_ram}"));
cmd.args(["--memory", &format!("{desired_ram}")]);
}
if let Some(desired_balloon) = desired_balloon {
cmd.arg(format!("--balloon={desired_balloon}"));
cmd.args(["--balloon", &format!("{desired_balloon}")]);
}
let ret = cmd.status().expect("Failed to launch ch-remote").success();
@ -319,10 +319,13 @@ fn resize_command(
fn resize_zone_command(api_socket: &str, id: &str, desired_size: &str) -> bool {
let mut cmd = Command::new(clh_command("ch-remote"));
cmd.args([
&format!("--api-socket={api_socket}"),
"--api-socket",
api_socket,
"resize-zone",
&format!("--id={id}"),
&format!("--size={desired_size}"),
"--id",
id,
"--size",
desired_size,
]);
cmd.status().expect("Failed to launch ch-remote").success()
@ -3861,7 +3864,7 @@ mod common_parallel {
let vfio_hotplug_output = guest
.ssh_command_l1(
"sudo /mnt/ch-remote \
--api-socket=/tmp/ch_api.sock \
--api-socket /tmp/ch_api.sock \
add-device path=/sys/bus/pci/devices/0000:00:09.0,id=vfio123",
)
.unwrap();
@ -3901,7 +3904,7 @@ mod common_parallel {
guest
.ssh_command_l1(
"sudo /mnt/ch-remote \
--api-socket=/tmp/ch_api.sock \
--api-socket /tmp/ch_api.sock \
remove-device vfio123",
)
.unwrap();
@ -3932,7 +3935,7 @@ mod common_parallel {
guest
.ssh_command_l1(
"sudo /mnt/ch-remote \
--api-socket=/tmp/ch_api.sock \
--api-socket /tmp/ch_api.sock \
resize --memory=1073741824",
)
.unwrap();
@ -7927,7 +7930,7 @@ mod vfio {
let vfio_hotplug_output = guest
.ssh_command_l1(
"sudo /mnt/ch-remote \
--api-socket=/tmp/ch_api.sock \
--api-socket /tmp/ch_api.sock \
add-device path=/sys/bus/pci/devices/0000:00:09.0,id=vfio123",
)
.unwrap();
@ -7967,7 +7970,7 @@ mod vfio {
guest
.ssh_command_l1(
"sudo /mnt/ch-remote \
--api-socket=/tmp/ch_api.sock \
--api-socket /tmp/ch_api.sock \
remove-device vfio123",
)
.unwrap();
@ -7998,7 +8001,7 @@ mod vfio {
guest
.ssh_command_l1(
"sudo /mnt/ch-remote \
--api-socket=/tmp/ch_api.sock \
--api-socket /tmp/ch_api.sock \
resize --memory=1073741824",
)
.unwrap();
@ -8157,7 +8160,8 @@ mod live_migration {
// Start to receive migration from the destintion VM
let mut receive_migration = Command::new(clh_command("ch-remote"))
.args([
&format!("--api-socket={dest_api_socket}"),
"--api-socket",
dest_api_socket,
"receive-migration",
&format! {"unix:{migration_socket}"},
])
@ -8170,14 +8174,15 @@ mod live_migration {
// Start to send migration from the source VM
let mut args = [
format!("--api-socket={}", &src_api_socket),
"--api-socket".to_string(),
src_api_socket.to_string(),
"send-migration".to_string(),
format! {"unix:{migration_socket}"},
]
.to_vec();
if local {
args.insert(2, "--local".to_string());
args.insert(3, "--local".to_string());
}
let mut send_migration = Command::new(clh_command("ch-remote"))