vmm: add VmSendMigrationData::parse(); integrate with OptionParser

This change prepares upcoming options (following commit) that are added
to VmSendMigrationData.

VmSendMigrationData is a special case as it is currently the only
"rich configuration" type that lives outside `config.rs`, as it is
purely API-facing. Therefore, it isn't integrated into the existing
OptionParser infrastructure. We therefore introduce a `parse()` method
to use that in `ch-remote` in the following.

In `ch-remote`, we remove `--local` for `send-migration` and switch to
the new option string parsing constructor (breaking change!). This
prepares the addition of downtime and timeout options in the following
and streamlines the `ch-remote` command line interface with other
commands, such as `ch-remote add-net`.

Lastly, this commit updates the integration tests.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
This commit is contained in:
Philipp Schuster
2026-03-17 11:11:54 +01:00
committed by Rob Bradford
parent 7e0f8f7163
commit 040fcaed92
3 changed files with 73 additions and 33 deletions

View File

@@ -16,7 +16,9 @@ use api_client::{
Error as ApiClientError, simple_api_command, simple_api_command_with_fds,
simple_api_full_command,
};
use clap::{Arg, ArgAction, ArgMatches, Command};
#[cfg(feature = "dbus_api")]
use clap::ArgAction;
use clap::{Arg, ArgMatches, Command};
use log::error;
use option_parser::{ByteSized, ByteSizedParseError};
use thiserror::Error;
@@ -69,6 +71,8 @@ enum Error {
ReadingFile(#[source] std::io::Error),
#[error("Invalid disk size")]
InvalidDiskSize(#[source] ByteSizedParseError),
#[error("Error parsing send migration configuration")]
SendMigrationConfig(#[from] vmm::api::VmSendMigrationParseError),
}
enum TargetApi<'a> {
@@ -519,11 +523,7 @@ fn rest_api_do_command(matches: &ArgMatches, socket: &mut UnixStream) -> ApiResu
.unwrap()
.get_one::<String>("send_migration_config")
.unwrap(),
matches
.subcommand_matches("send-migration")
.unwrap()
.get_flag("send_migration_local"),
);
)?;
simple_api_command(socket, "PUT", "send-migration", Some(&send_migration_data))
.map_err(Error::HttpApiClient)
}
@@ -743,11 +743,7 @@ fn dbus_api_do_command(matches: &ArgMatches, proxy: &DBusApi1ProxyBlocking<'_>)
.unwrap()
.get_one::<String>("send_migration_config")
.unwrap(),
matches
.subcommand_matches("send-migration")
.unwrap()
.get_flag("send_migration_local"),
);
)?;
proxy.api_vm_send_migration(&send_migration_data)
}
Some("receive-migration") => {
@@ -953,13 +949,11 @@ fn receive_migration_data(url: &str) -> String {
serde_json::to_string(&receive_migration_data).unwrap()
}
fn send_migration_data(url: &str, local: bool) -> String {
let send_migration_data = vmm::api::VmSendMigrationData {
destination_url: url.to_owned(),
local,
};
serde_json::to_string(&send_migration_data).unwrap()
fn send_migration_data(config: &str) -> Result<String, Error> {
let send_migration_data =
vmm::api::VmSendMigrationData::parse(config).map_err(Error::SendMigrationConfig)?;
let send_migration_config = serde_json::to_string(&send_migration_data).unwrap();
Ok(send_migration_config)
}
fn create_data(path: &str) -> Result<String, Error> {
@@ -1141,13 +1135,7 @@ fn get_cli_commands_sorted() -> Box<[Command]> {
.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),
.help(vmm::api::VmSendMigrationData::SYNTAX),
),
Command::new("shutdown").about("Shutdown the VM"),
Command::new("shutdown-vmm").about("Shutdown the VMM"),

View File

@@ -9891,17 +9891,16 @@ mod live_migration {
thread::sleep(std::time::Duration::new(1, 0));
// Start to send migration from the source VM
let mut args = [
let args = [
format!("--api-socket={}", &src_api_socket),
"send-migration".to_string(),
format! {"unix:{migration_socket}"},
format!(
"destination_url=unix:{migration_socket},local={}",
if local { "on" } else { "off" }
),
]
.to_vec();
if local {
args.insert(2, "--local".to_string());
}
let mut send_migration = Command::new(clh_command("ch-remote"))
.args(&args)
.stderr(Stdio::piped())
@@ -11066,7 +11065,7 @@ mod live_migration {
.args([
&format!("--api-socket={src_api_socket}"),
"send-migration",
&format!("tcp:{host_ip}:{migration_port}"),
&format!("destination_url=tcp:{host_ip}:{migration_port}"),
])
.stdin(Stdio::null())
.stderr(Stdio::piped())