Coverage for nova/api/validation/extra_specs/hw.py: 100%
12 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-17 15:08 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-17 15:08 +0000
1# Copyright 2020 Red Hat, Inc. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
15"""Validators for ``hw`` namespaced extra specs."""
17from nova.api.validation.extra_specs import base
18from nova.objects import fields
21realtime_validators = [
22 base.ExtraSpecValidator(
23 name='hw:cpu_realtime',
24 description=(
25 'Determine whether realtime mode should be enabled for the '
26 'instance or not. '
27 'Only supported by the libvirt virt driver.'
28 ),
29 value={
30 'type': bool,
31 'description': 'Whether to enable realtime priority.',
32 },
33 ),
34 base.ExtraSpecValidator(
35 name='hw:cpu_realtime_mask',
36 description=(
37 'A exclusion mask of CPUs that should not be enabled for '
38 'realtime. '
39 'Only supported by the libvirt virt driver.'
40 ),
41 value={
42 'type': str,
43 'pattern': r'(\^)?\d+((-\d+)?(,\^?\d+(-\d+)?)?)*',
44 },
45 ),
46]
48hide_hypervisor_id_validator = [
49 base.ExtraSpecValidator(
50 name='hw:hide_hypervisor_id',
51 description=(
52 'Determine whether the hypervisor ID should be hidden from the '
53 'guest. '
54 'Only supported by the libvirt virt driver.'
55 ),
56 value={
57 'type': bool,
58 'description': 'Whether to hide the hypervisor ID.',
59 },
60 )
61]
63cpu_policy_validators = [
64 base.ExtraSpecValidator(
65 name='hw:cpu_policy',
66 description=(
67 'The policy to apply when determining what host CPUs the guest '
68 'CPUs can run on. '
69 'If ``shared`` (default), guest CPUs can be overallocated but '
70 'cannot float across host cores. '
71 'If ``dedicated``, guest CPUs cannot be overallocated but are '
72 'individually pinned to their own host core. '
73 'If ``mixed``, the policy for each instance CPU can be specified '
74 'using the ``hw:cpu_dedicated_mask`` or ``hw:cpu_realtime_mask`` '
75 'extra specs. '
76 'Only supported by the libvirt virt driver.'
77 ),
78 value={
79 'type': str,
80 'description': 'The CPU policy.',
81 'enum': [
82 'dedicated',
83 'shared',
84 'mixed',
85 ],
86 },
87 ),
88 base.ExtraSpecValidator(
89 name='hw:cpu_thread_policy',
90 description=(
91 'The policy to apply when determining whether the destination '
92 'host can have hardware threads enabled or not. '
93 'If ``prefer`` (default), hosts with hardware threads will be '
94 'preferred. '
95 'If ``require``, hosts with hardware threads will be required. '
96 'If ``isolate``, hosts with hardware threads will be forbidden. '
97 'Only supported by the libvirt virt driver.'
98 ),
99 value={
100 'type': str,
101 'description': 'The CPU thread policy.',
102 'enum': [
103 'prefer',
104 'isolate',
105 'require',
106 ],
107 },
108 ),
109 base.ExtraSpecValidator(
110 name='hw:emulator_threads_policy',
111 description=(
112 'The policy to apply when determining whether emulator threads '
113 'should be offloaded to a separate isolated core or to a pool '
114 'of shared cores. '
115 'If ``share``, emulator overhead threads will be offloaded to a '
116 'pool of shared cores. '
117 'If ``isolate``, emulator overhead threads will be offloaded to '
118 'their own core. '
119 'Only supported by the libvirt virt driver.'
120 ),
121 value={
122 'type': str,
123 'description': 'The emulator thread policy.',
124 'enum': [
125 'isolate',
126 'share',
127 ],
128 },
129 ),
130 base.ExtraSpecValidator(
131 name='hw:cpu_dedicated_mask',
132 description=(
133 'A mapping of **guest** (instance) CPUs to be pinned to **host** '
134 'CPUs for an instance with a ``mixed`` CPU policy. '
135 'Any **guest** CPUs which are not in this mapping will float '
136 'across host cores. '
137 'Only supported by the libvirt virt driver.'
138 ),
139 value={
140 'type': str,
141 'description': (
142 'The **guest** CPU mapping to be pinned to **host** CPUs for '
143 'an instance with a ``mixed`` CPU policy.'
144 ),
145 # This pattern is identical to 'hw:cpu_realtime_mask' pattern.
146 'pattern': r'\^?\d+((-\d+)?(,\^?\d+(-\d+)?)?)*',
147 },
148 ),
149]
151hugepage_validators = [
152 base.ExtraSpecValidator(
153 name='hw:mem_page_size',
154 description=(
155 'The size of memory pages to allocate to the guest with. '
156 'Can be one of the three alias - ``large``, ``small`` or '
157 '``any``, - or an actual size. '
158 'Only supported by the libvirt virt driver.'
159 ),
160 value={
161 'type': str,
162 'description': 'The size of memory page to allocate',
163 'pattern': r'(large|small|any|\d+([kKMGT]i?)?(b|bit|B)?)',
164 },
165 ),
166 base.ExtraSpecValidator(
167 name='hw:locked_memory',
168 description=(
169 'Determine if **guest** (instance) memory should be locked '
170 'preventing swapping. This is required in rare cases for device '
171 'DMA transfers. Only supported by the libvirt virt driver.'
172 ),
173 value={
174 'type': bool,
175 'description': 'Whether to lock **guest** (instance) memory.',
176 },
177 ),
178]
180numa_validators = [
181 base.ExtraSpecValidator(
182 name='hw:numa_nodes',
183 description=(
184 'The number of virtual NUMA nodes to allocate to configure the '
185 'guest with. '
186 'Each virtual NUMA node will be mapped to a unique host NUMA '
187 'node. '
188 'Only supported by the libvirt virt driver.'
189 ),
190 value={
191 'type': int,
192 'description': 'The number of virtual NUMA nodes to allocate',
193 'min': 1,
194 },
195 ),
196 base.ExtraSpecValidator(
197 name='hw:numa_cpus.{num}',
198 description=(
199 'A mapping of **guest** (instance) CPUs to the **guest** (not '
200 'host!) NUMA node identified by ``{num}``. '
201 'This can be used to provide asymmetric CPU-NUMA allocation and '
202 'is necessary where the number of guest NUMA nodes is not a '
203 'factor of the number of guest CPUs. '
204 'Only supported by the libvirt virt driver.'
205 ),
206 parameters=[
207 {
208 'name': 'num',
209 'pattern': r'\d+', # positive integers
210 'description': 'The ID of the **guest** NUMA node.',
211 },
212 ],
213 value={
214 'type': str,
215 'description': (
216 'The guest CPUs, in the form of a CPU map, to allocate to the '
217 'guest NUMA node identified by ``{num}``.'
218 ),
219 'pattern': r'\^?\d+((-\d+)?(,\^?\d+(-\d+)?)?)*',
220 },
221 ),
222 base.ExtraSpecValidator(
223 name='hw:numa_mem.{num}',
224 description=(
225 'A mapping of **guest** memory to the **guest** (not host!) NUMA '
226 'node identified by ``{num}``. '
227 'This can be used to provide asymmetric memory-NUMA allocation '
228 'and is necessary where the number of guest NUMA nodes is not a '
229 'factor of the total guest memory. '
230 'Only supported by the libvirt virt driver.'
231 ),
232 parameters=[
233 {
234 'name': 'num',
235 'pattern': r'\d+', # positive integers
236 'description': 'The ID of the **guest** NUMA node.',
237 },
238 ],
239 value={
240 'type': int,
241 'description': (
242 'The guest memory, in MB, to allocate to the guest NUMA node '
243 'identified by ``{num}``.'
244 ),
245 'min': 1,
246 },
247 ),
248 base.ExtraSpecValidator(
249 name='hw:pci_numa_affinity_policy',
250 description=(
251 'The NUMA affinity policy of any PCI passthrough devices or '
252 'SR-IOV network interfaces attached to the instance. '
253 'If ``required``, only PCI devices from one of the host NUMA '
254 'nodes the instance VCPUs are allocated from can be used by said '
255 'instance. '
256 'If ``preferred``, any PCI device can be used, though preference '
257 'will be given to those from the same NUMA node as the instance '
258 'VCPUs. '
259 'If ``legacy`` (default), behavior is as with ``required`` unless '
260 'the PCI device does not support provide NUMA affinity '
261 'information, in which case affinity is ignored. '
262 'Only supported by the libvirt virt driver.'
263 ),
264 value={
265 'type': str,
266 'description': 'The PCI NUMA affinity policy',
267 'enum': [
268 'required',
269 'preferred',
270 'legacy',
271 'socket',
272 ],
273 },
274 ),
275]
277cpu_topology_validators = [
278 base.ExtraSpecValidator(
279 name='hw:cpu_sockets',
280 description=(
281 'The number of virtual CPU threads to emulate in the guest '
282 'CPU topology. '
283 'Defaults to the number of vCPUs requested. '
284 'Only supported by the libvirt virt driver.'
285 ),
286 value={
287 'type': int,
288 'description': 'A number of virtual CPU sockets',
289 'min': 1,
290 },
291 ),
292 base.ExtraSpecValidator(
293 name='hw:cpu_cores',
294 description=(
295 'The number of virtual CPU cores to emulate per socket in the '
296 'guest CPU topology. '
297 'Defaults to ``1``. '
298 'Only supported by the libvirt virt driver. '
299 ),
300 value={
301 'type': int,
302 'description': 'A number of virtual CPU cores',
303 'min': 1,
304 },
305 ),
306 base.ExtraSpecValidator(
307 name='hw:cpu_threads',
308 description=(
309 'The number of virtual CPU threads to emulate per core in the '
310 'guest CPU topology. '
311 'Defaults to ``1``. '
312 'Only supported by the libvirt virt driver. '
313 ),
314 value={
315 'type': int,
316 'description': 'A number of virtual CPU threads',
317 'min': 1,
318 },
319 ),
320 base.ExtraSpecValidator(
321 name='hw:max_cpu_sockets',
322 description=(
323 'The max number of virtual CPU threads to emulate in the '
324 'guest CPU topology. '
325 'This is used to limit the topologies that can be requested by '
326 'an image and will be used to validate the ``hw_cpu_sockets`` '
327 'image metadata property. '
328 'Only supported by the libvirt virt driver. '
329 ),
330 value={
331 'type': int,
332 'description': 'A number of virtual CPU sockets',
333 'min': 1,
334 },
335 ),
336 base.ExtraSpecValidator(
337 name='hw:max_cpu_cores',
338 description=(
339 'The max number of virtual CPU cores to emulate per socket in the '
340 'guest CPU topology. '
341 'This is used to limit the topologies that can be requested by an '
342 'image and will be used to validate the ``hw_cpu_cores`` image '
343 'metadata property. '
344 'Only supported by the libvirt virt driver. '
345 ),
346 value={
347 'type': int,
348 'description': 'A number of virtual CPU cores',
349 'min': 1,
350 },
351 ),
352 base.ExtraSpecValidator(
353 name='hw:max_cpu_threads',
354 description=(
355 'The max number of virtual CPU threads to emulate per core in the '
356 'guest CPU topology. '
357 'This is used to limit the topologies that can be requested by an '
358 'image and will be used to validate the ``hw_cpu_threads`` image '
359 'metadata property. '
360 'Only supported by the libvirt virt driver. '
361 ),
362 value={
363 'type': int,
364 'description': 'A number of virtual CPU threads',
365 'min': 1,
366 },
367 ),
368]
370feature_flag_validators = [
371 # TODO(stephenfin): Consider deprecating and moving this to the 'os:'
372 # namespace
373 base.ExtraSpecValidator(
374 name='hw:boot_menu',
375 description=(
376 'Whether to show a boot menu when booting the guest. '
377 'Only supported by the libvirt virt driver. '
378 ),
379 value={
380 'type': bool,
381 'description': 'Whether to enable the boot menu',
382 },
383 ),
384 base.ExtraSpecValidator(
385 name='hw:vif_multiqueue_enabled',
386 description=(
387 'Whether to enable the virtio-net multiqueue feature. '
388 'When set, the driver sets the number of queues equal to the '
389 'number of guest vCPUs. This makes the network performance scale '
390 'across a number of vCPUs. This requires guest support and is '
391 'only supported by the libvirt driver.'
392 ),
393 value={
394 'type': bool,
395 'description': 'Whether to enable multiqueue',
396 },
397 ),
398 base.ExtraSpecValidator(
399 name='hw:mem_encryption',
400 description=(
401 'Whether to enable memory encryption for the guest. '
402 'Only supported by the libvirt virt driver on hosts with AMD SEV '
403 'support.'
404 ),
405 value={
406 'type': bool,
407 'description': 'Whether to enable memory encryption',
408 },
409 ),
410 base.ExtraSpecValidator(
411 name='hw:pmem',
412 description=(
413 'A comma-separated list of ``$LABEL``\\ s defined in config for '
414 'vPMEM devices. '
415 'Only supported by the libvirt virt driver on hosts with PMEM '
416 'devices.'
417 ),
418 value={
419 'type': str,
420 'description': (
421 'A comma-separated list of valid resource class names.'
422 ),
423 'pattern': '([a-zA-Z0-9_]+(,)?)+',
424 },
425 ),
426 base.ExtraSpecValidator(
427 name='hw:pmu',
428 description=(
429 'Whether to enable the Performance Monitory Unit (PMU) for the '
430 'guest. '
431 'If this option is not specified, the presence of the vPMU is '
432 'determined by the hypervisor. '
433 'The vPMU is used by tools like ``perf`` in the guest to provide '
434 'more accurate information for profiling application and '
435 'monitoring guest performance. '
436 'For realtime workloads, the emulation of a vPMU can introduce '
437 'additional latency which may be undesirable. '
438 'If the telemetry it provides is not required, such workloads '
439 'should disable this feature. '
440 'For most workloads, the default of unset will be correct. '
441 'Only supported by the libvirt virt driver.'
442 ),
443 value={
444 'type': bool,
445 'description': 'Whether to enable the PMU',
446 },
447 ),
448 base.ExtraSpecValidator(
449 name='hw:serial_port_count',
450 description=(
451 'The number of serial ports to allocate to the guest. '
452 'Only supported by the libvirt virt driver.'
453 ),
454 value={
455 'type': int,
456 'min': 0,
457 'description': 'The number of serial ports to allocate',
458 },
459 ),
460 base.ExtraSpecValidator(
461 name='hw:tpm_model',
462 description=(
463 'The model of the attached TPM device. '
464 'Only supported by the libvirt virt driver.'
465 ),
466 value={
467 'type': str,
468 'description': 'A TPM model',
469 'enum': [
470 'tpm-tis',
471 'tpm-crb',
472 ],
473 },
474 ),
475 base.ExtraSpecValidator(
476 name='hw:tpm_version',
477 description=(
478 "The TPM version. "
479 "Required if requesting a vTPM via the 'hw:tpm_model' extra spec "
480 "or equivalent image metadata property. "
481 "Only supported by the libvirt virt driver."
482 ),
483 value={
484 'type': str,
485 'description': 'A TPM version.',
486 'enum': [
487 '1.2',
488 '2.0',
489 ],
490 },
491 ),
492 base.ExtraSpecValidator(
493 name='hw:watchdog_action',
494 description=(
495 'The action to take when the watchdog timer is kicked. '
496 'Watchdog devices keep an eye on the instance and carry out the '
497 'specified action if the server hangs. '
498 'The watchdog uses the ``i6300esb`` device, emulating a PCI Intel '
499 '6300ESB. '
500 'Only supported by the libvirt virt driver.'
501 ),
502 value={
503 'type': str,
504 'description': 'The action to take',
505 'enum': [
506 'none',
507 'pause',
508 'poweroff',
509 'reset',
510 'disabled',
511 ],
512 },
513 ),
514 base.ExtraSpecValidator(
515 name='hw:viommu_model',
516 description=(
517 'This can be used to set model for virtual IOMMU device.'
518 ),
519 value={
520 'type': str,
521 'enum': [
522 'intel',
523 'smmuv3',
524 'virtio',
525 'auto'
526 ],
527 'description': 'model for vIOMMU',
528 },
529 ),
530 base.ExtraSpecValidator(
531 name='hw:virtio_packed_ring',
532 description=(
533 'Permit guests to negotiate the virtio packed ring format. '
534 'This requires guest support and is only supported by '
535 'the libvirt driver.'
536 ),
537 value={
538 'type': bool,
539 'description': 'Whether to enable packed virtqueue',
540 },
541 ),
542]
544ephemeral_encryption_validators = [
545 base.ExtraSpecValidator(
546 name='hw:ephemeral_encryption',
547 description=(
548 'Whether to enable ephemeral storage encryption.'
549 ),
550 value={
551 'type': bool,
552 'description': 'Whether to enable ephemeral storage encryption.',
553 },
554 ),
555 base.ExtraSpecValidator(
556 name='hw:ephemeral_encryption_format',
557 description=(
558 'The encryption format to be used if ephemeral storage '
559 'encryption is enabled via hw:ephemeral_encryption.'
560 ),
561 value={
562 'type': str,
563 'description': 'The encryption format to be used if enabled.',
564 'enum': fields.BlockDeviceEncryptionFormatType.ALL,
565 },
566 ),
567]
570def register():
571 return (
572 realtime_validators +
573 hide_hypervisor_id_validator +
574 cpu_policy_validators +
575 hugepage_validators +
576 numa_validators +
577 cpu_topology_validators +
578 feature_flag_validators +
579 ephemeral_encryption_validators
580 )