aboutsummaryrefslogtreecommitdiffstats
path: root/zone_zfs/src/zfs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'zone_zfs/src/zfs.rs')
-rw-r--r--zone_zfs/src/zfs.rs60
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());
+ }
+}