summaryrefslogtreecommitdiff
path: root/src/libvirt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libvirt.rs')
-rw-r--r--src/libvirt.rs100
1 files changed, 84 insertions, 16 deletions
diff --git a/src/libvirt.rs b/src/libvirt.rs
index 2162f3c..e65ea1e 100644
--- a/src/libvirt.rs
+++ b/src/libvirt.rs
@@ -13,9 +13,45 @@ use virt::domain::{
/// Errors from this module.
#[derive(Debug, thiserror::Error)]
pub enum VirtError {
- /// Error creating virtual machine.
- #[error(transparent)]
- VirtError(#[from] virt::error::Error),
+ /// Error connecting to libvirtd.
+ #[error("couldn't connect to the libvirt daemon")]
+ Connect(#[source] virt::error::Error),
+
+ /// Error listing domains.
+ #[error("couldn't list all domains")]
+ Domains(#[source] virt::error::Error),
+
+ /// Error listing domains.
+ #[error("couldn't get name of domain")]
+ GetName(#[source] virt::error::Error),
+
+ /// Error checking if domain is active.
+ #[error("couldn't check is domain {0} is active")]
+ IsActive(String, #[source] virt::error::Error),
+
+ /// Error getting domain's XML description.
+ #[error("couldn't get domain's XML description: {0}")]
+ GetXml(String, #[source] virt::error::Error),
+
+ /// Error detaching cloud-init ISO from domain
+ #[error("couldn't detach cloud-init ISO file from domain {0}")]
+ DetachIso(String, #[source] virt::error::Error),
+
+ /// Error detaching drive from domain
+ #[error("couldn't create domain {0}")]
+ Create(String, #[source] virt::error::Error),
+
+ /// Error shutting down domain
+ #[error("couldn't shut down domain {0}")]
+ Shutdown(String, #[source] virt::error::Error),
+
+ /// Error undefining domain
+ #[error("couldn't undefine domain {0}")]
+ Undefine(String, #[source] virt::error::Error),
+
+ /// Error undefining domain
+ #[error("couldn't set domain {0} to be autostarted")]
+ Autostart(String, #[source] virt::error::Error),
/// Error doing I/O.
#[error(transparent)]
@@ -30,18 +66,21 @@ pub struct Libvirt {
impl Libvirt {
pub fn connect(url: &str) -> Result<Self, VirtError> {
debug!("connecting to libvirtd {}", url);
- let conn = Connect::open(url)?;
+ let conn = Connect::open(url).map_err(|err| VirtError::Connect(err))?;
Ok(Self { conn })
}
fn get_domains(&self) -> Result<Vec<Domain>, VirtError> {
debug!("listing all domains");
- Ok(self.conn.list_all_domains(0)?)
+ Ok(self
+ .conn
+ .list_all_domains(0)
+ .map_err(|err| VirtError::Domains(err))?)
}
fn get_domain(&self, name: &str) -> Result<Option<Domain>, VirtError> {
for domain in self.get_domains()? {
- if domain.get_name()? == name {
+ if get_name(&domain)? == name {
return Ok(Some(domain));
}
}
@@ -51,14 +90,14 @@ impl Libvirt {
pub fn names(&self) -> Result<Vec<String>, VirtError> {
let mut ret = vec![];
for domain in self.get_domains()? {
- ret.push(domain.get_name()?);
+ ret.push(get_name(&domain)?);
}
Ok(ret)
}
pub fn is_active(&self, name: &str) -> Result<bool, VirtError> {
if let Some(domain) = self.get_domain(name)? {
- Ok(domain.is_active()?)
+ Ok(is_active(&domain, name)?)
} else {
Ok(false)
}
@@ -76,12 +115,14 @@ impl Libvirt {
pub fn detach_cloud_init_iso(&self, name: &str) -> Result<(), VirtError> {
if let Some(domain) = self.get_domain(name)? {
debug!("detaching cloud-init ISO from {}", name);
- let xml = domain.get_xml_desc(0)?;
+ let xml = get_xml(&domain, name)?;
let disk = find_iso_xml(&xml);
let flags =
VIR_DOMAIN_AFFECT_CONFIG | VIR_DOMAIN_AFFECT_CURRENT | VIR_DOMAIN_AFFECT_LIVE;
if disk.len() > 0 {
- domain.detach_device_flags(&disk, flags)?;
+ domain
+ .detach_device_flags(&disk, flags)
+ .map_err(|err| VirtError::DetachIso(name.to_string(), err))?;
}
}
Ok(())
@@ -89,9 +130,11 @@ impl Libvirt {
pub fn trigger_start(&self, name: &str) -> Result<(), VirtError> {
if let Some(domain) = self.get_domain(name)? {
- if !domain.is_active()? {
+ if !is_active(&domain, name)? {
debug!("starting {}", name);
- domain.create()?;
+ domain
+ .create()
+ .map_err(|err| VirtError::Create(name.to_string(), err))?;
}
}
Ok(())
@@ -108,8 +151,10 @@ impl Libvirt {
pub fn trigger_shutdown(&self, name: &str) -> Result<(), VirtError> {
if let Some(domain) = self.get_domain(name)? {
debug!("asking {} to shut down", name);
- if domain.is_active()? {
- domain.shutdown()?;
+ if is_active(&domain, name)? {
+ domain
+ .shutdown()
+ .map_err(|err| VirtError::Shutdown(name.to_string(), err))?;
}
}
Ok(())
@@ -129,7 +174,9 @@ impl Libvirt {
self.shutdown(name)?;
debug!("undefine {}", name);
- domain.undefine()?;
+ domain
+ .undefine()
+ .map_err(|err| VirtError::Undefine(name.to_string(), err))?;
debug!("removing image file {}", image.display());
std::fs::remove_file(image)?;
@@ -140,12 +187,33 @@ impl Libvirt {
pub fn set_autostart(&self, name: &str, autostart: bool) -> Result<(), VirtError> {
if let Some(domain) = self.get_domain(name)? {
- domain.set_autostart(autostart)?;
+ domain
+ .set_autostart(autostart)
+ .map_err(|err| VirtError::Autostart(name.to_string(), err))?;
}
Ok(())
}
}
+fn get_name(domain: &Domain) -> Result<String, VirtError> {
+ let name = domain.get_name().map_err(|err| VirtError::GetName(err))?;
+ Ok(name)
+}
+
+fn is_active(domain: &Domain, name: &str) -> Result<bool, VirtError> {
+ let is = domain
+ .is_active()
+ .map_err(|err| VirtError::IsActive(name.to_string(), err))?;
+ Ok(is)
+}
+
+fn get_xml(domain: &Domain, name: &str) -> Result<String, VirtError> {
+ let is = domain
+ .get_xml_desc(0)
+ .map_err(|err| VirtError::GetXml(name.to_string(), err))?;
+ Ok(is)
+}
+
fn wait_until_inactive(domain: &Domain, name: &str) {
debug!("waiting for domain {} to become inactive", name);
let briefly = Duration::from_millis(1000);