553 lines
19 KiB
Python
553 lines
19 KiB
Python
# Copyright 2020 Red Hat, Inc. All rights reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
"""Validators for ``hw`` namespaced extra specs."""
|
|
|
|
from nova.api.validation.extra_specs import base
|
|
from nova.objects import fields
|
|
|
|
|
|
realtime_validators = [
|
|
base.ExtraSpecValidator(
|
|
name='hw:cpu_realtime',
|
|
description=(
|
|
'Determine whether realtime mode should be enabled for the '
|
|
'instance or not. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': bool,
|
|
'description': 'Whether to enable realtime priority.',
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:cpu_realtime_mask',
|
|
description=(
|
|
'A exclusion mask of CPUs that should not be enabled for '
|
|
'realtime. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': str,
|
|
'pattern': r'(\^)?\d+((-\d+)?(,\^?\d+(-\d+)?)?)*',
|
|
},
|
|
),
|
|
]
|
|
|
|
hide_hypervisor_id_validator = [
|
|
base.ExtraSpecValidator(
|
|
name='hw:hide_hypervisor_id',
|
|
description=(
|
|
'Determine whether the hypervisor ID should be hidden from the '
|
|
'guest. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': bool,
|
|
'description': 'Whether to hide the hypervisor ID.',
|
|
},
|
|
)
|
|
]
|
|
|
|
cpu_policy_validators = [
|
|
base.ExtraSpecValidator(
|
|
name='hw:cpu_policy',
|
|
description=(
|
|
'The policy to apply when determining what host CPUs the guest '
|
|
'CPUs can run on. '
|
|
'If ``shared`` (default), guest CPUs can be overallocated but '
|
|
'cannot float across host cores. '
|
|
'If ``dedicated``, guest CPUs cannot be overallocated but are '
|
|
'individually pinned to their own host core. '
|
|
'If ``mixed``, the policy for each instance CPU can be specified '
|
|
'using the ``hw:cpu_dedicated_mask`` or ``hw:cpu_realtime_mask`` '
|
|
'extra specs.'
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': str,
|
|
'description': 'The CPU policy.',
|
|
'enum': [
|
|
'dedicated',
|
|
'shared',
|
|
'mixed',
|
|
],
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:cpu_thread_policy',
|
|
description=(
|
|
'The policy to apply when determining whether the destination '
|
|
'host can have hardware threads enabled or not. '
|
|
'If ``prefer`` (default), hosts with hardware threads will be '
|
|
'preferred. '
|
|
'If ``require``, hosts with hardware threads will be required. '
|
|
'If ``isolate``, hosts with hardware threads will be forbidden. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': str,
|
|
'description': 'The CPU thread policy.',
|
|
'enum': [
|
|
'prefer',
|
|
'isolate',
|
|
'require',
|
|
],
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:emulator_threads_policy',
|
|
description=(
|
|
'The policy to apply when determining whether emulator threads '
|
|
'should be offloaded to a separate isolated core or to a pool '
|
|
'of shared cores. '
|
|
'If ``share``, emulator overhead threads will be offloaded to a '
|
|
'pool of shared cores. '
|
|
'If ``isolate``, emulator overhead threads will be offloaded to '
|
|
'their own core. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': str,
|
|
'description': 'The emulator thread policy.',
|
|
'enum': [
|
|
'isolate',
|
|
'share',
|
|
],
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:cpu_dedicated_mask',
|
|
description=(
|
|
'A mapping of **guest** (instance) CPUs to be pinned to **host** '
|
|
'CPUs for an instance with a ``mixed`` CPU policy. '
|
|
'Any **guest** CPUs which are not in this mapping will float '
|
|
'across host cores. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': str,
|
|
'description': (
|
|
'The **guest** CPU mapping to be pinned to **host** CPUs for '
|
|
'an instance with a ``mixed`` CPU policy.'
|
|
),
|
|
# This pattern is identical to 'hw:cpu_realtime_mask' pattern.
|
|
'pattern': r'\^?\d+((-\d+)?(,\^?\d+(-\d+)?)?)*',
|
|
},
|
|
),
|
|
]
|
|
|
|
hugepage_validators = [
|
|
base.ExtraSpecValidator(
|
|
name='hw:mem_page_size',
|
|
description=(
|
|
'The size of memory pages to allocate to the guest with. '
|
|
'Can be one of the three alias - ``large``, ``small`` or '
|
|
'``any``, - or an actual size. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': str,
|
|
'description': 'The size of memory page to allocate',
|
|
'pattern': r'(large|small|any|\d+([kKMGT]i?)?(b|bit|B)?)',
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:locked_memory',
|
|
description=(
|
|
'Determine if **guest** (instance) memory should be locked '
|
|
'preventing swaping. This is required in rare cases for device '
|
|
'DMA transfers. Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': bool,
|
|
'description': 'Whether to lock **guest** (instance) memory.',
|
|
},
|
|
),
|
|
]
|
|
|
|
numa_validators = [
|
|
base.ExtraSpecValidator(
|
|
name='hw:numa_nodes',
|
|
description=(
|
|
'The number of virtual NUMA nodes to allocate to configure the '
|
|
'guest with. '
|
|
'Each virtual NUMA node will be mapped to a unique host NUMA '
|
|
'node. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': int,
|
|
'description': 'The number of virtual NUMA nodes to allocate',
|
|
'min': 1,
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:numa_cpus.{num}',
|
|
description=(
|
|
'A mapping of **guest** (instance) CPUs to the **guest** (not '
|
|
'host!) NUMA node identified by ``{num}``. '
|
|
'This can be used to provide asymmetric CPU-NUMA allocation and '
|
|
'is necessary where the number of guest NUMA nodes is not a '
|
|
'factor of the number of guest CPUs. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
parameters=[
|
|
{
|
|
'name': 'num',
|
|
'pattern': r'\d+', # positive integers
|
|
'description': 'The ID of the **guest** NUMA node.',
|
|
},
|
|
],
|
|
value={
|
|
'type': str,
|
|
'description': (
|
|
'The guest CPUs, in the form of a CPU map, to allocate to the '
|
|
'guest NUMA node identified by ``{num}``.'
|
|
),
|
|
'pattern': r'\^?\d+((-\d+)?(,\^?\d+(-\d+)?)?)*',
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:numa_mem.{num}',
|
|
description=(
|
|
'A mapping of **guest** memory to the **guest** (not host!) NUMA '
|
|
'node identified by ``{num}``. '
|
|
'This can be used to provide asymmetric memory-NUMA allocation '
|
|
'and is necessary where the number of guest NUMA nodes is not a '
|
|
'factor of the total guest memory. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
parameters=[
|
|
{
|
|
'name': 'num',
|
|
'pattern': r'\d+', # positive integers
|
|
'description': 'The ID of the **guest** NUMA node.',
|
|
},
|
|
],
|
|
value={
|
|
'type': int,
|
|
'description': (
|
|
'The guest memory, in MB, to allocate to the guest NUMA node '
|
|
'identified by ``{num}``.'
|
|
),
|
|
'min': 1,
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:pci_numa_affinity_policy',
|
|
description=(
|
|
'The NUMA affinity policy of any PCI passthrough devices or '
|
|
'SR-IOV network interfaces attached to the instance. '
|
|
'If ``required`, only PCI devices from one of the host NUMA '
|
|
'nodes the instance VCPUs are allocated from can be used by said '
|
|
'instance. '
|
|
'If ``preferred``, any PCI device can be used, though preference '
|
|
'will be given to those from the same NUMA node as the instance '
|
|
'VCPUs. '
|
|
'If ``legacy`` (default), behavior is as with ``required`` unless '
|
|
'the PCI device does not support provide NUMA affinity '
|
|
'information, in which case affinity is ignored. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': str,
|
|
'description': 'The PCI NUMA affinity policy',
|
|
'enum': [
|
|
'required',
|
|
'preferred',
|
|
'legacy',
|
|
'socket',
|
|
],
|
|
},
|
|
),
|
|
]
|
|
|
|
cpu_topology_validators = [
|
|
base.ExtraSpecValidator(
|
|
name='hw:cpu_sockets',
|
|
description=(
|
|
'The number of virtual CPU threads to emulate in the guest '
|
|
'CPU topology. '
|
|
'Defaults to the number of vCPUs requested. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': int,
|
|
'description': 'A number of virtual CPU sockets',
|
|
'min': 1,
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:cpu_cores',
|
|
description=(
|
|
'The number of virtual CPU cores to emulate per socket in the '
|
|
'guest CPU topology. '
|
|
'Defaults to ``1``.'
|
|
'Only supported by the libvirt virt driver. '
|
|
),
|
|
value={
|
|
'type': int,
|
|
'description': 'A number of virtual CPU cores',
|
|
'min': 1,
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:cpu_threads',
|
|
description=(
|
|
'The number of virtual CPU threads to emulate per core in the '
|
|
'guest CPU topology.'
|
|
'Defaults to ``1``. '
|
|
'Only supported by the libvirt virt driver. '
|
|
),
|
|
value={
|
|
'type': int,
|
|
'description': 'A number of virtual CPU threads',
|
|
'min': 1,
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:max_cpu_sockets',
|
|
description=(
|
|
'The max number of virtual CPU threads to emulate in the '
|
|
'guest CPU topology. '
|
|
'This is used to limit the topologies that can be requested by '
|
|
'an image and will be used to validate the ``hw_cpu_sockets`` '
|
|
'image metadata property. '
|
|
'Only supported by the libvirt virt driver. '
|
|
),
|
|
value={
|
|
'type': int,
|
|
'description': 'A number of virtual CPU sockets',
|
|
'min': 1,
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:max_cpu_cores',
|
|
description=(
|
|
'The max number of virtual CPU cores to emulate per socket in the '
|
|
'guest CPU topology. '
|
|
'This is used to limit the topologies that can be requested by an '
|
|
'image and will be used to validate the ``hw_cpu_cores`` image '
|
|
'metadata property. '
|
|
'Only supported by the libvirt virt driver. '
|
|
),
|
|
value={
|
|
'type': int,
|
|
'description': 'A number of virtual CPU cores',
|
|
'min': 1,
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:max_cpu_threads',
|
|
description=(
|
|
'The max number of virtual CPU threads to emulate per core in the '
|
|
'guest CPU topology. '
|
|
'This is used to limit the topologies that can be requested by an '
|
|
'image and will be used to validate the ``hw_cpu_threads`` image '
|
|
'metadata property. '
|
|
'Only supported by the libvirt virt driver. '
|
|
),
|
|
value={
|
|
'type': int,
|
|
'description': 'A number of virtual CPU threads',
|
|
'min': 1,
|
|
},
|
|
),
|
|
]
|
|
|
|
feature_flag_validators = [
|
|
# TODO(stephenfin): Consider deprecating and moving this to the 'os:'
|
|
# namespace
|
|
base.ExtraSpecValidator(
|
|
name='hw:boot_menu',
|
|
description=(
|
|
'Whether to show a boot menu when booting the guest. '
|
|
'Only supported by the libvirt virt driver. '
|
|
),
|
|
value={
|
|
'type': bool,
|
|
'description': 'Whether to enable the boot menu',
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:vif_multiqueue_enabled',
|
|
description=(
|
|
'Whether to enable the virtio-net multiqueue feature. '
|
|
'When set, the driver sets the number of queues equal to the '
|
|
'number of guest vCPUs. This makes the network performance scale '
|
|
'across a number of vCPUs. This requires guest support and is '
|
|
'only supported by the libvirt driver.'
|
|
),
|
|
value={
|
|
'type': bool,
|
|
'description': 'Whether to enable multiqueue',
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:mem_encryption',
|
|
description=(
|
|
'Whether to enable memory encryption for the guest. '
|
|
'Only supported by the libvirt virt driver on hosts with AMD SEV '
|
|
'support.'
|
|
),
|
|
value={
|
|
'type': bool,
|
|
'description': 'Whether to enable memory encryption',
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:pmem',
|
|
description=(
|
|
'A comma-separated list of ``$LABEL``\\ s defined in config for '
|
|
'vPMEM devices. '
|
|
'Only supported by the libvirt virt driver on hosts with PMEM '
|
|
'devices.'
|
|
),
|
|
value={
|
|
'type': str,
|
|
'description': (
|
|
'A comma-separated list of valid resource class names.'
|
|
),
|
|
'pattern': '([a-zA-Z0-9_]+(,)?)+',
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:pmu',
|
|
description=(
|
|
'Whether to enable the Performance Monitory Unit (PMU) for the '
|
|
'guest. '
|
|
'If this option is not specified, the presence of the vPMU is '
|
|
'determined by the hypervisor. '
|
|
'The vPMU is used by tools like ``perf`` in the guest to provide '
|
|
'more accurate information for profiling application and '
|
|
'monitoring guest performance. '
|
|
'For realtime workloads, the emulation of a vPMU can introduce '
|
|
'additional latency which may be undesirable. '
|
|
'If the telemetry it provides is not required, such workloads '
|
|
'should disable this feature. '
|
|
'For most workloads, the default of unset will be correct. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': bool,
|
|
'description': 'Whether to enable the PMU',
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:serial_port_count',
|
|
description=(
|
|
'The number of serial ports to allocate to the guest. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': int,
|
|
'min': 0,
|
|
'description': 'The number of serial ports to allocate',
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:tpm_model',
|
|
description=(
|
|
'The model of the attached TPM device. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': str,
|
|
'description': 'A TPM model',
|
|
'enum': [
|
|
'tpm-tis',
|
|
'tpm-crb',
|
|
],
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:tpm_version',
|
|
description=(
|
|
"The TPM version. "
|
|
"Required if requesting a vTPM via the 'hw:tpm_model' extra spec "
|
|
"or equivalent image metadata property. "
|
|
"Only supported by the libvirt virt driver."
|
|
),
|
|
value={
|
|
'type': str,
|
|
'description': 'A TPM version.',
|
|
'enum': [
|
|
'1.2',
|
|
'2.0',
|
|
],
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:watchdog_action',
|
|
description=(
|
|
'The action to take when the watchdog timer is kicked. '
|
|
'Watchdog devices keep an eye on the instance and carry out the '
|
|
'specified action if the server hangs. '
|
|
'The watchdog uses the ``i6300esb`` device, emulating a PCI Intel '
|
|
'6300ESB. '
|
|
'Only supported by the libvirt virt driver.'
|
|
),
|
|
value={
|
|
'type': str,
|
|
'description': 'The action to take',
|
|
'enum': [
|
|
'none',
|
|
'pause',
|
|
'poweroff',
|
|
'reset',
|
|
'disabled',
|
|
],
|
|
},
|
|
),
|
|
]
|
|
|
|
ephemeral_encryption_validators = [
|
|
base.ExtraSpecValidator(
|
|
name='hw:ephemeral_encryption',
|
|
description=(
|
|
'Whether to enable ephemeral storage encryption.'
|
|
),
|
|
value={
|
|
'type': bool,
|
|
'description': 'Whether to enable ephemeral storage encryption.',
|
|
},
|
|
),
|
|
base.ExtraSpecValidator(
|
|
name='hw:ephemeral_encryption_format',
|
|
description=(
|
|
'The encryption format to be used if ephemeral storage '
|
|
'encryption is enabled via hw:ephemeral_encryption.'
|
|
),
|
|
value={
|
|
'type': str,
|
|
'description': 'The encryption format to be used if enabled.',
|
|
'enum': fields.BlockDeviceEncryptionFormatType.ALL,
|
|
},
|
|
),
|
|
]
|
|
|
|
|
|
def register():
|
|
return (
|
|
realtime_validators +
|
|
hide_hypervisor_id_validator +
|
|
cpu_policy_validators +
|
|
hugepage_validators +
|
|
numa_validators +
|
|
cpu_topology_validators +
|
|
feature_flag_validators +
|
|
ephemeral_encryption_validators
|
|
)
|