@@ -12,6 +12,7 @@ use akri_discovery_utils::discovery::{
12
12
} ;
13
13
use async_trait:: async_trait;
14
14
use log:: { error, info, trace} ;
15
+ use serde:: { de, Deserialize , Deserializer } ;
15
16
use std:: collections:: { HashMap , HashSet } ;
16
17
use std:: time:: Duration ;
17
18
use tokio:: sync:: mpsc;
@@ -30,6 +31,34 @@ pub struct UdevDiscoveryDetails {
30
31
31
32
#[ serde( default ) ]
32
33
pub group_recursive : bool ,
34
+
35
+ #[ serde( default = "default_permissions" ) ]
36
+ #[ serde( deserialize_with = "validate_permissions" ) ]
37
+ pub permissions : String ,
38
+ }
39
+
40
+ // Validate the permissible set of cgroups `permissions`
41
+ fn validate_permissions < ' de , D > ( deserializer : D ) -> Result < String , D :: Error >
42
+ where
43
+ D : Deserializer < ' de > ,
44
+ {
45
+ let value: String = Deserialize :: deserialize ( deserializer) ?;
46
+
47
+ // Validating that the string only contains allowed combinations of 'r', 'w', 'm'
48
+ let valid_permissions = [ "r" , "w" , "m" , "rw" , "rm" , "rwm" , "wm" ] ;
49
+ if valid_permissions. contains ( & value. as_str ( ) ) {
50
+ Ok ( value)
51
+ } else {
52
+ Err ( de:: Error :: invalid_value (
53
+ de:: Unexpected :: Str ( & value) ,
54
+ & "a valid permission combination ('r', 'w', 'm', 'rw', 'rm', 'rwm', 'wm')" ,
55
+ ) )
56
+ }
57
+ }
58
+
59
+ /// Default permissions for devices
60
+ fn default_permissions ( ) -> String {
61
+ "rwm" . to_string ( )
33
62
}
34
63
35
64
/// `DiscoveryHandlerImpl` discovers udev instances by parsing the udev rules in `discovery_handler_config.udev_rules`.
@@ -105,7 +134,7 @@ impl DiscoveryHandler for DiscoveryHandlerImpl {
105
134
device_specs. push ( DeviceSpec {
106
135
container_path : devnode. clone ( ) ,
107
136
host_path : devnode,
108
- permissions : "rwm" . to_string ( ) ,
137
+ permissions : discovery_handler_config . permissions . clone ( ) ,
109
138
} )
110
139
}
111
140
}
@@ -178,7 +207,8 @@ mod tests {
178
207
let udev_dh_config: UdevDiscoveryDetails = deserialize_discovery_details ( yaml) . unwrap ( ) ;
179
208
assert ! ( udev_dh_config. udev_rules. is_empty( ) ) ;
180
209
let serialized = serde_json:: to_string ( & udev_dh_config) . unwrap ( ) ;
181
- let expected_deserialized = r#"{"udevRules":[],"groupRecursive":false}"# ;
210
+ let expected_deserialized =
211
+ r#"{"udevRules":[],"groupRecursive":false,"permissions":"rwm"}"# ;
182
212
assert_eq ! ( expected_deserialized, serialized) ;
183
213
}
184
214
@@ -187,9 +217,24 @@ mod tests {
187
217
let yaml = r#"
188
218
udevRules:
189
219
- 'KERNEL=="video[0-9]*"'
220
+ permissions: rwm
190
221
"# ;
191
222
let udev_dh_config: UdevDiscoveryDetails = deserialize_discovery_details ( yaml) . unwrap ( ) ;
192
223
assert_eq ! ( udev_dh_config. udev_rules. len( ) , 1 ) ;
193
224
assert_eq ! ( & udev_dh_config. udev_rules[ 0 ] , "KERNEL==\" video[0-9]*\" " ) ;
225
+ assert_eq ! ( & udev_dh_config. permissions, "rwm" ) ;
226
+ }
227
+
228
+ #[ test]
229
+ fn test_deserialize_discovery_details_permissions_invalid ( ) {
230
+ let yaml = r#"
231
+ udevRules:
232
+ - 'KERNEL=="video[0-9]*"'
233
+ permissions: xyz
234
+ "# ;
235
+ match deserialize_discovery_details :: < UdevDiscoveryDetails > ( yaml) {
236
+ Ok ( _) => panic ! ( "Expected error parsing invalid permissions" ) ,
237
+ Err ( e) => assert ! ( e. to_string( ) . contains( "a valid permission combination" ) ) ,
238
+ }
194
239
}
195
240
}
0 commit comments