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

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. 

14 

15"""Validators for ``hw`` namespaced extra specs.""" 

16 

17from nova.api.validation.extra_specs import base 

18from nova.objects import fields 

19 

20 

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] 

47 

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] 

62 

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] 

150 

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] 

179 

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] 

276 

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] 

369 

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] 

543 

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] 

568 

569 

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 )