mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
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:
committed by
Rob Bradford
parent
7e0f8f7163
commit
040fcaed92
@@ -38,6 +38,7 @@ use std::sync::mpsc::{RecvError, SendError, Sender, channel};
|
||||
|
||||
use log::info;
|
||||
use micro_http::Body;
|
||||
use option_parser::{OptionParser, OptionParserError, Toggle};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
use vm_migration::MigratableError;
|
||||
@@ -266,7 +267,12 @@ pub struct VmReceiveMigrationData {
|
||||
pub receiver_url: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize, Default, Debug)]
|
||||
#[derive(Debug, Error)]
|
||||
#[error("Error parsing send migration parameters")]
|
||||
pub struct VmSendMigrationParseError(#[source] OptionParserError);
|
||||
|
||||
/// Configuration for an outgoing migration.
|
||||
#[derive(Clone, Deserialize, Serialize, Debug)]
|
||||
pub struct VmSendMigrationData {
|
||||
/// URL to migrate the VM to
|
||||
pub destination_url: String,
|
||||
@@ -275,6 +281,33 @@ pub struct VmSendMigrationData {
|
||||
pub local: bool,
|
||||
}
|
||||
|
||||
impl VmSendMigrationData {
|
||||
pub const SYNTAX: &'static str = "VM send migration parameters \
|
||||
\"destination_url=<url>[,local=on|off]\"";
|
||||
|
||||
pub fn parse(migration: &str) -> Result<Self, VmSendMigrationParseError> {
|
||||
let mut parser = OptionParser::new();
|
||||
parser.add("destination_url").add("local");
|
||||
parser.parse(migration).map_err(VmSendMigrationParseError)?;
|
||||
|
||||
let destination_url = parser.get("destination_url").ok_or_else(|| {
|
||||
VmSendMigrationParseError(OptionParserError::InvalidSyntax(
|
||||
"destination_url is required".to_string(),
|
||||
))
|
||||
})?;
|
||||
let local = parser
|
||||
.convert::<Toggle>("local")
|
||||
.map_err(VmSendMigrationParseError)?
|
||||
.unwrap_or(Toggle(false))
|
||||
.0;
|
||||
|
||||
Ok(Self {
|
||||
destination_url,
|
||||
local,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ApiResponsePayload {
|
||||
/// No data is sent on the channel.
|
||||
Empty,
|
||||
@@ -1541,3 +1574,23 @@ impl ApiAction for VmNmi {
|
||||
get_response_body(self, api_evt, api_sender, data)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod unit_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_vm_send_migration_data_parse() {
|
||||
// Fully specified
|
||||
let data = VmSendMigrationData::parse("destination_url=tcp://192.168.1.1:8080,local=on")
|
||||
.expect("valid migration string should parse");
|
||||
assert_eq!(data.destination_url, "tcp://192.168.1.1:8080");
|
||||
assert!(data.local);
|
||||
|
||||
// Unknown option is an error
|
||||
VmSendMigrationData::parse("destination_url=unix:/tmp/sock,unknown_field=foo").unwrap_err();
|
||||
|
||||
// Invalid toggle value is an error
|
||||
VmSendMigrationData::parse("destination_url=unix:/tmp/sock,local=yes").unwrap_err();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user