migrate to rust
This commit is contained in:
102
src/lvm.rs
Normal file
102
src/lvm.rs
Normal file
@ -0,0 +1,102 @@
|
||||
use eyre::{format_err, Result};
|
||||
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())
|
||||
}
|
Reference in New Issue
Block a user