container_device_interface/generate/
generator.rs1use std::cmp::Ordering;
2use std::path::PathBuf;
3
4use oci_spec::runtime::{Hook, LinuxDevice, LinuxDeviceCgroup, LinuxDeviceType, Mount};
5
6use super::config::Generator;
7
8impl Generator {
9 pub fn remove_device(&mut self, path: &str) {
11 self.init_config_linux();
12 if let Some(linux) = self.config.as_mut().unwrap().linux_mut() {
13 if let Some(devices) = linux.devices_mut() {
14 if let Some(index) = devices
15 .iter()
16 .position(|device| device.path() == &PathBuf::from(path))
17 {
18 devices.remove(index);
19 }
20 }
21 }
22 }
23
24 pub fn add_device(&mut self, device: LinuxDevice) {
26 self.init_config_linux();
27
28 if let Some(linux) = self.config.as_mut().unwrap().linux_mut() {
29 if let Some(devices) = linux.devices_mut() {
30 if let Some(index) = devices.iter().position(|dev| dev.path() == device.path()) {
31 devices[index] = device;
32 } else {
33 devices.push(device);
34 }
35 } else {
36 linux.set_devices(Some(vec![device]));
37 }
38 }
39 }
40
41 pub fn add_linux_resources_device(
43 &mut self,
44 allow: bool,
45 dev_type: LinuxDeviceType,
46 major: Option<i64>,
47 minor: Option<i64>,
48 access: Option<String>,
49 ) {
50 self.init_config_linux_resources_devices();
51 if let Some(linux) = self.config.as_mut().unwrap().linux_mut() {
52 if let Some(resource) = linux.resources_mut() {
53 if let Some(devices) = resource.devices_mut() {
54 let mut device = LinuxDeviceCgroup::default();
55 device.set_allow(allow);
56 device.set_typ(Some(dev_type));
57 device.set_major(major);
58 device.set_minor(minor);
59 device.set_access(access);
60
61 devices.push(device);
62 }
63 }
64 }
65 }
66
67 pub fn set_linux_intel_rdt_clos_id(&mut self, clos_id: String) {
69 self.init_config_linux_intel_rdt();
70 if let Some(linux) = self.config.as_mut().unwrap().linux_mut() {
71 if let Some(intel_rdt) = linux.intel_rdt_mut() {
72 intel_rdt.set_clos_id(Some(clos_id));
73 }
74 }
75 }
76
77 pub fn add_process_additional_gid(&mut self, gid: u32) {
79 self.init_config_process();
80 if let Some(process) = self.config.as_mut().unwrap().process_mut() {
81 if let Some(additional_gids) = process.user().additional_gids() {
82 let mut tmp_vec = additional_gids.clone();
83 if !additional_gids.contains(&gid) {
84 tmp_vec.push(gid)
85 }
86
87 process.user_mut().set_additional_gids(Some(tmp_vec));
88 }
89 }
90 }
91
92 pub fn add_multiple_process_env(&mut self, envs: &[String]) {
93 self.init_config_process();
94
95 if let Some(process) = self.config.as_mut().unwrap().process_mut() {
96 let mut env_vec: Vec<String> = process.env_mut().get_or_insert_with(Vec::new).to_vec();
97 for env in envs {
98 let split: Vec<&str> = env.splitn(2, '=').collect();
99 let key = split[0].to_string();
100 let idx = self.env_map.entry(key.clone()).or_insert(env_vec.len());
101
102 if let Some(elem) = env_vec.get_mut(*idx) {
103 elem.clone_from(env);
104 } else {
105 env_vec.push(env.clone());
106 self.env_map.insert(key, env_vec.len() - 1);
107 }
108 }
109 process.set_env(Some(env_vec));
110 }
111 }
112
113 pub fn add_prestart_hook(&mut self, hook: Hook) {
115 self.init_config_hooks();
116 if let Some(hooks) = self.config.as_mut().unwrap().hooks_mut() {
117 if let Some(prestart_hooks) = hooks.prestart_mut() {
118 prestart_hooks.push(hook);
119 } else {
120 hooks.set_prestart(Some(vec![hook]));
121 }
122 }
123 }
124
125 pub fn add_poststop_hook(&mut self, hook: Hook) {
127 self.init_config_hooks();
128 if let Some(hooks) = self.config.as_mut().unwrap().hooks_mut() {
129 if let Some(poststop_hooks) = hooks.poststop_mut() {
130 poststop_hooks.push(hook);
131 } else {
132 hooks.set_poststop(Some(vec![hook]));
133 }
134 }
135 }
136
137 pub fn add_poststart_hook(&mut self, hook: Hook) {
139 self.init_config_hooks();
140 if let Some(hooks) = self.config.as_mut().unwrap().hooks_mut() {
141 if let Some(poststart_hooks) = hooks.poststart_mut() {
142 poststart_hooks.push(hook);
143 } else {
144 hooks.set_poststart(Some(vec![hook]));
145 }
146 }
147 }
148
149 pub fn add_createruntime_hook(&mut self, hook: Hook) {
151 self.init_config_hooks();
152 if let Some(hooks) = self.config.as_mut().unwrap().hooks_mut() {
153 if let Some(create_runtime) = hooks.create_runtime_mut() {
154 create_runtime.push(hook);
155 } else {
156 hooks.set_create_runtime(Some(vec![hook]));
157 }
158 }
159 }
160
161 pub fn add_createcontainer_hook(&mut self, hook: Hook) {
163 self.init_config_hooks();
164 if let Some(hooks) = self.config.as_mut().unwrap().hooks_mut() {
165 if let Some(create_container) = hooks.create_container_mut() {
166 create_container.push(hook);
167 } else {
168 hooks.set_create_container(Some(vec![hook]));
169 }
170 }
171 }
172
173 pub fn add_startcontainer_hook(&mut self, hook: Hook) {
175 self.init_config_hooks();
176 if let Some(hooks) = self.config.as_mut().unwrap().hooks_mut() {
177 if let Some(start_container) = hooks.start_container_mut() {
178 start_container.push(hook);
179 } else {
180 hooks.set_start_container(Some(vec![hook]));
181 }
182 }
183 }
184
185 pub fn remove_mount(&mut self, dest: &str) {
187 if let Some(mounts) = self.config.as_mut().unwrap().mounts_mut() {
188 if let Some(index) = mounts
189 .iter()
190 .position(|m| m.destination() == &PathBuf::from(dest))
191 {
192 mounts.remove(index);
193 }
194 }
195 }
196
197 pub fn add_mount(&mut self, mount: Mount) {
199 self.init_config_mounts();
200
201 if let Some(mounts) = self.config.as_mut().unwrap().mounts_mut() {
202 mounts.push(mount);
203 }
204 }
205
206 pub fn sort_mounts(&mut self) {
208 if let Some(ref mut mounts) = self.config.as_mut().unwrap().mounts_mut() {
209 mounts.sort_by(|a, b| a.destination().cmp(b.destination()));
210 }
211 }
212
213 pub fn list_mounts(&self) -> Option<&Vec<Mount>> {
215 self.config.as_ref().and_then(|spec| spec.mounts().as_ref())
216 }
217
218 pub fn clear_mounts(&mut self) {
220 if let Some(spec) = self.config.as_mut() {
221 spec.set_mounts(None);
222 }
223 }
224}
225
226struct OrderedMounts(Vec<Mount>);
232
233#[allow(dead_code)]
234impl OrderedMounts {
235 fn new(mounts: Vec<Mount>) -> Self {
236 OrderedMounts(mounts)
237 }
238
239 fn parts(&self, i: usize) -> usize {
241 self.0[i].destination().components().count()
242 }
243}
244
245impl Ord for OrderedMounts {
246 fn cmp(&self, other: &Self) -> Ordering {
247 let self_parts = self.parts(0);
248 let other_parts = other.parts(0);
249 self_parts
250 .cmp(&other_parts)
251 .then_with(|| self.0[0].destination().cmp(other.0[0].destination()))
252 }
253}
254
255impl PartialOrd for OrderedMounts {
256 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
257 Some(self.cmp(other))
258 }
259}
260
261impl PartialEq for OrderedMounts {
262 fn eq(&self, other: &Self) -> bool {
263 self.parts(0) == other.parts(0) && self.0[0].destination() == other.0[0].destination()
264 }
265}
266
267impl Eq for OrderedMounts {}