]>
Commit | Line | Data |
---|---|---|
e7988a46 | 1 | use anyhow::{Error, Result}; |
2949f825 | 2 | use log::{info, warn}; |
e7988a46 AL |
3 | use serde::Deserialize; |
4 | use serde_json; | |
2949f825 AL |
5 | use std::{ |
6 | fs::{self, create_dir_all}, | |
7 | path::{Path, PathBuf}, | |
8 | process::Command, | |
9 | }; | |
10 | ||
11 | static ANSWER_MP: &str = "/mnt/answer"; | |
12 | static PARTLABEL: &str = "proxmoxinst"; | |
13 | static SEARCH_PATH: &str = "/dev/disk/by-label"; | |
14 | ||
1ca401af | 15 | pub mod post; |
e7988a46 AL |
16 | pub mod sysinfo; |
17 | ||
2949f825 AL |
18 | /// Searches for upper and lower case existence of the partlabel in the search_path |
19 | /// | |
20 | /// # Arguemnts | |
21 | /// * `partlabel_source` - Partition Label, used as upper and lower case | |
22 | /// * `search_path` - Path where to search for the partiiton label | |
23 | pub fn scan_partlabels(partlabel_source: &str, search_path: &str) -> Result<PathBuf> { | |
24 | let partlabel = partlabel_source.to_uppercase(); | |
25 | let path = Path::new(search_path).join(&partlabel); | |
26 | match path.try_exists() { | |
27 | Ok(true) => { | |
e7988a46 | 28 | info!("Found partition with label '{}'", partlabel); |
2949f825 AL |
29 | return Ok(path); |
30 | } | |
e7988a46 | 31 | Ok(false) => info!("Did not detect partition with label '{}'", partlabel), |
2949f825 AL |
32 | Err(err) => info!("Encountered issue, accessing '{}': {}", path.display(), err), |
33 | } | |
34 | ||
35 | let partlabel = partlabel_source.to_lowercase(); | |
36 | let path = Path::new(search_path).join(&partlabel); | |
37 | match path.try_exists() { | |
38 | Ok(true) => { | |
e7988a46 | 39 | info!("Found partition with label '{}'", partlabel); |
2949f825 AL |
40 | return Ok(path); |
41 | } | |
e7988a46 | 42 | Ok(false) => info!("Did not detect partition with label '{}'", partlabel), |
2949f825 AL |
43 | Err(err) => info!("Encountered issue, accessing '{}': {}", path.display(), err), |
44 | } | |
e7988a46 AL |
45 | Err(Error::msg(format!( |
46 | "Could not detect upper or lower case labels for '{partlabel_source}'" | |
47 | ))) | |
2949f825 AL |
48 | } |
49 | ||
50 | /// Will search and mount a partition/FS labeled proxmoxinst in lower or uppercase to ANSWER_MP; | |
51 | pub fn mount_proxmoxinst_part() -> Result<String> { | |
52 | if let Ok(true) = check_if_mounted(ANSWER_MP) { | |
53 | info!("Skipping: '{ANSWER_MP}' is already mounted."); | |
54 | return Ok(ANSWER_MP.into()); | |
55 | } | |
56 | let part_path = scan_partlabels(PARTLABEL, SEARCH_PATH)?; | |
57 | info!("Mounting partition at {ANSWER_MP}"); | |
58 | // create dir for mountpoint | |
59 | create_dir_all(ANSWER_MP)?; | |
60 | match Command::new("mount") | |
61 | .args(["-o", "ro"]) | |
62 | .arg(part_path) | |
63 | .arg(ANSWER_MP) | |
64 | .output() | |
65 | { | |
66 | Ok(output) => { | |
67 | if output.status.success() { | |
68 | Ok(ANSWER_MP.into()) | |
69 | } else { | |
70 | warn!("Error mounting: {}", String::from_utf8(output.stderr)?); | |
71 | Ok(ANSWER_MP.into()) | |
72 | } | |
73 | } | |
74 | Err(err) => Err(Error::msg(format!("Error mounting: {err}"))), | |
75 | } | |
76 | } | |
77 | ||
78 | fn check_if_mounted(target_path: &str) -> Result<bool> { | |
79 | let mounts = fs::read_to_string("/proc/mounts")?; | |
80 | for line in mounts.lines() { | |
81 | if let Some(mp) = line.split(' ').nth(1) { | |
82 | if mp == target_path { | |
83 | return Ok(true); | |
84 | } | |
85 | } | |
86 | } | |
87 | Ok(false) | |
88 | } | |
e7988a46 AL |
89 | |
90 | #[derive(Deserialize, Debug)] | |
91 | struct IpLinksUdevInfo { | |
92 | ifname: String, | |
93 | } | |
94 | ||
95 | /// Returns vec of usable NICs | |
96 | pub fn get_nic_list() -> Result<Vec<String>> { | |
97 | let ip_output = Command::new("/usr/sbin/ip") | |
98 | .arg("-j") | |
99 | .arg("link") | |
100 | .output()?; | |
101 | let parsed_links: Vec<IpLinksUdevInfo> = | |
102 | serde_json::from_str(String::from_utf8(ip_output.stdout)?.as_str())?; | |
103 | let mut links: Vec<String> = Vec::new(); | |
104 | ||
105 | for link in parsed_links { | |
106 | if link.ifname == *"lo" { | |
107 | continue; | |
108 | } | |
109 | links.push(link.ifname); | |
110 | } | |
111 | ||
112 | Ok(links) | |
113 | } |