aboutsummaryrefslogtreecommitdiff
path: root/src/planet.rs
diff options
context:
space:
mode:
authorCara Salter <cara@devcara.com>2022-05-26 16:36:41 -0400
committerCara Salter <cara@devcara.com>2022-05-26 16:37:20 -0400
commit77fa95a342f09953e3207ea0346135301ffe2664 (patch)
tree5a53f154671a54993bafbfd904a6c447d486d45c /src/planet.rs
parentee9be2d32e47a998858219362dd42f927aa8ce42 (diff)
downloadsolarlib-77fa95a342f09953e3207ea0346135301ffe2664.tar.gz
solarlib-77fa95a342f09953e3207ea0346135301ffe2664.zip
Project rename1.2.1
Diffstat (limited to 'src/planet.rs')
-rw-r--r--src/planet.rs179
1 files changed, 179 insertions, 0 deletions
diff --git a/src/planet.rs b/src/planet.rs
new file mode 100644
index 0000000..c29fb69
--- /dev/null
+++ b/src/planet.rs
@@ -0,0 +1,179 @@
+use std::convert::TryFrom;
+use virt::{domain::{Domain, DomainState}};
+use serde::{Serialize, Deserialize};
+
+use crate::errors::Error;
+
+/**
+ * Defines the amount of memory a planet 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 planet 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 [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 Planet {
+ /// 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,
+
+ #[serde(skip)]
+ domain: Option<Domain>,
+}
+
+impl PartialEq for Planet {
+ fn eq(&self, other: &Self) -> bool {
+ self.uuid == other.uuid
+ }
+}
+
+impl TryFrom<Domain> for Planet {
+ 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(),
+ domain: Some(d),
+ })
+ }
+}
+
+
+impl TryFrom<&Domain> for Planet {
+ 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(),
+ 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)
+ }
+}