Skip to main content

k8s_openapi/v1_37/api/resource/v1beta1/
device_request.rs

1// Generated from definition io.k8s.api.resource.v1beta1.DeviceRequest
2
3/// DeviceRequest is a request for devices required for a claim. This is typically a request for a single resource like a device, but can also ask for several identical devices.
4#[derive(Clone, Debug, Default, PartialEq)]
5pub struct DeviceRequest {
6    /// AdminAccess indicates that this is a claim for administrative access to the device(s). Claims with AdminAccess are expected to be used for monitoring or other management services for a device.  They ignore all ordinary claims to the device with respect to access modes and any resource allocations.
7    ///
8    /// This field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.
9    ///
10    /// This is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.
11    pub admin_access: Option<bool>,
12
13    /// AllocationMode and its related fields define how devices are allocated to satisfy this request. Supported values are:
14    ///
15    /// - ExactCount: This request is for a specific number of devices.
16    ///   This is the default. The exact number is provided in the
17    ///   count field.
18    ///
19    /// - All: This request is for all of the matching devices in a pool.
20    ///   At least one device must exist on the node for the allocation to succeed.
21    ///   Allocation will fail if some devices are already allocated,
22    ///   unless adminAccess is requested.
23    ///
24    /// If AllocationMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other requests must specify this field.
25    ///
26    /// This field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.
27    ///
28    /// More modes may get added in the future. Clients must refuse to handle requests with unknown modes.
29    pub allocation_mode: Option<std::string::String>,
30
31    /// Capacity define resource requirements against each capacity.
32    ///
33    /// If this field is unset and the device supports multiple allocations, the default value will be applied to each capacity according to requestPolicy. For the capacity that has no requestPolicy, default is the full capacity value.
34    ///
35    /// Applies to each device allocation. If Count \> 1, the request fails if there aren't enough devices that meet the requirements. If AllocationMode is set to All, the request fails if there are devices that otherwise match the request, and have this capacity, with a value \>= the requested amount, but which cannot be allocated to this request.
36    pub capacity: Option<crate::api::resource::v1beta1::CapacityRequirements>,
37
38    /// Count is used only when the count mode is "ExactCount". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.
39    ///
40    /// This field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.
41    pub count: Option<i64>,
42
43    /// DerivedAttributes defines a set of virtual attributes computed via CEL expressions for each candidate device. These virtual attributes can be referenced in `.devices.constraints` to align and match different devices (e.g., co-allocating a GPU and a NIC on the same NUMA node) even if their drivers publish different attributes. Derived attributes are not available via `device.attributes` in the CEL environment when evaluating selector expressions.
44    ///
45    /// Derived attributes allow you to extract, transform, or normalize topology information (such as extracting a NUMA index from a complex topology string or renaming a vendor-specific attribute) into a common virtual attribute name at scheduling time. The scheduler then evaluates these virtual attributes exactly like static attributes when matching constraints.
46    ///
47    /// Every derived attribute defined in this list must be referenced by at least one MatchAttribute or DistinctAttribute constraint in the `.devices.constraints` list.
48    ///
49    /// The maximum number of derived attributes is 32.
50    ///
51    /// This is an alpha field and requires enabling the DRADerivedAttributes feature gate.
52    pub derived_attributes: Option<std::vec::Vec<crate::api::resource::v1beta1::DeviceDerivedAttribute>>,
53
54    /// DeviceClassName references a specific DeviceClass, which can define additional configuration and selectors to be inherited by this request.
55    ///
56    /// A class is required if no subrequests are specified in the firstAvailable list and no class can be set if subrequests are specified in the firstAvailable list. Which classes are available depends on the cluster.
57    ///
58    /// Administrators may use this to restrict which devices may get requested by only installing classes with selectors for permitted devices. If users are free to request anything without restrictions, then administrators can create an empty DeviceClass for users to reference.
59    pub device_class_name: Option<std::string::String>,
60
61    /// FirstAvailable contains subrequests, of which exactly one will be satisfied by the scheduler to satisfy this request. It tries to satisfy them in the order in which they are listed here. So if there are two entries in the list, the scheduler will only check the second one if it determines that the first one cannot be used.
62    ///
63    /// This field may only be set in the entries of DeviceClaim.Requests.
64    ///
65    /// DRA does not yet implement scoring, so the scheduler will select the first set of devices that satisfies all the requests in the claim. And if the requirements can be satisfied on more than one node, other scheduling features will determine which node is chosen. This means that the set of devices allocated to a claim might not be the optimal set available to the cluster. Scoring will be implemented later.
66    pub first_available: Option<std::vec::Vec<crate::api::resource::v1beta1::DeviceSubRequest>>,
67
68    /// Name can be used to reference this request in a pod.spec.containers\[\].resources.claims entry and in a constraint of the claim.
69    ///
70    /// Must be a DNS label and unique among all DeviceRequests in a ResourceClaim.
71    pub name: std::string::String,
72
73    /// Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this request. All selectors must be satisfied for a device to be considered.
74    ///
75    /// This field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.
76    pub selectors: Option<std::vec::Vec<crate::api::resource::v1beta1::DeviceSelector>>,
77
78    /// If specified, the request's tolerations.
79    ///
80    /// Tolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.
81    ///
82    /// In addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.
83    ///
84    /// The maximum number of tolerations is 16.
85    ///
86    /// This field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.
87    ///
88    /// This is a beta field and requires enabling the DRADeviceTaints feature gate.
89    pub tolerations: Option<std::vec::Vec<crate::api::resource::v1beta1::DeviceToleration>>,
90}
91
92impl crate::DeepMerge for DeviceRequest {
93    fn merge_from(&mut self, other: Self) {
94        crate::DeepMerge::merge_from(&mut self.admin_access, other.admin_access);
95        crate::DeepMerge::merge_from(&mut self.allocation_mode, other.allocation_mode);
96        crate::DeepMerge::merge_from(&mut self.capacity, other.capacity);
97        crate::DeepMerge::merge_from(&mut self.count, other.count);
98        crate::merge_strategies::list::atomic(&mut self.derived_attributes, other.derived_attributes);
99        crate::DeepMerge::merge_from(&mut self.device_class_name, other.device_class_name);
100        crate::merge_strategies::list::atomic(&mut self.first_available, other.first_available);
101        crate::DeepMerge::merge_from(&mut self.name, other.name);
102        crate::merge_strategies::list::atomic(&mut self.selectors, other.selectors);
103        crate::merge_strategies::list::atomic(&mut self.tolerations, other.tolerations);
104    }
105}
106
107impl<'de> crate::serde::Deserialize<'de> for DeviceRequest {
108    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: crate::serde::Deserializer<'de> {
109        #[allow(non_camel_case_types)]
110        enum Field {
111            Key_admin_access,
112            Key_allocation_mode,
113            Key_capacity,
114            Key_count,
115            Key_derived_attributes,
116            Key_device_class_name,
117            Key_first_available,
118            Key_name,
119            Key_selectors,
120            Key_tolerations,
121            Other,
122        }
123
124        impl<'de> crate::serde::Deserialize<'de> for Field {
125            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: crate::serde::Deserializer<'de> {
126                struct Visitor;
127
128                impl crate::serde::de::Visitor<'_> for Visitor {
129                    type Value = Field;
130
131                    fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
132                        f.write_str("field identifier")
133                    }
134
135                    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: crate::serde::de::Error {
136                        Ok(match v {
137                            "adminAccess" => Field::Key_admin_access,
138                            "allocationMode" => Field::Key_allocation_mode,
139                            "capacity" => Field::Key_capacity,
140                            "count" => Field::Key_count,
141                            "derivedAttributes" => Field::Key_derived_attributes,
142                            "deviceClassName" => Field::Key_device_class_name,
143                            "firstAvailable" => Field::Key_first_available,
144                            "name" => Field::Key_name,
145                            "selectors" => Field::Key_selectors,
146                            "tolerations" => Field::Key_tolerations,
147                            _ => Field::Other,
148                        })
149                    }
150                }
151
152                deserializer.deserialize_identifier(Visitor)
153            }
154        }
155
156        struct Visitor;
157
158        impl<'de> crate::serde::de::Visitor<'de> for Visitor {
159            type Value = DeviceRequest;
160
161            fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
162                f.write_str("DeviceRequest")
163            }
164
165            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> where A: crate::serde::de::MapAccess<'de> {
166                let mut value_admin_access: Option<bool> = None;
167                let mut value_allocation_mode: Option<std::string::String> = None;
168                let mut value_capacity: Option<crate::api::resource::v1beta1::CapacityRequirements> = None;
169                let mut value_count: Option<i64> = None;
170                let mut value_derived_attributes: Option<std::vec::Vec<crate::api::resource::v1beta1::DeviceDerivedAttribute>> = None;
171                let mut value_device_class_name: Option<std::string::String> = None;
172                let mut value_first_available: Option<std::vec::Vec<crate::api::resource::v1beta1::DeviceSubRequest>> = None;
173                let mut value_name: Option<std::string::String> = None;
174                let mut value_selectors: Option<std::vec::Vec<crate::api::resource::v1beta1::DeviceSelector>> = None;
175                let mut value_tolerations: Option<std::vec::Vec<crate::api::resource::v1beta1::DeviceToleration>> = None;
176
177                while let Some(key) = crate::serde::de::MapAccess::next_key::<Field>(&mut map)? {
178                    match key {
179                        Field::Key_admin_access => value_admin_access = crate::serde::de::MapAccess::next_value(&mut map)?,
180                        Field::Key_allocation_mode => value_allocation_mode = crate::serde::de::MapAccess::next_value(&mut map)?,
181                        Field::Key_capacity => value_capacity = crate::serde::de::MapAccess::next_value(&mut map)?,
182                        Field::Key_count => value_count = crate::serde::de::MapAccess::next_value(&mut map)?,
183                        Field::Key_derived_attributes => value_derived_attributes = crate::serde::de::MapAccess::next_value(&mut map)?,
184                        Field::Key_device_class_name => value_device_class_name = crate::serde::de::MapAccess::next_value(&mut map)?,
185                        Field::Key_first_available => value_first_available = crate::serde::de::MapAccess::next_value(&mut map)?,
186                        Field::Key_name => value_name = crate::serde::de::MapAccess::next_value(&mut map)?,
187                        Field::Key_selectors => value_selectors = crate::serde::de::MapAccess::next_value(&mut map)?,
188                        Field::Key_tolerations => value_tolerations = crate::serde::de::MapAccess::next_value(&mut map)?,
189                        Field::Other => { let _: crate::serde::de::IgnoredAny = crate::serde::de::MapAccess::next_value(&mut map)?; },
190                    }
191                }
192
193                Ok(DeviceRequest {
194                    admin_access: value_admin_access,
195                    allocation_mode: value_allocation_mode,
196                    capacity: value_capacity,
197                    count: value_count,
198                    derived_attributes: value_derived_attributes,
199                    device_class_name: value_device_class_name,
200                    first_available: value_first_available,
201                    name: value_name.unwrap_or_default(),
202                    selectors: value_selectors,
203                    tolerations: value_tolerations,
204                })
205            }
206        }
207
208        deserializer.deserialize_struct(
209            "DeviceRequest",
210            &[
211                "adminAccess",
212                "allocationMode",
213                "capacity",
214                "count",
215                "derivedAttributes",
216                "deviceClassName",
217                "firstAvailable",
218                "name",
219                "selectors",
220                "tolerations",
221            ],
222            Visitor,
223        )
224    }
225}
226
227impl crate::serde::Serialize for DeviceRequest {
228    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: crate::serde::Serializer {
229        let mut state = serializer.serialize_struct(
230            "DeviceRequest",
231            1 +
232            self.admin_access.as_ref().map_or(0, |_| 1) +
233            self.allocation_mode.as_ref().map_or(0, |_| 1) +
234            self.capacity.as_ref().map_or(0, |_| 1) +
235            self.count.as_ref().map_or(0, |_| 1) +
236            self.derived_attributes.as_ref().map_or(0, |_| 1) +
237            self.device_class_name.as_ref().map_or(0, |_| 1) +
238            self.first_available.as_ref().map_or(0, |_| 1) +
239            self.selectors.as_ref().map_or(0, |_| 1) +
240            self.tolerations.as_ref().map_or(0, |_| 1),
241        )?;
242        if let Some(value) = &self.admin_access {
243            crate::serde::ser::SerializeStruct::serialize_field(&mut state, "adminAccess", value)?;
244        }
245        if let Some(value) = &self.allocation_mode {
246            crate::serde::ser::SerializeStruct::serialize_field(&mut state, "allocationMode", value)?;
247        }
248        if let Some(value) = &self.capacity {
249            crate::serde::ser::SerializeStruct::serialize_field(&mut state, "capacity", value)?;
250        }
251        if let Some(value) = &self.count {
252            crate::serde::ser::SerializeStruct::serialize_field(&mut state, "count", value)?;
253        }
254        if let Some(value) = &self.derived_attributes {
255            crate::serde::ser::SerializeStruct::serialize_field(&mut state, "derivedAttributes", value)?;
256        }
257        if let Some(value) = &self.device_class_name {
258            crate::serde::ser::SerializeStruct::serialize_field(&mut state, "deviceClassName", value)?;
259        }
260        if let Some(value) = &self.first_available {
261            crate::serde::ser::SerializeStruct::serialize_field(&mut state, "firstAvailable", value)?;
262        }
263        crate::serde::ser::SerializeStruct::serialize_field(&mut state, "name", &self.name)?;
264        if let Some(value) = &self.selectors {
265            crate::serde::ser::SerializeStruct::serialize_field(&mut state, "selectors", value)?;
266        }
267        if let Some(value) = &self.tolerations {
268            crate::serde::ser::SerializeStruct::serialize_field(&mut state, "tolerations", value)?;
269        }
270        crate::serde::ser::SerializeStruct::end(state)
271    }
272}
273
274#[cfg(feature = "schemars")]
275impl crate::schemars::JsonSchema for DeviceRequest {
276    fn schema_name() -> std::borrow::Cow<'static, str> {
277        "io.k8s.api.resource.v1beta1.DeviceRequest".into()
278    }
279
280    fn json_schema(__gen: &mut crate::schemars::SchemaGenerator) -> crate::schemars::Schema {
281        crate::schemars::json_schema!({
282            "description": "DeviceRequest is a request for devices required for a claim. This is typically a request for a single resource like a device, but can also ask for several identical devices.",
283            "type": "object",
284            "properties": {
285                "adminAccess": {
286                    "description": "AdminAccess indicates that this is a claim for administrative access to the device(s). Claims with AdminAccess are expected to be used for monitoring or other management services for a device.  They ignore all ordinary claims to the device with respect to access modes and any resource allocations.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.",
287                    "type": "boolean",
288                },
289                "allocationMode": {
290                    "description": "AllocationMode and its related fields define how devices are allocated to satisfy this request. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n  This is the default. The exact number is provided in the\n  count field.\n\n- All: This request is for all of the matching devices in a pool.\n  At least one device must exist on the node for the allocation to succeed.\n  Allocation will fail if some devices are already allocated,\n  unless adminAccess is requested.\n\nIf AllocationMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other requests must specify this field.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.",
291                    "type": "string",
292                },
293                "capacity": ({
294                    let mut schema_obj = __gen.subschema_for::<crate::api::resource::v1beta1::CapacityRequirements>();
295                    schema_obj.ensure_object().insert("description".into(), "Capacity define resource requirements against each capacity.\n\nIf this field is unset and the device supports multiple allocations, the default value will be applied to each capacity according to requestPolicy. For the capacity that has no requestPolicy, default is the full capacity value.\n\nApplies to each device allocation. If Count > 1, the request fails if there aren't enough devices that meet the requirements. If AllocationMode is set to All, the request fails if there are devices that otherwise match the request, and have this capacity, with a value >= the requested amount, but which cannot be allocated to this request.".into());
296                    schema_obj
297                }),
298                "count": {
299                    "description": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.",
300                    "type": "integer",
301                    "format": "int64",
302                },
303                "derivedAttributes": {
304                    "description": "DerivedAttributes defines a set of virtual attributes computed via CEL expressions for each candidate device. These virtual attributes can be referenced in `.devices.constraints` to align and match different devices (e.g., co-allocating a GPU and a NIC on the same NUMA node) even if their drivers publish different attributes. Derived attributes are not available via `device.attributes` in the CEL environment when evaluating selector expressions.\n\nDerived attributes allow you to extract, transform, or normalize topology information (such as extracting a NUMA index from a complex topology string or renaming a vendor-specific attribute) into a common virtual attribute name at scheduling time. The scheduler then evaluates these virtual attributes exactly like static attributes when matching constraints.\n\nEvery derived attribute defined in this list must be referenced by at least one MatchAttribute or DistinctAttribute constraint in the `.devices.constraints` list.\n\nThe maximum number of derived attributes is 32.\n\nThis is an alpha field and requires enabling the DRADerivedAttributes feature gate.",
305                    "type": "array",
306                    "items": (__gen.subschema_for::<crate::api::resource::v1beta1::DeviceDerivedAttribute>()),
307                },
308                "deviceClassName": {
309                    "description": "DeviceClassName references a specific DeviceClass, which can define additional configuration and selectors to be inherited by this request.\n\nA class is required if no subrequests are specified in the firstAvailable list and no class can be set if subrequests are specified in the firstAvailable list. Which classes are available depends on the cluster.\n\nAdministrators may use this to restrict which devices may get requested by only installing classes with selectors for permitted devices. If users are free to request anything without restrictions, then administrators can create an empty DeviceClass for users to reference.",
310                    "type": "string",
311                },
312                "firstAvailable": {
313                    "description": "FirstAvailable contains subrequests, of which exactly one will be satisfied by the scheduler to satisfy this request. It tries to satisfy them in the order in which they are listed here. So if there are two entries in the list, the scheduler will only check the second one if it determines that the first one cannot be used.\n\nThis field may only be set in the entries of DeviceClaim.Requests.\n\nDRA does not yet implement scoring, so the scheduler will select the first set of devices that satisfies all the requests in the claim. And if the requirements can be satisfied on more than one node, other scheduling features will determine which node is chosen. This means that the set of devices allocated to a claim might not be the optimal set available to the cluster. Scoring will be implemented later.",
314                    "type": "array",
315                    "items": (__gen.subschema_for::<crate::api::resource::v1beta1::DeviceSubRequest>()),
316                },
317                "name": {
318                    "description": "Name can be used to reference this request in a pod.spec.containers[].resources.claims entry and in a constraint of the claim.\n\nMust be a DNS label and unique among all DeviceRequests in a ResourceClaim.",
319                    "type": "string",
320                },
321                "selectors": {
322                    "description": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this request. All selectors must be satisfied for a device to be considered.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.",
323                    "type": "array",
324                    "items": (__gen.subschema_for::<crate::api::resource::v1beta1::DeviceSelector>()),
325                },
326                "tolerations": {
327                    "description": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nThis is a beta field and requires enabling the DRADeviceTaints feature gate.",
328                    "type": "array",
329                    "items": (__gen.subschema_for::<crate::api::resource::v1beta1::DeviceToleration>()),
330                },
331            },
332            "required": [
333                "name",
334            ],
335        })
336    }
337}