aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml4
-rw-r--r--README.md5
-rw-r--r--flake.nix2
-rw-r--r--src/lib.rs6
-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
7 files changed, 112 insertions, 65 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 9f0bfea..fc1b885 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
-name = "waifulib"
-version = "0.2.1"
+name = "solarlib"
+version = "1.2.1"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/README.md b/README.md
index 89bf1f8..250d3aa 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,3 @@
-# Waifulib
+# Solarlib
-Inspired by [github:Xe/waifud](https://github.com/Xe/waifud) but in more of a
-library form, so it can be used in other projects too.
+Representing virtual machines as solar systems
diff --git a/flake.nix b/flake.nix
index 568bf22..415d277 100644
--- a/flake.nix
+++ b/flake.nix
@@ -17,7 +17,7 @@
rec {
# `nix build`
packages.waifulib = naersk-lib.buildPackage {
- pname = "waifulib";
+ pname = "solarlib";
root = ./.;
buildInputs = build-inputs;
};
diff --git a/src/lib.rs b/src/lib.rs
index 0518b63..75e7c77 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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)
+ }
+}
diff --git a/src/van.rs b/src/ship.rs
index 64e7295..79253e1 100644
--- a/src/van.rs
+++ b/src/ship.rs
@@ -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")