Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 62ef2ed

Browse files
dongsuparkjeremycline
andauthoredApr 5, 2024··
bring back mount_media, remove_media (#62)
Functions `mount_media` and `remove_media` were removed in #57. To parse a ovf_env file, however, both mount_media and remove_media are necessary. Bring back the functions. Adjust return types according to the new LibError interface as well. Co-authored-by: Jeremy Cline <jeremycline@microsoft.com>
1 parent 49775b4 commit 62ef2ed

File tree

2 files changed

+99
-18
lines changed

2 files changed

+99
-18
lines changed
 

‎libazureinit/src/media.rs

+82-15
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use std::fs::create_dir_all;
66
use std::fs::File;
77
use std::io::Read;
88
use std::os::unix::fs::PermissionsExt;
9+
use std::path::PathBuf;
10+
use std::process::Command;
911

1012
use serde::Deserialize;
1113
use serde_xml_rs::from_str;
@@ -66,27 +68,92 @@ fn default_preprov_type() -> String {
6668
"None".to_owned()
6769
}
6870

69-
pub fn make_temp_directory() -> Result<(), Box<dyn std::error::Error>> {
70-
let file_path = "/run/azure-init/tmp/";
71+
pub const PATH_MOUNT_DEVICE: &str = "/dev/sr0";
72+
pub const PATH_MOUNT_POINT: &str = "/run/azure-init/media/";
7173

72-
create_dir_all(file_path)?;
74+
// Some zero-sized structs that just provide states for our state machine
75+
pub struct Mounted;
76+
pub struct Unmounted;
7377

74-
let metadata = fs::metadata(file_path)?;
75-
let permissions = metadata.permissions();
76-
let mut new_permissions = permissions.clone();
77-
new_permissions.set_mode(0o700);
78-
fs::set_permissions(file_path, new_permissions)?;
78+
pub struct Media<State = Unmounted> {
79+
device_path: PathBuf,
80+
mount_path: PathBuf,
81+
state: std::marker::PhantomData<State>,
82+
}
83+
84+
impl Media<Unmounted> {
85+
pub fn new(device_path: PathBuf, mount_path: PathBuf) -> Media<Unmounted> {
86+
Media {
87+
device_path,
88+
mount_path,
89+
state: std::marker::PhantomData,
90+
}
91+
}
92+
93+
pub fn mount(self) -> Result<Media<Mounted>, Error> {
94+
create_dir_all(&self.mount_path)?;
95+
96+
let metadata = fs::metadata(&self.mount_path)?;
97+
let permissions = metadata.permissions();
98+
let mut new_permissions = permissions.clone();
99+
new_permissions.set_mode(0o700);
100+
fs::set_permissions(&self.mount_path, new_permissions)?;
101+
102+
let mount_status = Command::new("mount")
103+
.arg("-o")
104+
.arg("ro")
105+
.arg(&self.device_path)
106+
.arg(&self.mount_path)
107+
.status()?;
79108

80-
Ok(())
109+
if !mount_status.success() {
110+
Err(Error::SubprocessFailed {
111+
command: "mount".to_string(),
112+
status: mount_status,
113+
})
114+
} else {
115+
Ok(Media {
116+
device_path: self.device_path,
117+
mount_path: self.mount_path,
118+
state: std::marker::PhantomData,
119+
})
120+
}
121+
}
81122
}
82123

83-
pub fn read_ovf_env_to_string() -> Result<String, Error> {
84-
let file_path = "/run/azure-init/tmp/ovf-env.xml";
85-
let mut file = File::open(file_path)?;
86-
let mut contents = String::new();
87-
file.read_to_string(&mut contents)?;
124+
impl Media<Mounted> {
125+
pub fn unmount(self) -> Result<(), Error> {
126+
let umount_status =
127+
Command::new("umount").arg(self.mount_path).status()?;
128+
if !umount_status.success() {
129+
return Err(Error::SubprocessFailed {
130+
command: "umount".to_string(),
131+
status: umount_status,
132+
});
133+
}
134+
135+
let eject_status =
136+
Command::new("eject").arg(self.device_path).status()?;
137+
if !eject_status.success() {
138+
Err(Error::SubprocessFailed {
139+
command: "eject".to_string(),
140+
status: eject_status,
141+
})
142+
} else {
143+
Ok(())
144+
}
145+
}
88146

89-
Ok(contents)
147+
pub fn read_ovf_env_to_string(&self) -> Result<String, Error> {
148+
let mut file_path = self.mount_path.clone();
149+
file_path.push("ovf-env.xml");
150+
let mut file =
151+
File::open(file_path.to_str().unwrap_or(PATH_MOUNT_POINT))?;
152+
let mut contents = String::new();
153+
file.read_to_string(&mut contents)?;
154+
155+
Ok(contents)
156+
}
90157
}
91158

92159
pub fn parse_ovf_env(ovf_body: &str) -> Result<Environment, Error> {

‎src/main.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4+
use std::path::PathBuf;
45
use std::process::ExitCode;
56

67
use anyhow::Context;
@@ -9,21 +10,34 @@ use libazureinit::distro::{Distribution, Distributions};
910
use libazureinit::{
1011
error::Error as LibError,
1112
goalstate, imds, media,
13+
media::Media,
1214
reqwest::{header, Client},
1315
user,
1416
};
1517

1618
const VERSION: &str = env!("CARGO_PKG_VERSION");
1719

18-
fn get_username(imds_body: String) -> Result<String, LibError> {
20+
fn get_username(imds_body: String) -> Result<String, anyhow::Error> {
1921
if imds::is_password_authentication_disabled(&imds_body)? {
2022
// password authentication is disabled
21-
imds::get_username(imds_body.clone())
23+
Ok(imds::get_username(imds_body.clone())?)
2224
} else {
2325
// password authentication is enabled
24-
let ovf_body = media::read_ovf_env_to_string()?;
26+
let mount_media = Media::new(
27+
PathBuf::from(media::PATH_MOUNT_DEVICE),
28+
PathBuf::from(media::PATH_MOUNT_POINT),
29+
);
30+
let mounted = mount_media
31+
.mount()
32+
.with_context(|| "Failed to mount media.")?;
33+
34+
let ovf_body = mounted.read_ovf_env_to_string()?;
2535
let environment = media::parse_ovf_env(ovf_body.as_str())?;
2636

37+
mounted
38+
.unmount()
39+
.with_context(|| "Failed to remove media.")?;
40+
2741
Ok(environment
2842
.provisioning_section
2943
.linux_prov_conf_set

0 commit comments

Comments
 (0)
Please sign in to comment.