machines/rust/program/zpool-setup/src/cli.rs
Kaare Hoff Skovgaard 5abaa9322e
Some checks failed
/ dev-shell (push) Successful in 49s
/ terraform-providers (push) Successful in 59s
/ rust-packages (push) Successful in 1m2s
/ check (push) Failing after 3m6s
/ systems (push) Successful in 4m28s
Attempt to get merging of zfs options in zpool setup working
I have not yet tested addition of new datasets, or the removal/
unmounting of newly disappeared datasets.
2025-08-07 22:32:18 +02:00

124 lines
2.8 KiB
Rust

use std::{borrow::Cow, collections::BTreeMap, ops::Deref, path::PathBuf, str::FromStr};
use serde::{Deserialize, Serialize};
use crate::disk_mapping::DiskMapping;
#[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
pub enum VdevMode {
#[serde(rename = "mirror")]
Mirror,
#[serde(rename = "raidz")]
Raidz,
#[serde(rename = "raidz1")]
Raidz1,
#[serde(rename = "raidz2")]
Raidz2,
#[serde(rename = "raidz3")]
Raidz3,
}
impl VdevMode {
fn str(&self) -> &'static str {
match self {
Self::Mirror => "mirror",
Self::Raidz => "raidz",
Self::Raidz1 => "raidz1",
Self::Raidz2 => "raidz2",
Self::Raidz3 => "raidz3",
}
}
}
#[derive(Clone, Debug, Deserialize)]
pub struct Vdev {
pub mode: VdevMode,
pub members: Vec<String>,
}
impl Vdev {
pub fn cli_args(&self, disk_mapper: &DiskMapping) -> anyhow::Result<Vec<Cow<'static, str>>> {
let mut args = Vec::with_capacity(self.members.len() + 1);
if self.members.len() > 1 || self.mode != VdevMode::Mirror {
args.push(Cow::Borrowed(self.mode.str()));
}
for member in self.members.iter() {
let resolved = disk_mapper.resolve(member)?;
args.push(resolved.into());
}
Ok(args)
}
}
#[derive(Clone, Debug, Deserialize)]
#[serde(transparent)]
pub struct Vdevs(Vec<Vdev>);
impl FromStr for Vdevs {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
common::json::from_str(s)
}
}
impl Deref for Vdevs {
type Target = Vec<Vdev>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
#[serde(transparent)]
pub struct Options(BTreeMap<String, String>);
impl FromStr for Options {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
common::json::from_str(s)
}
}
impl Deref for Options {
type Target = BTreeMap<String, String>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
pub struct Dataset {
pub options: Options,
pub mountpoint: Option<PathBuf>,
}
impl Dataset {
pub fn without_mountpoint(&self) -> Dataset {
Self {
mountpoint: None,
options: self.options.clone(),
}
}
pub fn with_options(options: &Options) -> Self {
Self {
mountpoint: None,
options: options.clone(),
}
}
}
#[derive(Clone, Debug, Deserialize)]
#[serde(transparent)]
pub struct Datasets(pub BTreeMap<String, Dataset>);
impl FromStr for Datasets {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
common::json::from_str(s)
}
}