api return also disk mountpoints
This commit is contained in:
		@@ -31,6 +31,10 @@ rust-latest:
 | 
			
		||||
    paths:
 | 
			
		||||
      - "./raid_manager_static"
 | 
			
		||||
      - "./raid_manager"
 | 
			
		||||
  cache:
 | 
			
		||||
    key: shared-rust-latest-cache
 | 
			
		||||
    paths:
 | 
			
		||||
      - lib/target/
 | 
			
		||||
 | 
			
		||||
rust-nightly:
 | 
			
		||||
  stage: build_backend
 | 
			
		||||
@@ -42,3 +46,7 @@ rust-nightly:
 | 
			
		||||
    - cargo build -r --manifest-path=lib/Cargo.toml
 | 
			
		||||
    - cargo test -r --manifest-path=lib/Cargo.toml
 | 
			
		||||
  allow_failure: true
 | 
			
		||||
  cache:
 | 
			
		||||
    key: shared-rust-nightly-cache
 | 
			
		||||
    paths:
 | 
			
		||||
      - lib/target/
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								lib/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										36
									
								
								lib/Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -573,6 +573,15 @@ dependencies = [
 | 
			
		||||
 "cfg-if",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "itertools"
 | 
			
		||||
version = "0.10.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "either",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "itoa"
 | 
			
		||||
version = "1.0.4"
 | 
			
		||||
@@ -646,6 +655,12 @@ version = "0.3.16"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "minimal-lexical"
 | 
			
		||||
version = "0.2.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "mio"
 | 
			
		||||
version = "0.8.5"
 | 
			
		||||
@@ -678,6 +693,16 @@ dependencies = [
 | 
			
		||||
 "version_check",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "nom"
 | 
			
		||||
version = "7.1.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "memchr",
 | 
			
		||||
 "minimal-lexical",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "nu-ansi-term"
 | 
			
		||||
version = "0.46.0"
 | 
			
		||||
@@ -838,6 +863,7 @@ dependencies = [
 | 
			
		||||
 "regex",
 | 
			
		||||
 "rocket",
 | 
			
		||||
 "rust-embed",
 | 
			
		||||
 "versions",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
@@ -1456,6 +1482,16 @@ version = "0.9.4"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "versions"
 | 
			
		||||
version = "4.1.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "ee97e1d97bd593fb513912a07691b742361b3dd64ad56f2c694ea2dbfe0665d3"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "itertools",
 | 
			
		||||
 "nom",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "walkdir"
 | 
			
		||||
version = "2.3.2"
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ regex = "1"
 | 
			
		||||
lazy_static = "1.4.0"
 | 
			
		||||
include_dir = "0.7.3"
 | 
			
		||||
rust-embed = "6.4.2"
 | 
			
		||||
versions = "4.1.0"
 | 
			
		||||
 | 
			
		||||
[features]
 | 
			
		||||
static = []
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,17 @@
 | 
			
		||||
use std::process::Command;
 | 
			
		||||
use lazy_static::lazy_static;
 | 
			
		||||
use regex::{Regex};
 | 
			
		||||
use rocket::serde::json::{serde_json};
 | 
			
		||||
use rocket::serde::{Serialize, Deserialize};
 | 
			
		||||
use versions::Versioning;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize)]
 | 
			
		||||
#[serde(crate = "rocket::serde")]
 | 
			
		||||
pub struct Disk {
 | 
			
		||||
    name: String,
 | 
			
		||||
    size: u64,
 | 
			
		||||
    mountpoints: Vec<String>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize, Deserialize)]
 | 
			
		||||
@@ -20,7 +25,10 @@ struct ChildDevice {
 | 
			
		||||
    ro: bool,
 | 
			
		||||
    #[serde(rename = "type")]
 | 
			
		||||
    kind: String,
 | 
			
		||||
    mountpoints: Vec<Option<String>>,
 | 
			
		||||
    // new version is with vec of mountpoints
 | 
			
		||||
    mountpoints: Option<Vec<Option<String>>>,
 | 
			
		||||
    // old version is with one single mountpoint
 | 
			
		||||
    mountpoint: Option<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize, Deserialize)]
 | 
			
		||||
@@ -34,7 +42,10 @@ struct Blockdevice {
 | 
			
		||||
    majmin: String,
 | 
			
		||||
    rm: bool,
 | 
			
		||||
    ro: bool,
 | 
			
		||||
    mountpoints: Vec<Option<String>>,
 | 
			
		||||
    // new version is with vec of mountpoints
 | 
			
		||||
    mountpoints: Option<Vec<Option<String>>>,
 | 
			
		||||
    // old version is with one single mountpoint
 | 
			
		||||
    mountpoint: Option<String>,
 | 
			
		||||
    children: Option<Vec<ChildDevice>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -44,6 +55,63 @@ struct LsblkT {
 | 
			
		||||
    blockdevices: Vec<Blockdevice>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn lsblk_version() -> Versioning {
 | 
			
		||||
    let output = Command::new("lsblk")
 | 
			
		||||
        .arg("--version")
 | 
			
		||||
        .output()
 | 
			
		||||
        .expect("failed to execute process");
 | 
			
		||||
 | 
			
		||||
    let out = output.stdout;
 | 
			
		||||
    let out = String::from_utf8(out).unwrap();
 | 
			
		||||
 | 
			
		||||
    lazy_static! {
 | 
			
		||||
        static ref RE: Regex = Regex::new(r"([0-9]+\.[0-9]+\.[0-9]+)$").unwrap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    match RE.captures(&out) {
 | 
			
		||||
        None => Versioning::default(),
 | 
			
		||||
        Some(res) => {
 | 
			
		||||
            if res.len() == 2 {
 | 
			
		||||
                match Versioning::new(&res[1]){
 | 
			
		||||
                    None => Versioning::default(),
 | 
			
		||||
                    Some(v) => v
 | 
			
		||||
                }
 | 
			
		||||
            }else{
 | 
			
		||||
                Versioning::default()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn parse_lsblk_str(out: String) -> Vec<Disk> {
 | 
			
		||||
    let v: LsblkT = serde_json::from_str(out.as_str()).unwrap();
 | 
			
		||||
    let version = lsblk_version();
 | 
			
		||||
 | 
			
		||||
    let mut disks: Vec<Disk> = Vec::new();
 | 
			
		||||
    for d in v.blockdevices {
 | 
			
		||||
        if d.kind != "disk" { continue; };
 | 
			
		||||
 | 
			
		||||
        let mut mountpoints: Vec<String> = Vec::new();
 | 
			
		||||
        if version < Versioning::new("2.37.0").unwrap() {
 | 
			
		||||
            if d.mountpoint.is_some() {
 | 
			
		||||
                mountpoints.push(d.mountpoint.unwrap())
 | 
			
		||||
            }
 | 
			
		||||
        } else{
 | 
			
		||||
            if d.mountpoints.is_some() {
 | 
			
		||||
                let mntpts = d.mountpoints.unwrap();
 | 
			
		||||
                for p in mntpts {
 | 
			
		||||
                    if p.is_some() {
 | 
			
		||||
                        mountpoints.push(p.unwrap())
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        disks.push(Disk { name: d.name, size: d.size, mountpoints });
 | 
			
		||||
    }
 | 
			
		||||
    return disks;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn parse_lsblk() -> Vec<Disk> {
 | 
			
		||||
    let output = Command::new("lsblk")
 | 
			
		||||
        .arg("-J")
 | 
			
		||||
@@ -54,13 +122,70 @@ pub fn parse_lsblk() -> Vec<Disk> {
 | 
			
		||||
 | 
			
		||||
    let out = output.stdout;
 | 
			
		||||
    let out = String::from_utf8(out).unwrap();
 | 
			
		||||
 | 
			
		||||
    let v: LsblkT = serde_json::from_str(out.as_str()).unwrap();
 | 
			
		||||
 | 
			
		||||
    let mut disks: Vec<Disk> = Vec::new();
 | 
			
		||||
    for d in v.blockdevices {
 | 
			
		||||
        if d.kind != "disk" { continue; };
 | 
			
		||||
        disks.push(Disk { name: d.name, size: d.size });
 | 
			
		||||
    }
 | 
			
		||||
    return disks;
 | 
			
		||||
    parse_lsblk_str(out)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests {
 | 
			
		||||
    use rocket::serde::json::serde_json::json;
 | 
			
		||||
    // Note this useful idiom: importing names from outer (for mod tests) scope.
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_empty() {
 | 
			
		||||
        assert_eq!(json!(parse_lsblk_str(r#"
 | 
			
		||||
{
 | 
			
		||||
   "blockdevices": [
 | 
			
		||||
      {"name":"/dev/loop0", "maj:min":"7:0", "rm":false, "size":8589934592, "ro":false, "type":"loop", "mountpoint":null},
 | 
			
		||||
      {"name":"/dev/loop1", "maj:min":"7:1", "rm":false, "size":8589934592, "ro":false, "type":"loop", "mountpoint":null},
 | 
			
		||||
      {"name":"/dev/loop2", "maj:min":"7:2", "rm":false, "size":107374182400, "ro":false, "type":"loop", "mountpoint":null},
 | 
			
		||||
      {"name":"/dev/loop3", "maj:min":"7:3", "rm":false, "size":10737418240, "ro":false, "type":"loop", "mountpoint":null},
 | 
			
		||||
      {"name":"/dev/loop4", "maj:min":"7:4", "rm":false, "size":34359738368, "ro":false, "type":"loop", "mountpoint":null},
 | 
			
		||||
      {"name":"/dev/loop5", "maj:min":"7:5", "rm":false, "size":8589934592, "ro":false, "type":"loop", "mountpoint":null},
 | 
			
		||||
      {"name":"/dev/loop6", "maj:min":"7:6", "rm":false, "size":8589934592, "ro":false, "type":"loop", "mountpoint":null},
 | 
			
		||||
      {"name":"/dev/loop7", "maj:min":"7:7", "rm":false, "size":8589934592, "ro":false, "type":"loop", "mountpoint":null},
 | 
			
		||||
      {"name":"/dev/loop8", "maj:min":"7:8", "rm":false, "size":32212254720, "ro":false, "type":"loop", "mountpoint":null},
 | 
			
		||||
      {"name":"/dev/loop9", "maj:min":"7:9", "rm":false, "size":8589934592, "ro":false, "type":"loop", "mountpoint":null},
 | 
			
		||||
      {"name":"/dev/loop10", "maj:min":"7:10", "rm":false, "size":8589934592, "ro":false, "type":"loop", "mountpoint":null},
 | 
			
		||||
      {"name":"/dev/loop11", "maj:min":"7:11", "rm":false, "size":12884901888, "ro":false, "type":"loop", "mountpoint":null},
 | 
			
		||||
      {"name":"/dev/loop12", "maj:min":"7:12", "rm":false, "size":8589934592, "ro":false, "type":"loop", "mountpoint":null},
 | 
			
		||||
      {"name":"/dev/sda", "maj:min":"8:0", "rm":false, "size":120034123776, "ro":false, "type":"disk", "mountpoint":null,
 | 
			
		||||
         "children": [
 | 
			
		||||
            {"name":"/dev/sda1", "maj:min":"8:1", "rm":false, "size":1031168, "ro":false, "type":"part", "mountpoint":null},
 | 
			
		||||
            {"name":"/dev/sda2", "maj:min":"8:2", "rm":false, "size":536870912, "ro":false, "type":"part", "mountpoint":null},
 | 
			
		||||
            {"name":"/dev/sda3", "maj:min":"8:3", "rm":false, "size":119496187392, "ro":false, "type":"part", "mountpoint":null,
 | 
			
		||||
               "children": [
 | 
			
		||||
                  {"name":"/dev/mapper/pve-swap", "maj:min":"253:0", "rm":false, "size":4294967296, "ro":false, "type":"lvm", "mountpoint":"[SWAP]"},
 | 
			
		||||
                  {"name":"/dev/mapper/pve-root", "maj:min":"253:1", "rm":false, "size":115196559360, "ro":false, "type":"lvm", "mountpoint":"/"}
 | 
			
		||||
               ]
 | 
			
		||||
            }
 | 
			
		||||
         ]
 | 
			
		||||
      },
 | 
			
		||||
      {"name":"/dev/sdb", "maj:min":"8:16", "rm":false, "size":3000592982016, "ro":false, "type":"disk", "mountpoint":null,
 | 
			
		||||
         "children": [
 | 
			
		||||
            {"name":"/dev/md127", "maj:min":"9:127", "rm":false, "size":9001376219136, "ro":false, "type":"raid5", "mountpoint":"/media/3TBRaid"}
 | 
			
		||||
         ]
 | 
			
		||||
      },
 | 
			
		||||
      {"name":"/dev/sdc", "maj:min":"8:32", "rm":false, "size":3000592982016, "ro":false, "type":"disk", "mountpoint":null,
 | 
			
		||||
         "children": [
 | 
			
		||||
            {"name":"/dev/md127", "maj:min":"9:127", "rm":false, "size":9001376219136, "ro":false, "type":"raid5", "mountpoint":"/media/3TBRaid"}
 | 
			
		||||
         ]
 | 
			
		||||
      },
 | 
			
		||||
      {"name":"/dev/sdd", "maj:min":"8:48", "rm":false, "size":4000787030016, "ro":false, "type":"disk", "mountpoint":null,
 | 
			
		||||
         "children": [
 | 
			
		||||
            {"name":"/dev/md127", "maj:min":"9:127", "rm":false, "size":9001376219136, "ro":false, "type":"raid5", "mountpoint":"/media/3TBRaid"}
 | 
			
		||||
         ]
 | 
			
		||||
      },
 | 
			
		||||
      {"name":"/dev/sde", "maj:min":"8:64", "rm":false, "size":240057409536, "ro":false, "type":"disk", "mountpoint":"/media/hdd1"},
 | 
			
		||||
      {"name":"/dev/sdf", "maj:min":"8:80", "rm":false, "size":120034123776, "ro":false, "type":"disk", "mountpoint":"/media/hdd2"},
 | 
			
		||||
      {"name":"/dev/sdg", "maj:min":"8:96", "rm":false, "size":3000592982016, "ro":false, "type":"disk", "mountpoint":null,
 | 
			
		||||
         "children": [
 | 
			
		||||
            {"name":"/dev/md127", "maj:min":"9:127", "rm":false, "size":9001376219136, "ro":false, "type":"raid5", "mountpoint":"/media/3TBRaid"}
 | 
			
		||||
         ]
 | 
			
		||||
      },
 | 
			
		||||
      {"name":"/dev/nvme0n1", "maj:min":"259:0", "rm":false, "size":1000204886016, "ro":false, "type":"disk", "mountpoint":"/media/hdd3"}
 | 
			
		||||
   ]
 | 
			
		||||
}
 | 
			
		||||
        "#.to_string())).to_string(), r#"[{"name":"/dev/sda","size":120034123776},{"name":"/dev/sdb","size":3000592982016},{"name":"/dev/sdc","size":3000592982016},{"name":"/dev/sdd","size":4000787030016},{"name":"/dev/sde","size":240057409536},{"name":"/dev/sdf","size":120034123776},{"name":"/dev/sdg","size":3000592982016},{"name":"/dev/nvme0n1","size":1000204886016}]"#);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user