1 use anyhow
::{format_err, Error, Result}
;
4 fs
::{self, create_dir_all}
,
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";
14 pub struct FetchFromPartition
;
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.");
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}"))?
;
26 info
!("Found answer file on partition.");
32 /// Searches for upper and lower case existence of the partlabel in the search_path
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() {
42 info
!("Found partition with label '{partlabel}'");
45 Ok(false) => info
!("Did not detect partition with label '{partlabel}'"),
46 Err(err
) => info
!("Encountered issue, accessing '{}': {err}", path
.display()),
49 let partlabel
= partlabel_source
.to_lowercase();
50 let path
= Path
::new(search_path
).join(&partlabel
);
51 match path
.try_exists() {
53 info
!("Found partition with label '{partlabel}'");
56 Ok(false) => info
!("Did not detect partition with label '{partlabel}'"),
57 Err(err
) => info
!("Encountered issue, accessing '{}': {err}", path
.display()),
59 Err(Error
::msg(format
!(
60 "Could not detect upper or lower case labels for '{partlabel_source}'"
64 /// Will search and mount a partition/FS labeled PARTLABEL (proxmox-inst-src) in lower or uppercase
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());
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")
82 if output
.status
.success() {
85 warn
!("Error mounting: {}", String
::from_utf8(output
.stderr
)?
);
89 Err(err
) => Err(Error
::msg(format
!("Error mounting: {err}"))),
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
{