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(u64);
impl From<u64> for Memory {
fn from(u: u64) -> Self {
Self(u)
}
}
impl Memory {
pub fn count(&self) -> u64 {
self.0
}
}
/**
* Defines the number of vCPUs a waifu has
*/
#[derive(Debug, Serialize, Deserialize)]
pub struct CpuCount(u64);
impl From<u64> for CpuCount {
fn from(u: u64) -> Self {
Self(u)
}
}
impl CpuCount {
pub fn count(&self) -> u64 {
self.0
}
}
/**
* 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<String>,
/// 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<Domain> for Waifu {
type Error = Error;
fn try_from(d: Domain) -> Result<Self, Self::Error> {
let c = d.get_connect()?;
// This... feels wrong
//
// I know it probably works
//
// Based on code by Cadey in waifud
let addr: Option<String> = if d.is_active()? {
let mut addr: Vec<String> = 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<Self, Self::Error> {
let c = d.get_connect()?;
// This... feels wrong
//
// I know it probably works
//
// Based on code by Cadey in waifud
let addr: Option<String> = if d.is_active()? {
let mut addr: Vec<String> = 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(),
})
}
}