use std::convert::TryFrom; use virt::{domain::Domain}; use serde::{Serialize, Deserialize}; use crate::errors::Error; /** * Defines the amount of memory a waifu has */ #[derive(Debug, Serialize, Deserialize)] pub struct Memory(pub u64); impl From for Memory { fn from(u: u64) -> Self { Self(u) } } /** * Defines the number of vCPUs a waifu has */ #[derive(Debug, Serialize, Deserialize)] pub struct CpuCount(pub u64); impl From for CpuCount { fn from(u: u64) -> Self { Self(u) } } /** * Represents a virtual machine, that's active on some server * * In keeping with the theme, it's named [Waifu] :) */ #[derive(Debug, Serialize, Deserialize)] pub struct Waifu { /// The reference name of the machine pub name: String, /// The physical machine where this one lives pub host: String, /// The UUID pub uuid: String, /// The network address where this machine can be reached pub addr: Option, /// The amount of RAM (in MB) assigned to this machine pub mem: Memory, /// The amount of vCPUs assigned to this machine pub cpu_count: CpuCount, } impl PartialEq for Waifu { fn eq(&self, other: &Self) -> bool { self.uuid == other.uuid } } impl TryFrom for Waifu { type Error = Error; fn try_from(d: Domain) -> Result { let c = d.get_connect()?; // This... feels wrong // // I know it probably works // // Based on code by Cadey in waifud let addr: Option = if d.is_active()? { let mut addr: Vec = d .interface_addresses(virt::domain::VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE, 0)? .into_iter() .map(|iface| iface.addrs.clone()) .filter(|addrs| addrs.get(0).is_some()) .map(|addrs| addrs.get(0).unwrap().clone().addr) .collect(); if addr.get(0).is_none() { Some(String::from("localhost")) } else { Some(addr.swap_remove(0)) } } else { None }; Ok(Self { name: d.get_name()?, host: c.get_hostname()?, addr, uuid: d.get_uuid_string()?, mem: d.get_max_memory()?.into(), cpu_count: d.get_max_vcpus()?.into(), }) } } impl TryFrom<&Domain> for Waifu { type Error = Error; fn try_from(d: &Domain) -> Result { let c = d.get_connect()?; // This... feels wrong // // I know it probably works // // Based on code by Cadey in waifud let addr: Option = if d.is_active()? { let mut addr: Vec = d .interface_addresses(virt::domain::VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE, 0)? .into_iter() .map(|iface| iface.addrs.clone()) .filter(|addrs| addrs.get(0).is_some()) .map(|addrs| addrs.get(0).unwrap().clone().addr) .collect(); if addr.get(0).is_none() { Some(String::from("localhost")) } else { Some(addr.swap_remove(0)) } } else { None }; Ok(Self { name: d.get_name()?, host: c.get_hostname()?, addr, uuid: d.get_uuid_string()?, mem: d.get_max_memory()?.into(), cpu_count: d.get_max_vcpus()?.into(), }) } }