nova/nova/api/validation/extra_specs/hw.py

371 lines
12 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
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 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.'
),
value={
'type': str,
# NOTE(stephenfin): Yes, these things *have* to start with '^'
'pattern': r'\^\d+((-\d+)?(,\^?\d+(-\d+)?)?)*',
},
),
]
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.'
),
value={
'type': str,
'description': 'The CPU policy.',
'enum': [
'dedicated',
'shared'
],
},
),
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.'
),
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.'
),
value={
'type': str,
'description': 'The emulator thread policy.',
'enum': [
'isolate',
'share',
],
},
),
]
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)?)',
},
),
]
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.{id}',
description=(
'A mapping of **guest** CPUs to the **guest** NUMA node '
'identified by ``{id}``. 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.'
),
parameters=[
{
'name': 'id',
'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 ``{id}``.'
),
'pattern': r'\^?\d+((-\d+)?(,\^?\d+(-\d+)?)?)*',
},
),
base.ExtraSpecValidator(
name='hw:numa_mem.{id}',
description=(
'A mapping of **guest** memory to the **guest** NUMA node '
'identified by ``{id}``. 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.'
),
parameters=[
{
'name': 'id',
'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 ``{id}``.'
),
'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.'
),
value={
'type': str,
'description': 'The PCI NUMA affinity policy',
'enum': [
'required',
'preferred',
'legacy',
],
},
),
]
cpu_topology_validators = [
base.ExtraSpecValidator(
name='hw:cpu_sockets',
description=(
'The number of virtual CPU threads to emulate in the guest '
'CPU topology.'
),
value={
'type': int,
'description': 'A number of vurtla 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.'
),
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.'
),
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.'
),
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.'
),
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.'
),
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.'
),
value={
'type': bool,
'description': 'Whether to enable the boot menu',
},
),
base.ExtraSpecValidator(
name='hw:mem_encryption',
description=(
'Whether to enable memory encryption for the guest. Only '
'supported by the libvirt 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.'
),
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. Only supported by the libvirt 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:watchdog_action',
description=(
'The action to take when the watchdog timer is kicked. Only '
'supported by the libvirt virt driver.'
),
value={
'type': str,
'description': 'The action to take',
'enum': [
'none',
'pause',
'poweroff',
'reset',
'disabled',
],
},
),
]
def register():
return (
realtime_validators +
cpu_policy_validators +
hugepage_validators +
numa_validators +
cpu_topology_validators +
feature_flag_validators
)