Automatically backup source network and VM configuration
This commit is contained in:
parent
d053490a47
commit
d8a6b58c52
@ -115,17 +115,24 @@ impl Handler<GetSourceDomainXMLReq> for LibVirtActor {
|
|||||||
|
|
||||||
#[derive(Message)]
|
#[derive(Message)]
|
||||||
#[rtype(result = "anyhow::Result<XMLUuid>")]
|
#[rtype(result = "anyhow::Result<XMLUuid>")]
|
||||||
pub struct DefineDomainReq(pub DomainXML);
|
pub struct DefineDomainReq(pub VMInfo, pub DomainXML);
|
||||||
|
|
||||||
impl Handler<DefineDomainReq> for LibVirtActor {
|
impl Handler<DefineDomainReq> for LibVirtActor {
|
||||||
type Result = anyhow::Result<XMLUuid>;
|
type Result = anyhow::Result<XMLUuid>;
|
||||||
|
|
||||||
fn handle(&mut self, msg: DefineDomainReq, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, mut msg: DefineDomainReq, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
let xml = msg.0.into_xml()?;
|
let xml = msg.1.into_xml()?;
|
||||||
|
|
||||||
log::debug!("Define domain:\n{}", xml);
|
log::debug!("Define domain:\n{}", xml);
|
||||||
let domain = Domain::define_xml(&self.m, &xml)?;
|
let domain = Domain::define_xml(&self.m, &xml)?;
|
||||||
XMLUuid::parse_from_str(&domain.get_uuid_string()?)
|
let uuid = XMLUuid::parse_from_str(&domain.get_uuid_string()?)?;
|
||||||
|
|
||||||
|
// Save a copy of the source definition
|
||||||
|
msg.0.uuid = Some(uuid);
|
||||||
|
let json = serde_json::to_string(&msg.0)?;
|
||||||
|
std::fs::write(AppConfig::get().vm_definition_path(&msg.0.name), json)?;
|
||||||
|
|
||||||
|
Ok(uuid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,6 +162,12 @@ impl Handler<DeleteDomainReq> for LibVirtActor {
|
|||||||
std::fs::remove_file(vnc_socket)?;
|
std::fs::remove_file(vnc_socket)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove backup definition
|
||||||
|
let backup_definition = AppConfig::get().vm_definition_path(&domain_name);
|
||||||
|
if backup_definition.exists() {
|
||||||
|
std::fs::remove_file(backup_definition)?;
|
||||||
|
}
|
||||||
|
|
||||||
// Delete the domain
|
// Delete the domain
|
||||||
domain.undefine_flags(match msg.keep_files {
|
domain.undefine_flags(match msg.keep_files {
|
||||||
true => sys::VIR_DOMAIN_UNDEFINE_KEEP_NVRAM,
|
true => sys::VIR_DOMAIN_UNDEFINE_KEEP_NVRAM,
|
||||||
@ -360,20 +373,27 @@ impl Handler<SetDomainAutostart> for LibVirtActor {
|
|||||||
|
|
||||||
#[derive(Message)]
|
#[derive(Message)]
|
||||||
#[rtype(result = "anyhow::Result<XMLUuid>")]
|
#[rtype(result = "anyhow::Result<XMLUuid>")]
|
||||||
pub struct DefineNetwork(pub NetworkXML);
|
pub struct DefineNetwork(pub NetworkInfo, pub NetworkXML);
|
||||||
|
|
||||||
impl Handler<DefineNetwork> for LibVirtActor {
|
impl Handler<DefineNetwork> for LibVirtActor {
|
||||||
type Result = anyhow::Result<XMLUuid>;
|
type Result = anyhow::Result<XMLUuid>;
|
||||||
|
|
||||||
fn handle(&mut self, msg: DefineNetwork, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, mut msg: DefineNetwork, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
log::debug!("Define network: {:?}", msg.0);
|
log::debug!("Define network: {:?}", msg.1);
|
||||||
|
|
||||||
log::debug!("Source network structure: {:#?}", msg.0);
|
log::debug!("Source network structure: {:#?}", msg.1);
|
||||||
let network_xml = msg.0.into_xml()?;
|
let network_xml = msg.1.into_xml()?;
|
||||||
log::debug!("Define network XML: {network_xml}");
|
log::debug!("Define network XML: {network_xml}");
|
||||||
|
|
||||||
let network = Network::define_xml(&self.m, &network_xml)?;
|
let network = Network::define_xml(&self.m, &network_xml)?;
|
||||||
XMLUuid::parse_from_str(&network.get_uuid_string()?)
|
let uuid = XMLUuid::parse_from_str(&network.get_uuid_string()?)?;
|
||||||
|
|
||||||
|
// Save a copy of the source definition
|
||||||
|
msg.0.uuid = Some(uuid);
|
||||||
|
let json = serde_json::to_string(&msg.0)?;
|
||||||
|
std::fs::write(AppConfig::get().net_definition_path(&msg.0.name), json)?;
|
||||||
|
|
||||||
|
Ok(uuid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,7 +457,15 @@ impl Handler<DeleteNetwork> for LibVirtActor {
|
|||||||
fn handle(&mut self, msg: DeleteNetwork, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, msg: DeleteNetwork, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
log::debug!("Delete network: {}\n", msg.0.as_string());
|
log::debug!("Delete network: {}\n", msg.0.as_string());
|
||||||
let network = Network::lookup_by_uuid_string(&self.m, &msg.0.as_string())?;
|
let network = Network::lookup_by_uuid_string(&self.m, &msg.0.as_string())?;
|
||||||
|
let network_name = network.get_name()?;
|
||||||
network.undefine()?;
|
network.undefine()?;
|
||||||
|
|
||||||
|
// Remove backup definition
|
||||||
|
let backup_definition = AppConfig::get().net_definition_path(&network_name);
|
||||||
|
if backup_definition.exists() {
|
||||||
|
std::fs::remove_file(backup_definition)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,6 +240,18 @@ impl AppConfig {
|
|||||||
pub fn vm_storage_path(&self, id: XMLUuid) -> PathBuf {
|
pub fn vm_storage_path(&self, id: XMLUuid) -> PathBuf {
|
||||||
self.disks_storage_path().join(id.as_string())
|
self.disks_storage_path().join(id.as_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn definitions_path(&self) -> PathBuf {
|
||||||
|
self.storage_path().join("definitions")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vm_definition_path(&self, name: &str) -> PathBuf {
|
||||||
|
self.definitions_path().join(format!("vm-{name}.json"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn net_definition_path(&self, name: &str) -> PathBuf {
|
||||||
|
self.definitions_path().join(format!("net-{name}.json"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Serialize)]
|
#[derive(Debug, Clone, serde::Serialize)]
|
||||||
|
@ -10,7 +10,7 @@ pub struct NetworkID {
|
|||||||
|
|
||||||
/// Create a new network
|
/// Create a new network
|
||||||
pub async fn create(client: LibVirtReq, req: web::Json<NetworkInfo>) -> HttpResult {
|
pub async fn create(client: LibVirtReq, req: web::Json<NetworkInfo>) -> HttpResult {
|
||||||
let network = match req.0.to_virt_network() {
|
let network = match req.0.as_virt_network() {
|
||||||
Ok(d) => d,
|
Ok(d) => d,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Failed to extract network info! {e}");
|
log::error!("Failed to extract network info! {e}");
|
||||||
@ -20,7 +20,7 @@ pub async fn create(client: LibVirtReq, req: web::Json<NetworkInfo>) -> HttpResu
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let uid = match client.update_network(network).await {
|
let uid = match client.update_network(req.0, network).await {
|
||||||
Ok(u) => u,
|
Ok(u) => u,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Failed to update network! {e}");
|
log::error!("Failed to update network! {e}");
|
||||||
@ -71,7 +71,7 @@ pub async fn update(
|
|||||||
path: web::Path<NetworkID>,
|
path: web::Path<NetworkID>,
|
||||||
body: web::Json<NetworkInfo>,
|
body: web::Json<NetworkInfo>,
|
||||||
) -> HttpResult {
|
) -> HttpResult {
|
||||||
let mut network = match body.0.to_virt_network() {
|
let mut network = match body.0.as_virt_network() {
|
||||||
Ok(n) => n,
|
Ok(n) => n,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Failed to extract network info! {e}");
|
log::error!("Failed to extract network info! {e}");
|
||||||
@ -82,7 +82,7 @@ pub async fn update(
|
|||||||
};
|
};
|
||||||
network.uuid = Some(path.uid);
|
network.uuid = Some(path.uid);
|
||||||
|
|
||||||
if let Err(e) = client.update_network(network).await {
|
if let Err(e) = client.update_network(body.0, network).await {
|
||||||
log::error!("Failed to update network! {e}");
|
log::error!("Failed to update network! {e}");
|
||||||
return Ok(
|
return Ok(
|
||||||
HttpResponse::InternalServerError().json(format!("Failed to update network!\n${e}"))
|
HttpResponse::InternalServerError().json(format!("Failed to update network!\n${e}"))
|
||||||
|
@ -20,7 +20,7 @@ struct VMUuid {
|
|||||||
|
|
||||||
/// Create a new VM
|
/// Create a new VM
|
||||||
pub async fn create(client: LibVirtReq, req: web::Json<VMInfo>) -> HttpResult {
|
pub async fn create(client: LibVirtReq, req: web::Json<VMInfo>) -> HttpResult {
|
||||||
let domain = match req.0.to_domain() {
|
let domain = match req.0.as_tomain() {
|
||||||
Ok(d) => d,
|
Ok(d) => d,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Failed to extract domain info! {e}");
|
log::error!("Failed to extract domain info! {e}");
|
||||||
@ -29,7 +29,7 @@ pub async fn create(client: LibVirtReq, req: web::Json<VMInfo>) -> HttpResult {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let id = match client.update_domain(domain).await {
|
let id = match client.update_domain(req.0, domain).await {
|
||||||
Ok(i) => i,
|
Ok(i) => i,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Failed to update domain info! {e}");
|
log::error!("Failed to update domain info! {e}");
|
||||||
@ -111,13 +111,13 @@ pub async fn update(
|
|||||||
id: web::Path<SingleVMUUidReq>,
|
id: web::Path<SingleVMUUidReq>,
|
||||||
req: web::Json<VMInfo>,
|
req: web::Json<VMInfo>,
|
||||||
) -> HttpResult {
|
) -> HttpResult {
|
||||||
let mut domain = req.0.to_domain().map_err(|e| {
|
let mut domain = req.0.as_tomain().map_err(|e| {
|
||||||
log::error!("Failed to extract domain info! {e}");
|
log::error!("Failed to extract domain info! {e}");
|
||||||
HttpResponse::BadRequest().json(format!("Failed to extract domain info! {e}"))
|
HttpResponse::BadRequest().json(format!("Failed to extract domain info! {e}"))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
domain.uuid = Some(id.uid);
|
domain.uuid = Some(id.uid);
|
||||||
if let Err(e) = client.update_domain(domain).await {
|
if let Err(e) = client.update_domain(req.0, domain).await {
|
||||||
log::error!("Failed to update domain info! {e}");
|
log::error!("Failed to update domain info! {e}");
|
||||||
return Ok(HttpResponse::BadRequest().json(format!("Failed to update domain info!\n{e}")));
|
return Ok(HttpResponse::BadRequest().json(format!("Failed to update domain info!\n{e}")));
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::actors::libvirt_actor;
|
use crate::actors::libvirt_actor;
|
||||||
use crate::actors::libvirt_actor::LibVirtActor;
|
use crate::actors::libvirt_actor::LibVirtActor;
|
||||||
use crate::libvirt_lib_structures::{DomainState, DomainXML, NetworkXML, XMLUuid};
|
use crate::libvirt_lib_structures::{DomainState, DomainXML, NetworkXML, XMLUuid};
|
||||||
use crate::libvirt_rest_structures::HypervisorInfo;
|
use crate::libvirt_rest_structures::{HypervisorInfo, NetworkInfo, VMInfo};
|
||||||
use actix::Addr;
|
use actix::Addr;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -36,8 +36,10 @@ impl LibVirtClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Update a domain
|
/// Update a domain
|
||||||
pub async fn update_domain(&self, xml: DomainXML) -> anyhow::Result<XMLUuid> {
|
pub async fn update_domain(&self, vm_def: VMInfo, xml: DomainXML) -> anyhow::Result<XMLUuid> {
|
||||||
self.0.send(libvirt_actor::DefineDomainReq(xml)).await?
|
self.0
|
||||||
|
.send(libvirt_actor::DefineDomainReq(vm_def, xml))
|
||||||
|
.await?
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete a domain
|
/// Delete a domain
|
||||||
@ -100,8 +102,14 @@ impl LibVirtClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Update a network configuration
|
/// Update a network configuration
|
||||||
pub async fn update_network(&self, network: NetworkXML) -> anyhow::Result<XMLUuid> {
|
pub async fn update_network(
|
||||||
self.0.send(libvirt_actor::DefineNetwork(network)).await?
|
&self,
|
||||||
|
net_def: NetworkInfo,
|
||||||
|
network: NetworkXML,
|
||||||
|
) -> anyhow::Result<XMLUuid> {
|
||||||
|
self.0
|
||||||
|
.send(libvirt_actor::DefineNetwork(net_def, network))
|
||||||
|
.await?
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the full list of networks
|
/// Get the full list of networks
|
||||||
|
@ -108,7 +108,7 @@ pub struct VMInfo {
|
|||||||
|
|
||||||
impl VMInfo {
|
impl VMInfo {
|
||||||
/// Turn this VM into a domain
|
/// Turn this VM into a domain
|
||||||
pub fn to_domain(self) -> anyhow::Result<DomainXML> {
|
pub fn as_tomain(&self) -> anyhow::Result<DomainXML> {
|
||||||
if !regex!("^[a-zA-Z0-9]+$").is_match(&self.name) {
|
if !regex!("^[a-zA-Z0-9]+$").is_match(&self.name) {
|
||||||
return Err(StructureExtraction("VM name is invalid!").into());
|
return Err(StructureExtraction("VM name is invalid!").into());
|
||||||
}
|
}
|
||||||
@ -207,7 +207,7 @@ impl VMInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply disks configuration
|
// Apply disks configuration
|
||||||
for disk in self.disks {
|
for disk in &self.disks {
|
||||||
disk.check_config()?;
|
disk.check_config()?;
|
||||||
disk.apply_config(uuid)?;
|
disk.apply_config(uuid)?;
|
||||||
|
|
||||||
@ -242,28 +242,34 @@ impl VMInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut networks = vec![];
|
let mut networks = vec![];
|
||||||
for n in self.networks {
|
for n in &self.networks {
|
||||||
networks.push(match n.r#type {
|
networks.push(match &n.r#type {
|
||||||
NetworkType::UserspaceSLIRPStack => DomainNetInterfaceXML {
|
NetworkType::UserspaceSLIRPStack => DomainNetInterfaceXML {
|
||||||
mac: NetMacAddress { address: n.mac },
|
mac: NetMacAddress {
|
||||||
|
address: n.mac.to_string(),
|
||||||
|
},
|
||||||
r#type: "user".to_string(),
|
r#type: "user".to_string(),
|
||||||
source: None,
|
source: None,
|
||||||
},
|
},
|
||||||
NetworkType::DefinedNetwork { network } => DomainNetInterfaceXML {
|
NetworkType::DefinedNetwork { network } => DomainNetInterfaceXML {
|
||||||
mac: NetMacAddress { address: n.mac },
|
mac: NetMacAddress {
|
||||||
|
address: n.mac.to_string(),
|
||||||
|
},
|
||||||
r#type: "network".to_string(),
|
r#type: "network".to_string(),
|
||||||
source: Some(NetIntSourceXML { network }),
|
source: Some(NetIntSourceXML {
|
||||||
|
network: network.to_string(),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(DomainXML {
|
Ok(DomainXML {
|
||||||
r#type: "kvm".to_string(),
|
r#type: "kvm".to_string(),
|
||||||
name: self.name,
|
name: self.name.to_string(),
|
||||||
uuid: Some(uuid),
|
uuid: Some(uuid),
|
||||||
genid: self.genid.map(|i| i.0),
|
genid: self.genid.map(|i| i.0),
|
||||||
title: self.title,
|
title: self.title.clone(),
|
||||||
description: self.description,
|
description: self.description.clone(),
|
||||||
|
|
||||||
os: OSXML {
|
os: OSXML {
|
||||||
r#type: OSTypeXML {
|
r#type: OSTypeXML {
|
||||||
@ -487,8 +493,8 @@ pub struct IPV6Config {
|
|||||||
/// Network configuration
|
/// Network configuration
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
|
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
|
||||||
pub struct NetworkInfo {
|
pub struct NetworkInfo {
|
||||||
name: String,
|
pub name: String,
|
||||||
uuid: Option<XMLUuid>,
|
pub uuid: Option<XMLUuid>,
|
||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
forward_mode: NetworkForwardMode,
|
forward_mode: NetworkForwardMode,
|
||||||
@ -501,7 +507,7 @@ pub struct NetworkInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkInfo {
|
impl NetworkInfo {
|
||||||
pub fn to_virt_network(self) -> anyhow::Result<NetworkXML> {
|
pub fn as_virt_network(&self) -> anyhow::Result<NetworkXML> {
|
||||||
if !regex!("^[a-zA-Z0-9]+$").is_match(&self.name) {
|
if !regex!("^[a-zA-Z0-9]+$").is_match(&self.name) {
|
||||||
return Err(StructureExtraction("network name is invalid!").into());
|
return Err(StructureExtraction("network name is invalid!").into());
|
||||||
}
|
}
|
||||||
@ -532,7 +538,7 @@ impl NetworkInfo {
|
|||||||
|
|
||||||
let mut ips = Vec::with_capacity(2);
|
let mut ips = Vec::with_capacity(2);
|
||||||
|
|
||||||
if let Some(ipv4) = self.ip_v4 {
|
if let Some(ipv4) = &self.ip_v4 {
|
||||||
if ipv4.prefix > 32 {
|
if ipv4.prefix > 32 {
|
||||||
return Err(StructureExtraction("IPv4 prefix is invalid!").into());
|
return Err(StructureExtraction("IPv4 prefix is invalid!").into());
|
||||||
}
|
}
|
||||||
@ -545,17 +551,17 @@ impl NetworkInfo {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.mask()
|
.mask()
|
||||||
.into(),
|
.into(),
|
||||||
dhcp: ipv4.dhcp.map(|dhcp| NetworkDHCPXML {
|
dhcp: ipv4.dhcp.as_ref().map(|dhcp| NetworkDHCPXML {
|
||||||
range: NetworkDHCPRangeXML {
|
range: NetworkDHCPRangeXML {
|
||||||
start: IpAddr::V4(dhcp.start),
|
start: IpAddr::V4(dhcp.start),
|
||||||
end: IpAddr::V4(dhcp.end),
|
end: IpAddr::V4(dhcp.end),
|
||||||
},
|
},
|
||||||
hosts: dhcp
|
hosts: dhcp
|
||||||
.hosts
|
.hosts
|
||||||
.into_iter()
|
.iter()
|
||||||
.map(|c| NetworkDHCPHostXML {
|
.map(|c| NetworkDHCPHostXML {
|
||||||
mac: c.mac,
|
mac: c.mac.to_string(),
|
||||||
name: c.name,
|
name: c.name.to_string(),
|
||||||
ip: c.ip.into(),
|
ip: c.ip.into(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
@ -563,7 +569,7 @@ impl NetworkInfo {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ipv6) = self.ip_v6 {
|
if let Some(ipv6) = &self.ip_v6 {
|
||||||
ips.push(NetworkIPXML {
|
ips.push(NetworkIPXML {
|
||||||
family: "ipv6".to_string(),
|
family: "ipv6".to_string(),
|
||||||
address: IpAddr::V6(ipv6.bridge_address),
|
address: IpAddr::V6(ipv6.bridge_address),
|
||||||
@ -572,17 +578,17 @@ impl NetworkInfo {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.mask()
|
.mask()
|
||||||
.into(),
|
.into(),
|
||||||
dhcp: ipv6.dhcp.map(|dhcp| NetworkDHCPXML {
|
dhcp: ipv6.dhcp.as_ref().map(|dhcp| NetworkDHCPXML {
|
||||||
range: NetworkDHCPRangeXML {
|
range: NetworkDHCPRangeXML {
|
||||||
start: IpAddr::V6(dhcp.start),
|
start: IpAddr::V6(dhcp.start),
|
||||||
end: IpAddr::V6(dhcp.end),
|
end: IpAddr::V6(dhcp.end),
|
||||||
},
|
},
|
||||||
hosts: dhcp
|
hosts: dhcp
|
||||||
.hosts
|
.hosts
|
||||||
.into_iter()
|
.iter()
|
||||||
.map(|h| NetworkDHCPHostXML {
|
.map(|h| NetworkDHCPHostXML {
|
||||||
mac: "".to_string(),
|
mac: "".to_string(),
|
||||||
name: h.name,
|
name: h.name.to_string(),
|
||||||
ip: h.ip.into(),
|
ip: h.ip.into(),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
@ -591,24 +597,24 @@ impl NetworkInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(NetworkXML {
|
Ok(NetworkXML {
|
||||||
name: self.name,
|
name: self.name.to_string(),
|
||||||
uuid: self.uuid,
|
uuid: self.uuid,
|
||||||
title: self.title,
|
title: self.title.clone(),
|
||||||
description: self.description,
|
description: self.description.clone(),
|
||||||
forward: match self.forward_mode {
|
forward: match self.forward_mode {
|
||||||
NetworkForwardMode::NAT => Some(NetworkForwardXML {
|
NetworkForwardMode::NAT => Some(NetworkForwardXML {
|
||||||
mode: "nat".to_string(),
|
mode: "nat".to_string(),
|
||||||
dev: self.device.unwrap_or_default(),
|
dev: self.device.clone().unwrap_or_default(),
|
||||||
}),
|
}),
|
||||||
NetworkForwardMode::Isolated => None,
|
NetworkForwardMode::Isolated => None,
|
||||||
},
|
},
|
||||||
bridge: self.bridge_name.map(|b| NetworkBridgeXML {
|
bridge: self.bridge_name.clone().map(|b| NetworkBridgeXML {
|
||||||
name: b.to_string(),
|
name: b.to_string(),
|
||||||
}),
|
}),
|
||||||
dns: self.dns_server.map(|addr| NetworkDNSXML {
|
dns: self.dns_server.map(|addr| NetworkDNSXML {
|
||||||
forwarder: NetworkDNSForwarderXML { addr },
|
forwarder: NetworkDNSForwarderXML { addr },
|
||||||
}),
|
}),
|
||||||
domain: self.domain.map(|name| NetworkDomainXML { name }),
|
domain: self.domain.clone().map(|name| NetworkDomainXML { name }),
|
||||||
ips,
|
ips,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ async fn main() -> std::io::Result<()> {
|
|||||||
files_utils::create_directory_if_missing(AppConfig::get().vnc_sockets_path()).unwrap();
|
files_utils::create_directory_if_missing(AppConfig::get().vnc_sockets_path()).unwrap();
|
||||||
files_utils::set_file_permission(AppConfig::get().vnc_sockets_path(), 0o777).unwrap();
|
files_utils::set_file_permission(AppConfig::get().vnc_sockets_path(), 0o777).unwrap();
|
||||||
files_utils::create_directory_if_missing(AppConfig::get().disks_storage_path()).unwrap();
|
files_utils::create_directory_if_missing(AppConfig::get().disks_storage_path()).unwrap();
|
||||||
|
files_utils::create_directory_if_missing(AppConfig::get().definitions_path()).unwrap();
|
||||||
|
|
||||||
let conn = Data::new(LibVirtClient(
|
let conn = Data::new(LibVirtClient(
|
||||||
LibVirtActor::connect()
|
LibVirtActor::connect()
|
||||||
|
Loading…
Reference in New Issue
Block a user