diff options
Diffstat (limited to 'zone_zfs/src/zfs.rs')
-rw-r--r-- | zone_zfs/src/zfs.rs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/zone_zfs/src/zfs.rs b/zone_zfs/src/zfs.rs new file mode 100644 index 0000000..7f34951 --- /dev/null +++ b/zone_zfs/src/zfs.rs @@ -0,0 +1,60 @@ +use figment::{Figment, Provider}; +use std::path::PathBuf; +use std::process::Command; + +use crate::{Config, Error, FileSystem, Result}; + +#[derive(Default, Debug)] +pub struct ZFS { + pub config: Config, +} + +impl ZFS { + pub fn new() -> Result<Self> { + Self::custom(Config::figment()) + } + + pub fn custom<T: Provider>(provider: T) -> Result<Self> { + Config::from(Figment::from(provider)) + .map_err(Error::from) + .map(|config| Self { config }) + } + + pub fn clone_from_latest(&self, name: PathBuf, parent: PathBuf) -> Result<FileSystem> { + Self::get_file_system(parent)? + .get_latest_snapshot()? + .ok_or_else(|| Error::Snapshot("No snapshot found".into()))? + .clone_into_file_system(name)? + .set_quota(self.config.quota) + } + + pub(super) fn get_file_systems() -> Result<Vec<FileSystem>> { + Command::new("zfs") + .arg("list") + .arg("-H") + .arg("-o") + .arg("name") + .output() + .map(|o| String::from_utf8(o.stdout))? + .map_err(|err| Error::FileSystem(format!("Failed to parse command output: {:?}", err)))? + .split_whitespace() + .map(FileSystem::try_from) + .collect() + } + + fn get_file_system(name: PathBuf) -> Result<FileSystem> { + Self::get_file_systems()? + .into_iter() + .find(|fs| PathBuf::from(&fs.value).ends_with(&name)) + .ok_or_else(|| Error::FileSystem("No file system found".into())) + } +} + +#[cfg(test)] +mod tests { + #[test] + fn zfs_list() { + use super::*; + assert!(ZFS::get_file_systems().is_ok()); + } +} |