container_device_interface/specs/
oci.rs1use std::{path::PathBuf, str::FromStr};
2
3use anyhow::Result;
4use oci_spec::runtime::{
5 Hook as OCIHook, LinuxDevice, LinuxDeviceType, LinuxIntelRdt,
6 LinuxNetDevice as OCILinuxNetDevice, Mount as OCIMount,
7};
8
9use crate::specs::config::{
10 DeviceNode, Hook as CDIHook, IntelRdt, LinuxNetDevice, Mount as CDIMount,
11};
12
13impl CDIHook {
14 pub fn to_oci(&self) -> Result<OCIHook> {
15 let mut oci_hook: OCIHook = Default::default();
16 oci_hook.set_path(PathBuf::from(&self.path));
17 oci_hook.set_args(self.args.clone());
18 oci_hook.set_env(self.env.clone());
19 oci_hook.set_timeout(self.timeout);
20
21 Ok(oci_hook)
22 }
23}
24
25impl CDIMount {
26 pub fn to_oci(&self) -> Result<OCIMount> {
27 let mut oci_mount: OCIMount = Default::default();
28 oci_mount.set_source(Some(PathBuf::from(&self.host_path)));
29 oci_mount.set_destination(PathBuf::from(&self.container_path));
30 oci_mount.set_typ(self.r#type.clone());
31 oci_mount.set_options(self.options.clone());
32
33 Ok(oci_mount)
34 }
35}
36
37impl DeviceNode {
38 pub fn to_oci(&self) -> Result<LinuxDevice> {
39 let mut linux_device: LinuxDevice = Default::default();
40 linux_device.set_path(PathBuf::from(&self.path));
41 if let Some(typ) = &self.r#type {
42 linux_device.set_typ(LinuxDeviceType::from_str(typ)?);
43 }
44 if let Some(maj) = self.major {
45 linux_device.set_major(maj);
46 }
47 if let Some(min) = self.minor {
48 linux_device.set_minor(min);
49 }
50 linux_device.set_file_mode(self.file_mode);
51 linux_device.set_uid(self.uid);
52 linux_device.set_gid(self.gid);
53
54 Ok(linux_device)
55 }
56}
57
58impl IntelRdt {
59 #[allow(deprecated)]
60 pub fn to_oci(&self) -> Result<LinuxIntelRdt> {
61 let mut intel_rdt: LinuxIntelRdt = Default::default();
62 intel_rdt.set_clos_id(self.clos_id.clone());
63 intel_rdt.set_l3_cache_schema(self.l3_cache_schema.clone());
64 intel_rdt.set_mem_bw_schema(self.mem_bw_schema.clone());
65 intel_rdt.set_schemata(self.schemata.clone());
66 intel_rdt.set_enable_monitoring(self.enable_monitoring);
67 intel_rdt.set_enable_cmt(self.enable_cmt);
68 intel_rdt.set_enable_mbm(self.enable_mbm);
69
70 Ok(intel_rdt)
71 }
72}
73
74impl LinuxNetDevice {
75 pub fn to_oci(&self) -> Result<OCILinuxNetDevice> {
76 let mut net_device = OCILinuxNetDevice::default();
77 net_device.set_name(Some(self.name.clone()));
78 Ok(net_device)
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use oci_spec::runtime::LinuxDevice;
85 use std::path::PathBuf;
86
87 use crate::specs::{
88 config::{DeviceNode, IntelRdt, LinuxNetDevice},
89 oci::{CDIHook, CDIMount, OCIHook, OCIMount},
90 };
91
92 #[test]
93 fn test_hooks_to_oci() {
94 let cdi_hooks = CDIHook {
95 hook_name: "x".to_owned(),
96 path: "y".to_owned(),
97 args: None,
98 env: Some(vec!["n".to_owned(), "v".to_owned()]),
99 timeout: Some(100_i64),
100 };
101
102 let oci_hook: OCIHook = cdi_hooks.to_oci().unwrap();
103 assert_eq!(PathBuf::from(cdi_hooks.path), oci_hook.path().clone());
104 assert_eq!(None, oci_hook.args().clone());
105 assert_eq!(cdi_hooks.env, oci_hook.env().clone());
106 assert_eq!(cdi_hooks.timeout, oci_hook.timeout());
107 }
108
109 #[test]
110 fn test_mount_to_oci() {
111 let cdi_mount = CDIMount {
112 host_path: "x".to_owned(),
113 container_path: "c".to_owned(),
114 r#type: Some("t".to_owned()),
115 options: None,
116 };
117
118 let oci_mount: OCIMount = cdi_mount.to_oci().unwrap();
119 assert_eq!(
120 Some(PathBuf::from(cdi_mount.host_path)),
121 oci_mount.source().clone()
122 );
123 assert_eq!(
124 PathBuf::from(cdi_mount.container_path),
125 oci_mount.destination().clone()
126 );
127 assert_eq!(cdi_mount.r#type, oci_mount.typ().clone());
128 }
129
130 #[test]
131 fn test_device_node_to_oci() {
132 let dev_node = DeviceNode {
133 path: "p".to_owned(),
134 host_path: Some("hostp".to_owned()),
135 major: Some(251),
136 minor: Some(0),
137 ..Default::default()
138 };
139
140 let linux_dev: LinuxDevice = dev_node.to_oci().unwrap();
141 assert_eq!(PathBuf::from(dev_node.path), linux_dev.path().clone());
142 assert_eq!(dev_node.major, Some(linux_dev.major()));
143 assert_eq!(dev_node.minor, Some(linux_dev.minor()));
144 }
145
146 #[test]
147 fn test_device_node_to_oci_preserves_type() {
148 let dev_node = DeviceNode {
149 path: "/dev/example".to_string(),
150 r#type: Some("b".to_string()),
151 major: Some(8),
152 minor: Some(0),
153 ..Default::default()
154 };
155
156 let linux_dev = dev_node.to_oci().unwrap();
157 assert_eq!(oci_spec::runtime::LinuxDeviceType::B, linux_dev.typ());
158 }
159
160 #[test]
161 fn test_intel_rdt_to_oci_v1_1_fields() {
162 let intel_rdt = IntelRdt {
163 clos_id: Some("class-a".to_string()),
164 l3_cache_schema: Some("L3:0=ffff".to_string()),
165 mem_bw_schema: Some("MB:0=100".to_string()),
166 schemata: Some(vec!["L3:0=ffff".to_string()]),
167 enable_monitoring: Some(true),
168 enable_cmt: Some(true),
169 enable_mbm: Some(true),
170 };
171
172 let oci_rdt = intel_rdt.to_oci().unwrap();
173 assert_eq!(Some(&"class-a".to_string()), oci_rdt.clos_id().as_ref());
174 assert_eq!(
175 Some(&"L3:0=ffff".to_string()),
176 oci_rdt.l3_cache_schema().as_ref()
177 );
178 assert_eq!(
179 Some(&"MB:0=100".to_string()),
180 oci_rdt.mem_bw_schema().as_ref()
181 );
182 assert_eq!(
183 Some(&vec!["L3:0=ffff".to_string()]),
184 oci_rdt.schemata().as_ref()
185 );
186 assert_eq!(&Some(true), oci_rdt.enable_monitoring());
187 #[allow(deprecated)]
188 {
189 assert_eq!(&Some(true), oci_rdt.enable_cmt());
190 assert_eq!(&Some(true), oci_rdt.enable_mbm());
191 }
192 }
193
194 #[test]
195 fn test_linux_net_device_to_oci() {
196 let net_device = LinuxNetDevice {
197 host_interface_name: "eth0".to_string(),
198 name: "container_eth0".to_string(),
199 };
200
201 let oci_net_device = net_device.to_oci().unwrap();
202 assert_eq!(
203 Some(&"container_eth0".to_string()),
204 oci_net_device.name().as_ref()
205 );
206 }
207}