From c23edda98bf88a0a31d6e16ba574292f99283dec Mon Sep 17 00:00:00 2001 From: Sebastian Eydam Date: Wed, 15 Apr 2026 10:16:33 +0200 Subject: [PATCH] vmm: add TLS API option to send migration call To enable TLS, the caller has to provide a path to a directory that contains the necessary files. On-behalf-of: SAP sebastian.eydam@sap.com Signed-off-by: Sebastian Eydam --- vmm/src/api/mod.rs | 25 ++++++++++++++++++++--- vmm/src/api/openapi/cloud-hypervisor.yaml | 6 ++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/vmm/src/api/mod.rs b/vmm/src/api/mod.rs index edaa85435..93bc40a5c 100644 --- a/vmm/src/api/mod.rs +++ b/vmm/src/api/mod.rs @@ -35,6 +35,7 @@ pub mod http; use std::io; use std::num::{NonZeroU32, NonZeroU64}; +use std::path::PathBuf; use std::str::FromStr; use std::sync::mpsc::{RecvError, SendError, Sender, channel}; use std::time::Duration; @@ -338,13 +339,17 @@ pub struct VmSendMigrationData { /// Must be between 1 and `MAX_MIGRATION_CONNECTIONS` inclusive. #[serde(default = "VmSendMigrationData::default_connections")] pub connections: NonZeroU32, + /// Path to the directory containing the TLS root CA certificate (ca-cert.pem), the TLS client certificate (client-cert.pem), and TLS client key (client-key.pem). + #[serde(default)] + pub tls_dir: Option, } impl VmSendMigrationData { pub const SYNTAX: &'static str = "VM send migration parameters \ \"destination_url=[,local=on|off,\ downtime_ms=,timeout_s=,\ - timeout_strategy=cancel|ignore,connections=]\""; + timeout_strategy=cancel|ignore,connections=,\ + tls_dir=]\""; // Same as QEMU. pub const DEFAULT_DOWNTIME: Duration = Duration::from_millis(300); @@ -372,7 +377,8 @@ impl VmSendMigrationData { .add("downtime_ms") .add("timeout_s") .add("timeout_strategy") - .add("connections"); + .add("connections") + .add("tls_dir"); parser .parse(migration) .map_err(VmSendMigrationConfigError::ParseError)?; @@ -424,6 +430,10 @@ impl VmSendMigrationData { })?, None => Self::default_connections(), }; + let tls_dir = parser + .convert::("tls_dir") + .map_err(VmSendMigrationConfigError::ParseError)? + .map(|path| PathBuf::from(&path)); let data = Self { destination_url, @@ -432,6 +442,7 @@ impl VmSendMigrationData { timeout_s, timeout_strategy, connections, + tls_dir, }; data.validate()?; @@ -462,6 +473,11 @@ impl VmSendMigrationData { .to_string(), )); } + if self.tls_dir.is_some() { + return Err(VmSendMigrationConfigError::ValidationError( + "UNIX sockets and TLS encryption cannot be used at the same time.".to_string(), + )); + } } else { return Err(VmSendMigrationConfigError::ValidationError( "destination_url must use tcp:: or unix:.".to_string(), @@ -1862,12 +1878,14 @@ mod unit_tests { timeout_s: VmSendMigrationData::default_timeout_s(), timeout_strategy: Default::default(), connections: VmSendMigrationData::default_connections(), + tls_dir: None, } ); // Happy path, fully specified + let tls_dir = std::env::temp_dir(); let data = - VmSendMigrationData::parse("destination_url=tcp:192.168.1.1:8080,downtime_ms=150,timeout_s=900,timeout_strategy=ignore,connections=4") + VmSendMigrationData::parse(&format!("destination_url=tcp:192.168.1.1:8080,downtime_ms=150,timeout_s=900,timeout_strategy=ignore,connections=4,tls_dir={}", tls_dir.display())) .unwrap(); assert_eq!( data, @@ -1878,6 +1896,7 @@ mod unit_tests { timeout_s: NonZeroU64::new(900).unwrap(), timeout_strategy: TimeoutStrategy::Ignore, connections: NonZeroU32::new(4).unwrap(), + tls_dir: Some(tls_dir), } ); } diff --git a/vmm/src/api/openapi/cloud-hypervisor.yaml b/vmm/src/api/openapi/cloud-hypervisor.yaml index 4dd392ea5..4ed651ced 100644 --- a/vmm/src/api/openapi/cloud-hypervisor.yaml +++ b/vmm/src/api/openapi/cloud-hypervisor.yaml @@ -1553,6 +1553,12 @@ components: The number of parallel TCP connections to use for migration. Must be between 1 and 128. Multiple connections are not supported with local UNIX-socket migration. + tls_dir: + type: string + description: > + Directory containing the TLS root CA certificate (ca-cert.pem), the TLS client + certificate (client-cert.pem), and TLS client key (client-key.pem). + TLS is only supported with tcp:: destination URLs. VmAddUserDevice: required: