]>
Commit | Line | Data |
---|---|---|
412871c9 TL |
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 | }; | |
2949f825 AL |
8 | |
9 | static ANSWER_FILE: &str = "answer.toml"; | |
412871c9 | 10 | static ANSWER_MP: &str = "/mnt/answer"; |
528d1268 | 11 | static PARTLABEL: &str = "proxmox-inst-src"; |
412871c9 | 12 | static SEARCH_PATH: &str = "/dev/disk/by-label"; |
2949f825 AL |
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."); | |
412871c9 | 20 | |
249a10e9 AL |
21 | let mut mount_path = PathBuf::from(mount_proxmoxinst_part()?); |
22 | mount_path.push(ANSWER_FILE); | |
412871c9 TL |
23 | let answer = fs::read_to_string(mount_path) |
24 | .map_err(|err| format_err!("failed to read answer file - {err}"))?; | |
25 | ||
2949f825 | 26 | info!("Found answer file on partition."); |
412871c9 | 27 | |
2949f825 AL |
28 | Ok(answer) |
29 | } | |
2949f825 | 30 | } |
412871c9 TL |
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 '{}': {err}", path.display()), | |
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 '{}': {err}", path.display()), | |
58 | } | |
59 | Err(Error::msg(format!( | |
60 | "Could not detect upper or lower case labels for '{partlabel_source}'" | |
61 | ))) | |
62 | } | |
63 | ||
528d1268 TL |
64 | /// Will search and mount a partition/FS labeled PARTLABEL (proxmox-inst-src) in lower or uppercase |
65 | /// to ANSWER_MP | |
412871c9 TL |
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 | } |