]> git.proxmox.com Git - pve-installer.git/blame - proxmox-auto-installer/src/fetch_plugins/utils/mod.rs
auto-installer: fetch: add http plugin to fetch answer
[pve-installer.git] / proxmox-auto-installer / src / fetch_plugins / utils / mod.rs
CommitLineData
e7988a46 1use anyhow::{Error, Result};
2949f825 2use log::{info, warn};
e7988a46
AL
3use serde::Deserialize;
4use serde_json;
2949f825
AL
5use std::{
6 fs::{self, create_dir_all},
7 path::{Path, PathBuf},
8 process::Command,
9};
10
11static ANSWER_MP: &str = "/mnt/answer";
12static PARTLABEL: &str = "proxmoxinst";
13static SEARCH_PATH: &str = "/dev/disk/by-label";
14
1ca401af 15pub mod post;
e7988a46
AL
16pub 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
23pub 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;
51pub 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
78fn 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)]
91struct IpLinksUdevInfo {
92 ifname: String,
93}
94
95/// Returns vec of usable NICs
96pub 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}