@@ -6,6 +6,8 @@ use std::fs::create_dir_all;
6
6
use std:: fs:: File ;
7
7
use std:: io:: Read ;
8
8
use std:: os:: unix:: fs:: PermissionsExt ;
9
+ use std:: path:: PathBuf ;
10
+ use std:: process:: Command ;
9
11
10
12
use serde:: Deserialize ;
11
13
use serde_xml_rs:: from_str;
@@ -66,27 +68,92 @@ fn default_preprov_type() -> String {
66
68
"None" . to_owned ( )
67
69
}
68
70
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 /" ;
71
73
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 ;
73
77
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 ( ) ?;
79
108
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
+ }
81
122
}
82
123
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
+ }
88
146
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
+ }
90
157
}
91
158
92
159
pub fn parse_ovf_env ( ovf_body : & str ) -> Result < Environment , Error > {
0 commit comments