103 lines
2.4 KiB
Rust
103 lines
2.4 KiB
Rust
use eyre::{Result, format_err};
|
|
use tokio::process::Command;
|
|
|
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
|
struct Report {
|
|
report: Vec<ReportObj>,
|
|
}
|
|
|
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
|
enum ReportObj {
|
|
#[serde(rename = "pv")]
|
|
PV(Vec<PV>),
|
|
#[serde(rename = "vg")]
|
|
VG(Vec<VG>),
|
|
#[serde(rename = "lv")]
|
|
LV(Vec<LV>),
|
|
}
|
|
|
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
|
pub struct PV {
|
|
pub pv_name: String,
|
|
pub vg_name: String,
|
|
pub pv_fmt: String,
|
|
pub pv_attr: String,
|
|
pub pv_size: String,
|
|
pub pv_free: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
|
pub struct VG {
|
|
pub vg_name: String,
|
|
pub pv_count: String,
|
|
pub lv_count: String,
|
|
pub snap_count: String,
|
|
pub vg_attr: String,
|
|
pub vg_size: String,
|
|
pub vg_free: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
|
pub struct LV {
|
|
pub lv_name: String,
|
|
pub vg_name: String,
|
|
pub lv_attr: String,
|
|
pub lv_size: String,
|
|
pub pool_lv: String,
|
|
pub origin: String,
|
|
pub data_percent: String,
|
|
pub metadata_percent: String,
|
|
pub move_pv: String,
|
|
pub mirror_log: String,
|
|
pub copy_percent: String,
|
|
pub convert_lv: String,
|
|
}
|
|
|
|
impl LV {
|
|
pub fn equal_name(&self, vg_name: &str, lv_name: &str) -> bool {
|
|
vg_name == &self.vg_name && lv_name == &self.lv_name
|
|
}
|
|
}
|
|
|
|
pub async fn pvs() -> Result<Vec<PV>> {
|
|
report_cmd("pvs", |o| match o {
|
|
ReportObj::PV(pv) => Some(pv),
|
|
_ => None,
|
|
})
|
|
.await
|
|
}
|
|
|
|
pub async fn vgs() -> Result<Vec<VG>> {
|
|
report_cmd("vgs", |o| match o {
|
|
ReportObj::VG(vg) => Some(vg),
|
|
_ => None,
|
|
})
|
|
.await
|
|
}
|
|
|
|
pub async fn lvs() -> Result<Vec<LV>> {
|
|
report_cmd("lvs", |o| match o {
|
|
ReportObj::LV(lv) => Some(lv),
|
|
_ => None,
|
|
})
|
|
.await
|
|
}
|
|
|
|
async fn report_cmd<T>(cmd: &str, find: fn(ReportObj) -> Option<Vec<T>>) -> Result<Vec<T>> {
|
|
let output = Command::new(cmd)
|
|
.arg("--reportformat=json")
|
|
.output()
|
|
.await?;
|
|
|
|
if !output.status.success() {
|
|
let stderr = String::from_utf8_lossy(&output.stderr.trim_ascii());
|
|
return Err(format_err!("{cmd} failed: {}", stderr));
|
|
}
|
|
|
|
let report: Report = serde_json::from_slice(&output.stdout).unwrap();
|
|
Ok((report.report.into_iter())
|
|
.filter_map(find)
|
|
.flatten()
|
|
.collect())
|
|
}
|