diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 6 | ||||
-rw-r--r-- | src/planet.rs (renamed from src/waifu.rs) | 53 | ||||
-rw-r--r-- | src/ship.rs (renamed from src/van.rs) | 54 | ||||
-rw-r--r-- | src/star.rs (renamed from src/house.rs) | 53 |
4 files changed, 107 insertions, 59 deletions
@@ -1,9 +1,9 @@ pub mod errors; -pub mod waifu; +pub mod planet; -pub mod house; +pub mod star; -pub mod van; +pub mod ship; include!(concat!(env!("OUT_DIR"), "/templates.rs")); diff --git a/src/waifu.rs b/src/planet.rs index bb99d2b..c29fb69 100644 --- a/src/waifu.rs +++ b/src/planet.rs @@ -1,11 +1,11 @@ use std::convert::TryFrom; -use virt::{domain::Domain}; +use virt::{domain::{Domain, DomainState}}; use serde::{Serialize, Deserialize}; use crate::errors::Error; /** - * Defines the amount of memory a waifu has + * Defines the amount of memory a planet has */ #[derive(Debug, Serialize, Deserialize)] pub struct Memory(pub u64); @@ -17,7 +17,7 @@ impl From<u64> for Memory { } /** - * Defines the number of vCPUs a waifu has + * Defines the number of vCPUs a planet has */ #[derive(Debug, Serialize, Deserialize)] pub struct CpuCount(pub u64); @@ -31,10 +31,14 @@ impl From<u64> for CpuCount { /** * Represents a virtual machine, that's active on some server * - * In keeping with the theme, it's named [Waifu] :) + * In keeping with the theme, it's named [Planet] :) + * + * There is a private `domain` field that contains a reference to the actual domain. This will not + * be (de)serialized, and, if needed across a network, should be recreated from the `host` and + * `uuid` attributes using [virt::domain::lookup_from_uuid_string] */ #[derive(Debug, Serialize, Deserialize)] -pub struct Waifu { +pub struct Planet { /// The reference name of the machine pub name: String, @@ -52,15 +56,18 @@ pub struct Waifu { /// The amount of vCPUs assigned to this machine pub cpu_count: CpuCount, + + #[serde(skip)] + domain: Option<Domain>, } -impl PartialEq for Waifu { +impl PartialEq for Planet { fn eq(&self, other: &Self) -> bool { self.uuid == other.uuid } } -impl TryFrom<Domain> for Waifu { +impl TryFrom<Domain> for Planet { type Error = Error; fn try_from(d: Domain) -> Result<Self, Self::Error> { @@ -96,12 +103,13 @@ impl TryFrom<Domain> for Waifu { uuid: d.get_uuid_string()?, mem: d.get_max_memory()?.into(), cpu_count: d.get_max_vcpus()?.into(), + domain: Some(d), }) } } -impl TryFrom<&Domain> for Waifu { +impl TryFrom<&Domain> for Planet { type Error = Error; fn try_from(d: &Domain) -> Result<Self, Self::Error> { @@ -137,6 +145,35 @@ impl TryFrom<&Domain> for Waifu { uuid: d.get_uuid_string()?, mem: d.get_max_memory()?.into(), cpu_count: d.get_max_vcpus()?.into(), + domain: Some(*d), }) } } + +#[repr(u32)] +#[derive(Serialize, Deserialize)] +pub enum Health { + Unknown = 0, + Running = 1, + Blocked = 2, + Paused = 3, + ShuttingDown = 4, + ShutDown = 5, + Crashed = 6, + GuestSuspended = 7 +} + +impl Planet { + fn get_status(&self) -> Result<Health, Error> { + let d = match self.domain { + Some(d) => d, + None => { + return Err(Error::Other(String::from("No domain connection found"))); + } + }; + + let state = d.get_state()?; + + Ok(state.0 as Health) + } +} @@ -1,13 +1,16 @@ -/*! A Van is a moving van, or an installation ISO */ +/*! A Ship is a star ship, or an installation ISO */ use tokio::process::Command; -use std::process::ExitStatus; +use std::process::{ExitStatus, Output}; use std::os::unix::process::ExitStatusExt; use std::str::FromStr; -use crate::errors::Error; +use crate::{errors::Error, star::Star}; + +use serde::{Serialize, Deserialize}; /// Describes a hash of a file +#[derive(Serialize, Deserialize)] pub struct Sha256(pub String); impl FromStr for Sha256 { @@ -25,8 +28,9 @@ impl ToString for Sha256 { } } -/// Describes a moving Van, or a way to install a distribution -pub struct Van { +/// Describes a starship, or a way to install a distribution +#[derive(Serialize, Deserialize)] +pub struct Ship { /// The common name of the distribution (e.g "Arch Linux") pub name: String, /// The SHA-256 hash of the downloaded file @@ -37,7 +41,7 @@ pub struct Van { pub version: String, } -impl Van { +impl Ship { pub fn new(name: String, shasum: String, download_url: String, @@ -51,18 +55,32 @@ impl Van { } } - pub async fn download(&self, target: String) -> Result<(), Error> { - let output = Command::new("ssh") - .args([ - "-oStrictHostKeyChecking=accept-new", - &target.clone(), - "wget", - "-O", - &self.download_url.clone(), - &format!("/var/lib/libvirt/images/{}", self.make_pretty_name().clone()) - ]) - .output() - .await?; + pub async fn download(&self, target: Star) -> Result<(), Error> { + + let mut output: Output; + + if target.remote { + output = Command::new("ssh") + .args([ + "-oStrictHostKeyChecking=accept-new", + &target.address.clone(), + "wget", + "-O", + &format!("/var/lib/libvirt/images/{}", self.make_pretty_name().clone()), + &self.download_url.clone(), + ]) + .output() + .await?; + } else { + output = Command::new("wget") + .args([ + "-O", + &format!("/var/lib/libvirt/images/{}", self.make_pretty_name().clone()), + &self.download_url.clone(), + ]) + .output() + .await?; + } if output.status != ExitStatus::from_raw(0) { Err(Error::RemoteCommand(String::from_utf8(output.stdout).unwrap())) diff --git a/src/house.rs b/src/star.rs index abd0eef..9cd9d14 100644 --- a/src/house.rs +++ b/src/star.rs @@ -1,10 +1,10 @@ /*! - * `House`s are where [crate::waifu::Waifu]s live (the physical hypervisors that + * `Star`s are where [crate::planet::Planet]s orbit (the physical hypervisors that * libvirtd connects to */ -use crate::waifu::*; +use crate::planet::*; use crate::errors::Error; -use crate::van::Van; +use crate::ship::Ship; use serde::{Serialize, Deserialize}; use virt::{connect::Connect, domain::Domain}; use std::process::{ExitStatus}; @@ -28,15 +28,15 @@ impl ToString for Address { } } -/// Defines a "house" where waifus live +/// Defines a "star" where [crate::planet::Planet]s orbit #[derive(Debug, Serialize, Deserialize)] -pub struct House { +pub struct Star { /// Hostname pub name: String, - /// FQDN or IP address, a way to talk to the house + /// FQDN or IP address, a way to talk to the planet pub address: String, - /// Whether or not the House is local (same machine) or remote (networked machine) + /// Whether or not the Planet is local (same machine) or remote (networked machine) pub remote: bool, /// Connection to the House, if available @@ -44,13 +44,13 @@ pub struct House { con: Option<Connect>, } -impl House { - /// Creates a new House based on a libvirtd connect URL +impl Star { + /// Creates a new Planet based on a libvirtd connect URL /// /// Example: /// ``` - /// use waifulib::house::House; - /// let mut h: House = House::new("test:///default".to_string()).unwrap(); + /// use waifulib::planet::Planet; + /// let mut h = Planet::new("test:///default".to_string()).unwrap(); /// ``` pub fn new(url: String) -> Result<Self, Error> { let c = Connect::open(&url.clone())?; @@ -73,22 +73,22 @@ impl House { /// Lists the "inhabitants" of the House (the [Waifu]s on the machine /// /// ``` - /// use waifulib::house::House; - /// let mut h: House = House::new("test:///default".to_string()).unwrap(); + /// use crate::star::Star; + /// let mut h = Star::new("test:///default".to_string()).unwrap(); /// /// assert_eq!(h.inhabitants().unwrap().len(), 1); /// ``` - pub fn inhabitants(&mut self) -> Result<Vec<Waifu>, Error> { + pub fn inhabitants(&mut self) -> Result<Vec<Planet>, Error> { match &self.con { Some(c) => { let domains = c.list_all_domains(0)?; - let mut waifus: Vec<Waifu> = Vec::new(); + let mut planets: Vec<Planet> = Vec::new(); for d in domains.iter() { - waifus.push(d.clone().try_into()?); + planets.push(d.clone().try_into()?); } - Ok(waifus) + Ok(planets) }, None => { return Err(Error::Connection("Domain connection was None".to_string())); @@ -96,20 +96,13 @@ impl House { } } - /// Introduces a new Waifu into the House, taking care of everything needed to make the VM run + /// Creates a new Planet orbiting the Star, taking care of everything needed to make the VM run /// fine /// /// If the installation image doesn't exist in the default libvirtd pool, this will fail with /// [`Error::MissingImage`][crate::errors::Error::MissingImage]. /// - /// ``` - /// use waifulib::house::House - /// - /// let mut h: House = House::new("test:///default".to_string()).unwrap(); - /// - /// h.introduce("test-2", 1024, 1, 20000, "test.iso").unwrap(); - /// ``` - pub async fn introduce(&mut self, name: String, max_mem: Memory, max_cpus: CpuCount, disk_size_mb: u64, van: Van) -> Result<Waifu, Error> { + pub async fn planet(&mut self, name: String, max_mem: Memory, max_cpus: CpuCount, disk_size_mb: u64, ship: Ship) -> Result<Planet, Error> { // Check for image on host machine if self.remote { @@ -118,13 +111,13 @@ impl House { "-oStrictHostKeyChecking=accept-new", &self.address.clone(), "stat", - &format!("/var/lib/libvirt/images/{}", van.make_pretty_name().clone()) + &format!("/var/lib/libvirt/images/{}", ship.make_pretty_name().clone()) ]) .output() .await?; if output.status != ExitStatus::from_raw(0) { - return Err(Error::MissingImage(van.name.clone())); + return Err(Error::MissingImage(ship.name.clone())); } // Allocate VM disk @@ -149,13 +142,13 @@ impl House { // It's local let mut output = Command::new("stat") .args([ - &format!("/var/lib/libvirt/images/{}", van.make_pretty_name().clone()), + &format!("/var/lib/libvirt/images/{}", ship.make_pretty_name().clone()), ]) .output() .await?; if output.status != ExitStatus::from_raw(0) { - return Err(Error::MissingImage(van.name.clone())); + return Err(Error::MissingImage(ship.name.clone())); } output = Command::new("qemu-img") |