Add 'flavor-extra-spec-image-property-validation-extended' spec
It's quite a mouthful, yes. Blueprint: flavor-extra-spec-image-property-validation-extended Change-Id: I5912498e7f5f449c44884d93585362e1a04185a9 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
committed by
Eric Fried
parent
2b2bdfd49f
commit
9e4114fb49
@@ -0,0 +1,393 @@
|
||||
..
|
||||
This work is licensed under a Creative Commons Attribution 3.0 Unported
|
||||
License.
|
||||
|
||||
http://creativecommons.org/licenses/by/3.0/legalcode
|
||||
|
||||
=======================================
|
||||
Flavor Extra Spec Validation (Extended)
|
||||
=======================================
|
||||
|
||||
https://blueprints.launchpad.net/nova/+spec/flavor-extra-spec-image-property-validation-extended
|
||||
|
||||
Introduce a YAML-based schema describing flavor extra specs, image metadata
|
||||
properties, and the relationship between each.
|
||||
|
||||
Problem description
|
||||
===================
|
||||
|
||||
Flavor extra specs are one of the Wild West aspects of nova. There are a number
|
||||
of issues we'd like to address:
|
||||
|
||||
- Lack of documentation for many flavor extra specs and image metadata
|
||||
properties [1]_. Yes, we have Glance image metadata definitions but they're
|
||||
generally rather out-of-date, we don't/can't consume them in Nova, and
|
||||
they're not aimed towards user-facing documentation.
|
||||
|
||||
- Outdated, incomplete or incorrect Glance metadata definitions.
|
||||
|
||||
- No warnings if there is a typo in your extra spec, resulting in different
|
||||
behavior to that expected.
|
||||
|
||||
- No defined way to do things like deprecate a flavor extra spec, resulting in
|
||||
continued reinvention of the wheel.
|
||||
|
||||
Use Cases
|
||||
---------
|
||||
|
||||
* As a deployer, I'd like to know what flavor extra specs and image metadata
|
||||
properties are available and why I'd want to use them.
|
||||
|
||||
* As a deployer, I'd like nova to tell me when I've used a flavor extra spec
|
||||
that doesn't exist or has a typo in it.
|
||||
|
||||
* As a developer, I'd like an easy way to deprecate flavor extra specs, which
|
||||
is something that will only become more common if we do things like move
|
||||
tracking of dedicated CPUs into placement.
|
||||
|
||||
* As a documentation writer, I'd like to be able to cross-reference the various
|
||||
flavor extra specs and image metadata properties available.
|
||||
|
||||
Proposed change
|
||||
===============
|
||||
|
||||
A flavor extra spec is a key-value pair. For example::
|
||||
|
||||
hw:cpu_policy=dedicated
|
||||
|
||||
Different solutions are needed to validate the *value* part of an extra spec
|
||||
compared to the *key* part. This spec aims to tackle validation of both *key*
|
||||
and *value*, starting with the latter and then moving onto the former.
|
||||
|
||||
The following are considered out-of-scope for this change:
|
||||
|
||||
- Enforcement of extra spec dependencies. For example, if extra spec A requires
|
||||
extra spec B be configured first. We will document the dependency but it
|
||||
won't be enforced.
|
||||
|
||||
- Enforcement of virt driver dependencies. Unfortunately, while flavor extra
|
||||
specs should be generic, this isn't always the case. As above, we will
|
||||
document this dependency but it won't be enforced.
|
||||
|
||||
- Hard enforcement of key validation. Eventually we will want to track all
|
||||
possible extra spec names and raise a warning or error for errant values, but
|
||||
this is likely to take some time to perfect. In the interim, we will merely
|
||||
log these potentially errant values.
|
||||
|
||||
This change builds upon `Flavor extra spec image metadata validation
|
||||
<http://specs.openstack.org/openstack/nova-specs/specs/stein/approved/flavor-extra-spec-image-property-validation.html>`,
|
||||
which covers some of these issues for us.
|
||||
|
||||
Value validation
|
||||
----------------
|
||||
|
||||
Value validation is the easier of the two issues to tackle. It will resolve
|
||||
issues like the following in a generic manner::
|
||||
|
||||
hw:cpu_policy=deddddicated
|
||||
|
||||
For a generic extra spec, a definition of a validator will need to contain the
|
||||
following:
|
||||
|
||||
- Name or *key* of the extra spec, e.g. ``cpu_policy`` for the above example
|
||||
|
||||
- Namespace of the extra spec, e.g. ``hw`` for the above example
|
||||
|
||||
- Description of the extra spec
|
||||
|
||||
- Support status of the extra spec
|
||||
|
||||
- Valid values; whether it's an integer, a free-form string, a string matching
|
||||
a given regex, an enum, or something else entirely
|
||||
|
||||
- Virt driver dependencies; this is only for documentation purposes and will
|
||||
not be enforced
|
||||
|
||||
- Extra spec dependencies; this is only for documentation purposes and will not
|
||||
be enforced
|
||||
|
||||
For many extra specs namespaces, we propose maintaining the definitions
|
||||
in-tree. To do this, we propose adding a new module,
|
||||
``nova.api.validation.extra_specs``, which will contain definitions for *flavor
|
||||
validators*. These will be defined using two new base objects,
|
||||
``BaseValidator`` and ``BaseExtraSpec``. ``BaseValidator`` will be subclassed
|
||||
to represent a namespace while ``BaseExtraSpec`` will be subclassed to
|
||||
represent an individual extra spec. ``BaseExtraSpec`` subclasses will be
|
||||
registered again a namespace.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class HWValidator(BaseValidator):
|
||||
"""A validator for the ``hw`` namespace."""
|
||||
name = 'hw'
|
||||
description = (
|
||||
'Extra specs that modify behavior of the virtual hardware '
|
||||
'associated with instances.'
|
||||
)
|
||||
|
||||
class CPUPolicy(BaseExtraSpec):
|
||||
"""A validator for the ``hw:cpu_policy`` extra spec."""
|
||||
name = '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.'
|
||||
)
|
||||
deprecated = True
|
||||
value = {
|
||||
'type': str,
|
||||
'description': 'The CPU policy.',
|
||||
'enum': [
|
||||
'dedicated',
|
||||
'shared'
|
||||
],
|
||||
}
|
||||
|
||||
class NUMACPUs(BaseExtraSpec):
|
||||
"""A validator for the ``hw:numa_cpu.{id}`` extra spec."""
|
||||
name = 'numa_cpu.{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 is not a factor of the number of guest CPUs.'
|
||||
)
|
||||
params = [
|
||||
{
|
||||
'name': 'id',
|
||||
'type': int,
|
||||
'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+)?)?)*',
|
||||
}
|
||||
|
||||
register(HWValidator, CPUPolicy)
|
||||
register(HWValdiator, NUMACPUs)
|
||||
|
||||
While many of the definitions will be maintained in-tree, some namespaces will
|
||||
require special handling as they're owned by external services, e.g. the
|
||||
``traits`` namespace (owned by os-traits) or the ``accel`` namespace (proposed
|
||||
for use by cyborg). For these, we propose using `stevedore`_ to allow external
|
||||
projects to register custom validators. For example, nova would provide the
|
||||
following:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
nova.extra_spec_validators =
|
||||
hw = nova.api.validation.extra_specs:HWValidator
|
||||
os = nova.api.validation.extra_specs:OSValidator
|
||||
traits = nova.api.validation.extra_specs:TraitsValidator
|
||||
resources = nova.api.validation.extra_specs:ResourcesValidator
|
||||
custom = nova.validators.extra_specs:NoopValidator
|
||||
* = nova.validators.extra_specs:YAMLValidator
|
||||
|
||||
Cyborg could extend this by providing something like the following:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
nova.extra_spec_validators =
|
||||
accel = cyborg.extra_specs_validator:AccelValidator
|
||||
|
||||
Finally, there are extra specs that are operator defined and therefore will not
|
||||
be known by a consuming service. For these, we propose introducing a schema
|
||||
definition file. This a YAML-formatted file, which describes the flavor extra
|
||||
specs available. The YAML format is chosen as it allows us to define a
|
||||
specification in a declarative manner while avoiding the need to write Python
|
||||
code. The format of this file will nonetheless mirror the format of the Python
|
||||
objects. For example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
---
|
||||
version: 1.0
|
||||
metadata:
|
||||
- name: numa_nodes
|
||||
namspace: hw
|
||||
description: >
|
||||
The number of NUMA nodes the instance should have.
|
||||
value:
|
||||
type: integer
|
||||
description: >
|
||||
The number of NUMA nodes the instance should have.
|
||||
|
||||
- name: numa_cpus.{id}
|
||||
namspace: hw
|
||||
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 is not a
|
||||
factor of the number of guest CPUs.
|
||||
parameters:
|
||||
- name: id
|
||||
type: integer
|
||||
description: >
|
||||
The ID of the **guest** NUMA node.
|
||||
value:
|
||||
type: string
|
||||
format: '\d+((-\d+)?(,\^?\d+(-\d+)?)?)*'
|
||||
description: >
|
||||
The guest CPUs, in the form of a CPU map, to allocate to the guest
|
||||
NUMA node identified by ``{id}``.
|
||||
|
||||
Regardless of the source of the extra spec validator, they will be used by the
|
||||
API behind the :command:`openstack flavor set` command. A microversion will be
|
||||
introduced for this command to avoid breaking existing tools that are
|
||||
inadvertently setting the wrong values.
|
||||
|
||||
.. _stevedore: https://docs.openstack.org/stevedore/latest
|
||||
|
||||
Key validation
|
||||
--------------
|
||||
|
||||
We also want to be able to catch invalid extra specs themselves. It will
|
||||
resolve issues like the following in a generic manner::
|
||||
|
||||
hw:cpu_pollllicy=dedicated
|
||||
|
||||
This involves maintaining a registry of valid extra specs. Not all extra specs
|
||||
can be known ahead of time and for dynamic extra specs, such as those proposed
|
||||
in `Support filtering by forbidden aggregate membership
|
||||
<http://specs.openstack.org/openstack/nova-specs/specs/stein/approved/negative-aggregate-membership.html>`.
|
||||
For these, we can rely on a custom namespace validator or YAML specification
|
||||
provided by the operator. However, completing this registry both in-tree and
|
||||
out-of-tree is expected to be a complex endeavour and for this reason we won't
|
||||
enforce validation of keys as part of this spec.
|
||||
|
||||
Other changes
|
||||
-------------
|
||||
|
||||
We also propose adding tooling to (a) render reStructuredText documentation
|
||||
from the definitions and (b) convert the definitions into Glance metadata
|
||||
definition files. Both of these tools will live within the nova tree, allowing
|
||||
us to remain the single source of truth for these things.
|
||||
|
||||
Alternatives
|
||||
------------
|
||||
|
||||
* We could ignore some of the above issues and try to solve others in a
|
||||
piecemeal fashion. This will likely be far more tedious and time consuming as
|
||||
modifications will be needed in far more places.
|
||||
|
||||
Data model impact
|
||||
-----------------
|
||||
|
||||
None.
|
||||
|
||||
REST API impact
|
||||
---------------
|
||||
|
||||
We will add a REST API microversion to the ``POST
|
||||
flavors/{flavor_d}/os-extra_specs`` API to catch invalid flavor extra specs.
|
||||
|
||||
Security impact
|
||||
---------------
|
||||
|
||||
None.
|
||||
|
||||
Notifications impact
|
||||
--------------------
|
||||
|
||||
None.
|
||||
|
||||
Other end user impact
|
||||
---------------------
|
||||
|
||||
End users will have better documentation for the available flavor extra specs
|
||||
and image metadata properties.
|
||||
|
||||
Performance Impact
|
||||
------------------
|
||||
|
||||
None.
|
||||
|
||||
Other deployer impact
|
||||
---------------------
|
||||
|
||||
Operators will now need to add new flavor extra specs to the YAML schema file
|
||||
or they will see errors when using the new API microversion.
|
||||
|
||||
Developer impact
|
||||
----------------
|
||||
|
||||
Developers should now add new flavor extra specs to the
|
||||
``nova.compute.extra_specs`` module to take advantage of the validation
|
||||
available.
|
||||
|
||||
Upgrade impact
|
||||
--------------
|
||||
|
||||
None.
|
||||
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
Assignee(s)
|
||||
-----------
|
||||
|
||||
Primary assignee:
|
||||
stephenfinucane
|
||||
|
||||
Other contributors:
|
||||
None
|
||||
|
||||
Work Items
|
||||
----------
|
||||
|
||||
1. Produce extra spec definitions for all in-tree flavor extra specs.
|
||||
|
||||
2. Add code to validate this against the image metadata properties and flavor
|
||||
extra specs on instance create, resize and rebuild operations.
|
||||
|
||||
3. Add a Sphinx extension to render this spec into documentation and another
|
||||
tool to convert the spec into Glance metadata definitions.
|
||||
|
||||
4. Add parser for YAML-formatted definitions and document how operators can and
|
||||
should use this.
|
||||
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
||||
None.
|
||||
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
Unit tests.
|
||||
|
||||
|
||||
Documentation Impact
|
||||
====================
|
||||
|
||||
There will be better docs, through the power of Sphinx.
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [1] https://docs.openstack.org/image-guide/image-metadata.html#metadata-definition-service
|
||||
|
||||
|
||||
History
|
||||
=======
|
||||
|
||||
.. list-table:: Revisions
|
||||
:header-rows: 1
|
||||
|
||||
* - Release Name
|
||||
- Description
|
||||
* - Train
|
||||
- Introduced
|
||||
Reference in New Issue
Block a user