container_device_interface/
device.rs1use std::collections::BTreeMap;
2
3use anyhow::{anyhow, Context, Result};
4use oci_spec::runtime as oci;
5
6use crate::{
7 container_edits::{ContainerEdits, Validate},
8 internal::validation::validate::validate_spec_annotations,
9 parser::{qualified_name, validate_device_name},
10 spec::Spec,
11 specs::config::Device as CDIDevice,
12};
13
14#[derive(Clone, Debug, Eq, PartialEq, Hash)]
16pub struct Device {
17 pub cdi_device: CDIDevice,
18 cdi_spec: Spec,
19}
20
21impl Default for Device {
22 fn default() -> Self {
23 Self::new()
24 }
25}
26
27pub fn new_device(spec: &Spec, device: &CDIDevice) -> Result<Device> {
29 let device = Device {
30 cdi_device: device.clone(),
31 cdi_spec: spec.clone(),
32 };
33
34 if let Err(e) = device.validate() {
35 return Err(anyhow!(
36 "device validated failed with error: {:?}",
37 e.to_string()
38 ));
39 }
40
41 Ok(device)
42}
43
44impl Device {
45 pub fn new() -> Self {
47 Self {
48 cdi_device: Default::default(),
49 cdi_spec: Default::default(),
50 }
51 }
52
53 pub fn get_spec(&self) -> Spec {
55 self.cdi_spec.clone()
56 }
57
58 pub fn get_qualified_name(&self) -> String {
60 qualified_name(
61 &self.cdi_spec.get_vendor(),
62 &self.cdi_spec.get_class(),
63 &self.cdi_device.name,
64 )
65 }
66
67 pub fn edits(&self) -> ContainerEdits {
69 ContainerEdits {
70 container_edits: self.cdi_device.container_edits.clone(),
71 }
72 }
73 pub fn apply_edits(&mut self, oci_spec: &mut oci::Spec) -> Result<()> {
75 let _ = self.edits().apply(oci_spec);
76
77 Ok(())
78 }
79
80 pub fn validate(&self) -> Result<()> {
82 validate_device_name(&self.cdi_device.name).context("validate device name failed")?;
83 let name = self.get_qualified_name();
84
85 let annotations: &BTreeMap<String, String> =
86 &<BTreeMap<String, String> as Clone>::clone(&self.cdi_device.annotations)
87 .into_iter()
88 .collect();
89 if let Err(e) = validate_spec_annotations(&name, annotations) {
90 return Err(anyhow!(
91 "validate spec annotations failed with error: {:?}",
92 e
93 ));
94 }
95
96 let edits = self.edits();
97 edits
98 .validate()
99 .context(format!("invalid device {:?} ", self.cdi_device.name))?;
100
101 Ok(())
102 }
103}