mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-08-22 07:51:16 +00:00
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:
parent
1ba995d952
commit
d5558aea2a
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -177,6 +177,7 @@ version = "29.0.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"api_client",
|
"api_client",
|
||||||
|
"argh",
|
||||||
"clap",
|
"clap",
|
||||||
"dirs",
|
"dirs",
|
||||||
"epoll",
|
"epoll",
|
||||||
|
@ -26,6 +26,7 @@ strip = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.68"
|
anyhow = "1.0.68"
|
||||||
api_client = { path = "api_client" }
|
api_client = { path = "api_client" }
|
||||||
|
argh = "0.1.9"
|
||||||
clap = { version = "4.0.32", features = ["wrap_help","cargo","string"] }
|
clap = { version = "4.0.32", features = ["wrap_help","cargo","string"] }
|
||||||
epoll = "4.3.1"
|
epoll = "4.3.1"
|
||||||
event_monitor = { path = "event_monitor" }
|
event_monitor = { path = "event_monitor" }
|
||||||
|
@ -7,7 +7,7 @@ use api_client::simple_api_command;
|
|||||||
use api_client::simple_api_command_with_fds;
|
use api_client::simple_api_command_with_fds;
|
||||||
use api_client::simple_api_full_command;
|
use api_client::simple_api_full_command;
|
||||||
use api_client::Error as ApiClientError;
|
use api_client::Error as ApiClientError;
|
||||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
use argh::FromArgs;
|
||||||
use option_parser::{ByteSized, ByteSizedParseError};
|
use option_parser::{ByteSized, ByteSizedParseError};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
@ -18,7 +18,6 @@ use std::process;
|
|||||||
enum Error {
|
enum Error {
|
||||||
Connect(std::io::Error),
|
Connect(std::io::Error),
|
||||||
ApiClient(ApiClientError),
|
ApiClient(ApiClientError),
|
||||||
InvalidCpuCount(std::num::ParseIntError),
|
|
||||||
InvalidMemorySize(ByteSizedParseError),
|
InvalidMemorySize(ByteSizedParseError),
|
||||||
InvalidBalloonSize(ByteSizedParseError),
|
InvalidBalloonSize(ByteSizedParseError),
|
||||||
AddDeviceConfig(vmm::config::Error),
|
AddDeviceConfig(vmm::config::Error),
|
||||||
@ -40,7 +39,6 @@ impl fmt::Display for Error {
|
|||||||
match self {
|
match self {
|
||||||
ApiClient(e) => e.fmt(f),
|
ApiClient(e) => e.fmt(f),
|
||||||
Connect(e) => write!(f, "Error opening HTTP socket: {e}"),
|
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:?}"),
|
InvalidMemorySize(e) => write!(f, "Error parsing memory size: {e:?}"),
|
||||||
InvalidBalloonSize(e) => write!(f, "Error parsing balloon size: {e:?}"),
|
InvalidBalloonSize(e) => write!(f, "Error parsing balloon size: {e:?}"),
|
||||||
AddDeviceConfig(e) => write!(f, "Error parsing device syntax: {e}"),
|
AddDeviceConfig(e) => write!(f, "Error parsing device syntax: {e}"),
|
||||||
@ -60,16 +58,10 @@ impl fmt::Display for Error {
|
|||||||
|
|
||||||
fn resize_api_command(
|
fn resize_api_command(
|
||||||
socket: &mut UnixStream,
|
socket: &mut UnixStream,
|
||||||
cpus: Option<&str>,
|
desired_vcpus: Option<u8>,
|
||||||
memory: Option<&str>,
|
memory: &Option<String>,
|
||||||
balloon: Option<&str>,
|
balloon: &Option<String>,
|
||||||
) -> Result<(), Error> {
|
) -> 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 {
|
let desired_ram: Option<u64> = if let Some(memory) = memory {
|
||||||
Some(
|
Some(
|
||||||
memory
|
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)
|
simple_api_command(socket, "PUT", "create", Some(&data)).map_err(Error::ApiClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_command(matches: &ArgMatches) -> Result<(), Error> {
|
fn do_command(toplevel: &TopLevel) -> Result<(), Error> {
|
||||||
let mut socket = UnixStream::connect(matches.get_one::<String>("api-socket").unwrap())
|
let mut socket =
|
||||||
.map_err(Error::Connect)?;
|
UnixStream::connect(toplevel.api_socket.as_deref().unwrap()).map_err(Error::Connect)?;
|
||||||
|
|
||||||
match matches.subcommand_name() {
|
match toplevel.command {
|
||||||
Some("info") => {
|
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)
|
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)
|
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)
|
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)
|
SubCommandEnum::Shutdown(_) => {
|
||||||
.map_err(Error::ApiClient),
|
simple_api_full_command(&mut socket, "PUT", "vmm.shutdown", None)
|
||||||
Some("resize") => resize_api_command(
|
.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,
|
&mut socket,
|
||||||
matches
|
&config.send_migration_config,
|
||||||
.subcommand_matches("resize")
|
config.send_migration_local,
|
||||||
.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),
|
|
||||||
),
|
),
|
||||||
Some("resize-zone") => resize_zone_api_command(
|
SubCommandEnum::ReceiveMigration(ref config) => {
|
||||||
&mut socket,
|
receive_migration_api_command(&mut socket, &config.receive_migration_config)
|
||||||
matches
|
}
|
||||||
.subcommand_matches("resize-zone")
|
SubCommandEnum::Create(ref config) => create_api_command(&mut socket, &config.vm_config),
|
||||||
.unwrap()
|
SubCommandEnum::Version(_) => {
|
||||||
.get_one::<String>("id")
|
// Already handled outside of this function
|
||||||
.unwrap(),
|
panic!()
|
||||||
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!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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() {
|
fn main() {
|
||||||
let app = Command::new("ch-remote")
|
let toplevel: TopLevel = argh::from_env();
|
||||||
.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 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}");
|
eprintln!("Error running command: {e}");
|
||||||
process::exit(1)
|
process::exit(1)
|
||||||
};
|
};
|
||||||
|
@ -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 {
|
fn remote_command(api_socket: &str, command: &str, arg: Option<&str>) -> bool {
|
||||||
let mut cmd = Command::new(clh_command("ch-remote"));
|
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 {
|
if let Some(arg) = arg {
|
||||||
cmd.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>) {
|
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"));
|
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 {
|
if let Some(arg) = arg {
|
||||||
cmd.arg(arg);
|
cmd.arg(arg);
|
||||||
@ -283,18 +283,18 @@ fn resize_command(
|
|||||||
event_file: Option<&str>,
|
event_file: Option<&str>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut cmd = Command::new(clh_command("ch-remote"));
|
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 {
|
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 {
|
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 {
|
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();
|
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 {
|
fn resize_zone_command(api_socket: &str, id: &str, desired_size: &str) -> bool {
|
||||||
let mut cmd = Command::new(clh_command("ch-remote"));
|
let mut cmd = Command::new(clh_command("ch-remote"));
|
||||||
cmd.args([
|
cmd.args([
|
||||||
&format!("--api-socket={api_socket}"),
|
"--api-socket",
|
||||||
|
api_socket,
|
||||||
"resize-zone",
|
"resize-zone",
|
||||||
&format!("--id={id}"),
|
"--id",
|
||||||
&format!("--size={desired_size}"),
|
id,
|
||||||
|
"--size",
|
||||||
|
desired_size,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
cmd.status().expect("Failed to launch ch-remote").success()
|
cmd.status().expect("Failed to launch ch-remote").success()
|
||||||
@ -3861,7 +3864,7 @@ mod common_parallel {
|
|||||||
let vfio_hotplug_output = guest
|
let vfio_hotplug_output = guest
|
||||||
.ssh_command_l1(
|
.ssh_command_l1(
|
||||||
"sudo /mnt/ch-remote \
|
"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",
|
add-device path=/sys/bus/pci/devices/0000:00:09.0,id=vfio123",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -3901,7 +3904,7 @@ mod common_parallel {
|
|||||||
guest
|
guest
|
||||||
.ssh_command_l1(
|
.ssh_command_l1(
|
||||||
"sudo /mnt/ch-remote \
|
"sudo /mnt/ch-remote \
|
||||||
--api-socket=/tmp/ch_api.sock \
|
--api-socket /tmp/ch_api.sock \
|
||||||
remove-device vfio123",
|
remove-device vfio123",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -3932,7 +3935,7 @@ mod common_parallel {
|
|||||||
guest
|
guest
|
||||||
.ssh_command_l1(
|
.ssh_command_l1(
|
||||||
"sudo /mnt/ch-remote \
|
"sudo /mnt/ch-remote \
|
||||||
--api-socket=/tmp/ch_api.sock \
|
--api-socket /tmp/ch_api.sock \
|
||||||
resize --memory=1073741824",
|
resize --memory=1073741824",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -7927,7 +7930,7 @@ mod vfio {
|
|||||||
let vfio_hotplug_output = guest
|
let vfio_hotplug_output = guest
|
||||||
.ssh_command_l1(
|
.ssh_command_l1(
|
||||||
"sudo /mnt/ch-remote \
|
"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",
|
add-device path=/sys/bus/pci/devices/0000:00:09.0,id=vfio123",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -7967,7 +7970,7 @@ mod vfio {
|
|||||||
guest
|
guest
|
||||||
.ssh_command_l1(
|
.ssh_command_l1(
|
||||||
"sudo /mnt/ch-remote \
|
"sudo /mnt/ch-remote \
|
||||||
--api-socket=/tmp/ch_api.sock \
|
--api-socket /tmp/ch_api.sock \
|
||||||
remove-device vfio123",
|
remove-device vfio123",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -7998,7 +8001,7 @@ mod vfio {
|
|||||||
guest
|
guest
|
||||||
.ssh_command_l1(
|
.ssh_command_l1(
|
||||||
"sudo /mnt/ch-remote \
|
"sudo /mnt/ch-remote \
|
||||||
--api-socket=/tmp/ch_api.sock \
|
--api-socket /tmp/ch_api.sock \
|
||||||
resize --memory=1073741824",
|
resize --memory=1073741824",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -8157,7 +8160,8 @@ mod live_migration {
|
|||||||
// Start to receive migration from the destintion VM
|
// Start to receive migration from the destintion VM
|
||||||
let mut receive_migration = Command::new(clh_command("ch-remote"))
|
let mut receive_migration = Command::new(clh_command("ch-remote"))
|
||||||
.args([
|
.args([
|
||||||
&format!("--api-socket={dest_api_socket}"),
|
"--api-socket",
|
||||||
|
dest_api_socket,
|
||||||
"receive-migration",
|
"receive-migration",
|
||||||
&format! {"unix:{migration_socket}"},
|
&format! {"unix:{migration_socket}"},
|
||||||
])
|
])
|
||||||
@ -8170,14 +8174,15 @@ mod live_migration {
|
|||||||
// Start to send migration from the source VM
|
// Start to send migration from the source VM
|
||||||
|
|
||||||
let mut args = [
|
let mut args = [
|
||||||
format!("--api-socket={}", &src_api_socket),
|
"--api-socket".to_string(),
|
||||||
|
src_api_socket.to_string(),
|
||||||
"send-migration".to_string(),
|
"send-migration".to_string(),
|
||||||
format! {"unix:{migration_socket}"},
|
format! {"unix:{migration_socket}"},
|
||||||
]
|
]
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
if local {
|
if local {
|
||||||
args.insert(2, "--local".to_string());
|
args.insert(3, "--local".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut send_migration = Command::new(clh_command("ch-remote"))
|
let mut send_migration = Command::new(clh_command("ch-remote"))
|
||||||
|
Loading…
Reference in New Issue
Block a user