aboutsummaryrefslogblamecommitdiff
path: root/src/waifu.rs
blob: bb99d2b9d4ce89afc53858f39b43ec70e3d37500 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                          
                           



                                    



                                           
                           





                             
 



                                          
                             





                             











                                                             



                     




                                                             
                    

                                                    
                            

 





                                        








































                                                                                                
                                 

                       
                                                          




                                   

                                           





















                                                                                                


                                                 


          
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<u64> 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<u64> 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<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(),
        })
    }
}