]> git.proxmox.com Git - pve-installer.git/blob - proxmox-fetch-answer/src/fetch_plugins/partition.rs
print paths directly with debug, not display
[pve-installer.git] / proxmox-fetch-answer / src / fetch_plugins / partition.rs
1 use anyhow::{format_err, Error, Result};
2 use log::{info, warn};
3 use std::{
4 fs::{self, create_dir_all},
5 path::{Path, PathBuf},
6 process::Command,
7 };
8
9 static ANSWER_FILE: &str = "answer.toml";
10 static ANSWER_MP: &str = "/mnt/answer";
11 static PARTLABEL: &str = "proxmox-inst-src";
12 static SEARCH_PATH: &str = "/dev/disk/by-label";
13
14 pub struct FetchFromPartition;
15
16 impl FetchFromPartition {
17 /// Returns the contents of the answer file
18 pub fn get_answer() -> Result<String> {
19 info!("Checking for answer file on partition.");
20
21 let mut mount_path = PathBuf::from(mount_proxmoxinst_part()?);
22 mount_path.push(ANSWER_FILE);
23 let answer = fs::read_to_string(mount_path)
24 .map_err(|err| format_err!("failed to read answer file - {err}"))?;
25
26 info!("Found answer file on partition.");
27
28 Ok(answer)
29 }
30 }
31
32 /// Searches for upper and lower case existence of the partlabel in the search_path
33 ///
34 /// # Arguemnts
35 /// * `partlabel_source` - Partition Label, used as upper and lower case
36 /// * `search_path` - Path where to search for the partiiton label
37 fn scan_partlabels(partlabel_source: &str, search_path: &str) -> Result<PathBuf> {
38 let partlabel = partlabel_source.to_uppercase();
39 let path = Path::new(search_path).join(&partlabel);
40 match path.try_exists() {
41 Ok(true) => {
42 info!("Found partition with label '{partlabel}'");
43 return Ok(path);
44 }
45 Ok(false) => info!("Did not detect partition with label '{partlabel}'"),
46 Err(err) => info!("Encountered issue, accessing '{path:?}': {err}"),
47 }
48
49 let partlabel = partlabel_source.to_lowercase();
50 let path = Path::new(search_path).join(&partlabel);
51 match path.try_exists() {
52 Ok(true) => {
53 info!("Found partition with label '{partlabel}'");
54 return Ok(path);
55 }
56 Ok(false) => info!("Did not detect partition with label '{partlabel}'"),
57 Err(err) => info!("Encountered issue, accessing '{path:?}': {err}"),
58 }
59 Err(Error::msg(format!(
60 "Could not detect upper or lower case labels for '{partlabel_source}'"
61 )))
62 }
63
64 /// Will search and mount a partition/FS labeled PARTLABEL (proxmox-inst-src) in lower or uppercase
65 /// to ANSWER_MP
66 fn mount_proxmoxinst_part() -> Result<String> {
67 if let Ok(true) = check_if_mounted(ANSWER_MP) {
68 info!("Skipping: '{ANSWER_MP}' is already mounted.");
69 return Ok(ANSWER_MP.into());
70 }
71 let part_path = scan_partlabels(PARTLABEL, SEARCH_PATH)?;
72 info!("Mounting partition at {ANSWER_MP}");
73 // create dir for mountpoint
74 create_dir_all(ANSWER_MP)?;
75 match Command::new("mount")
76 .args(["-o", "ro"])
77 .arg(part_path)
78 .arg(ANSWER_MP)
79 .output()
80 {
81 Ok(output) => {
82 if output.status.success() {
83 Ok(ANSWER_MP.into())
84 } else {
85 warn!("Error mounting: {}", String::from_utf8(output.stderr)?);
86 Ok(ANSWER_MP.into())
87 }
88 }
89 Err(err) => Err(Error::msg(format!("Error mounting: {err}"))),
90 }
91 }
92
93 fn check_if_mounted(target_path: &str) -> Result<bool> {
94 let mounts = fs::read_to_string("/proc/mounts")?;
95 for line in mounts.lines() {
96 if let Some(mp) = line.split(' ').nth(1) {
97 if mp == target_path {
98 return Ok(true);
99 }
100 }
101 }
102 Ok(false)
103 }