diff --git a/api-ref/source/baremetal-api-v1-nodes-traits.inc b/api-ref/source/baremetal-api-v1-nodes-traits.inc
index 5f98114239..ae4b54c545 100644
--- a/api-ref/source/baremetal-api-v1-nodes-traits.inc
+++ b/api-ref/source/baremetal-api-v1-nodes-traits.inc
@@ -11,6 +11,16 @@ attributes to influence the placement of instances to bare metal compute nodes.
Traits specified for a node in the Bare Metal service will be registered on the
corresponding resource provider in the Compute service's placement API.
+Traits can be either standard or custom. Standard traits are listed in the
+`os_traits library `_. Custom
+traits must meet the following requirements:
+
+* prefixed with ``CUSTOM_``
+* contain only upper case characters A to Z, digits 0 to 9, or underscores
+* no longer than 255 characters in length
+
+A bare metal node can have a maximum of 50 traits.
+
List Traits of a Node
=====================
diff --git a/doc/source/admin/notifications.rst b/doc/source/admin/notifications.rst
index 849c149b33..ff0131ff2b 100644
--- a/doc/source/admin/notifications.rst
+++ b/doc/source/admin/notifications.rst
@@ -132,7 +132,7 @@ Example of node CRUD notification::
"payload":{
"ironic_object.namespace":"ironic",
"ironic_object.name":"NodeCRUDPayload",
- "ironic_object.version":"1.3",
+ "ironic_object.version":"1.4",
"ironic_object.data":{
"chassis_uuid": "db0eef9d-45b2-4dc0-94a8-fc283c01171f",
"clean_step": None,
@@ -173,6 +173,9 @@ Example of node CRUD notification::
"resource_class": None,
"target_power_state": None,
"target_provision_state": "active",
+ "traits": [
+ "CUSTOM_TRAIT1",
+ "HW_CPU_X86_VMX"],
"updated_at": "2016-01-27T20:41:03+00:00",
"uuid": "1be26c0b-03f2-4d2e-ae87-c02d7f33c123"
}
@@ -355,7 +358,7 @@ node maintenance notification::
"payload":{
"ironic_object.namespace":"ironic",
"ironic_object.name":"NodePayload",
- "ironic_object.version":"1.5",
+ "ironic_object.version":"1.6",
"ironic_object.data":{
"clean_step": None,
"console_enabled": False,
@@ -392,6 +395,9 @@ node maintenance notification::
"resource_class": None,
"target_power_state": None,
"target_provision_state": None,
+ "traits": [
+ "CUSTOM_TRAIT1",
+ "HW_CPU_X86_VMX"],
"updated_at": "2016-01-27T20:41:03+00:00",
"uuid": "1be26c0b-03f2-4d2e-ae87-c02d7f33c123"
}
@@ -432,7 +438,7 @@ notification::
"payload":{
"ironic_object.namespace":"ironic",
"ironic_object.name":"NodePayload",
- "ironic_object.version":"1.5",
+ "ironic_object.version":"1.6",
"ironic_object.data":{
"clean_step": None,
"console_enabled": True,
@@ -469,6 +475,9 @@ notification::
"resource_class": None,
"target_power_state": None,
"target_provision_state": None,
+ "traits": [
+ "CUSTOM_TRAIT1",
+ "HW_CPU_X86_VMX"],
"updated_at": "2016-01-27T20:41:03+00:00",
"uuid": "1be26c0b-03f2-4d2e-ae87-c02d7f33c123"
}
@@ -502,7 +511,7 @@ ironic-conductor is attempting to change the node::
"payload":{
"ironic_object.namespace":"ironic",
"ironic_object.name":"NodeSetPowerStatePayload",
- "ironic_object.version":"1.5",
+ "ironic_object.version":"1.6",
"ironic_object.data":{
"clean_step": None,
"console_enabled": False,
@@ -538,6 +547,9 @@ ironic-conductor is attempting to change the node::
"resource_class": None,
"target_power_state": None,
"target_provision_state": None,
+ "traits": [
+ "CUSTOM_TRAIT1",
+ "HW_CPU_X86_VMX"],
"updated_at": "2016-01-27T20:41:03+00:00",
"uuid": "1be26c0b-03f2-4d2e-ae87-c02d7f33c123",
"to_power": "power on"
@@ -566,7 +578,7 @@ prior to the correction::
"payload":{
"ironic_object.namespace":"ironic",
"ironic_object.name":"NodeCorrectedPowerStatePayload",
- "ironic_object.version":"1.5",
+ "ironic_object.version":"1.6",
"ironic_object.data":{
"clean_step": None,
"console_enabled": False,
@@ -602,6 +614,9 @@ prior to the correction::
"resource_class": None,
"target_power_state": None,
"target_provision_state": None,
+ "traits": [
+ "CUSTOM_TRAIT1",
+ "HW_CPU_X86_VMX"],
"updated_at": "2016-01-27T20:41:03+00:00",
"uuid": "1be26c0b-03f2-4d2e-ae87-c02d7f33c123",
"from_power": "power on"
@@ -641,7 +656,7 @@ indicate a node's provision states before state change, "event" is the FSM
"payload":{
"ironic_object.namespace":"ironic",
"ironic_object.name":"NodeSetProvisionStatePayload",
- "ironic_object.version":"1.5",
+ "ironic_object.version":"1.6",
"ironic_object.data":{
"clean_step": None,
"console_enabled": False,
@@ -678,6 +693,9 @@ indicate a node's provision states before state change, "event" is the FSM
"resource_class": None,
"target_power_state": None,
"target_provision_state": "active",
+ "traits": [
+ "CUSTOM_TRAIT1",
+ "HW_CPU_X86_VMX"],
"updated_at": "2016-01-27T20:41:03+00:00",
"uuid": "1be26c0b-03f2-4d2e-ae87-c02d7f33c123",
"previous_provision_state": "available",
diff --git a/doc/source/install/configure-nova-flavors.rst b/doc/source/install/configure-nova-flavors.rst
index ba75728280..2310b46e65 100644
--- a/doc/source/install/configure-nova-flavors.rst
+++ b/doc/source/install/configure-nova-flavors.rst
@@ -104,3 +104,46 @@ the standard properties:
Note how ``baremetal.with-GPU`` in the node's ``resource_class`` field becomes
``CUSTOM_BAREMETAL_WITH_GPU`` in the flavor's properties.
+
+.. _scheduling-traits:
+
+Scheduling based on traits
+--------------------------
+
+Starting with the Queens release, the Compute service supports scheduling based
+on qualitative attributes using traits. Starting with Bare Metal REST API
+version 1.37, it is possible to assign a list of traits to each bare metal
+node. Traits assigned to a bare metal node will be assigned to the
+corresponding resource provider in the Compute service placement API.
+
+When creating a flavor in the Compute service, required traits may be specified
+via flavor properties. The Compute service will then schedule instances only
+to bare metal nodes with all of the required traits.
+
+Traits can be either standard or custom. Standard traits are listed in the
+`os_traits library `_. Custom
+traits must meet the following requirements:
+
+* prefixed with ``CUSTOM_``
+* contain only upper case characters A to Z, digits 0 to 9, or underscores
+* no longer than 255 characters in length
+
+A bare metal node can have a maximum of 50 traits.
+
+Example
+^^^^^^^
+
+To add the standard trait ``HW_CPU_X86_VMX`` and a custom trait
+``CUSTOM_TRAIT1`` to a node:
+
+.. code-block:: console
+
+ $ openstack --os-baremetal-api-version 1.37 baremetal node add trait \
+ $NODE_UUID CUSTOM_TRAIT1 HW_CPU_X86_VMX
+
+Then, update the flavor to require these traits:
+
+.. code-block:: console
+
+ $ nova flavor-key my-baremetal-flavor set trait:CUSTOM_TRAIT1=required
+ $ nova flavor-key my-baremetal-flavor set trait:HW_CPU_X86_VMX=required
diff --git a/doc/source/install/enrollment.rst b/doc/source/install/enrollment.rst
index 84992bb582..8d322f9293 100644
--- a/doc/source/install/enrollment.rst
+++ b/doc/source/install/enrollment.rst
@@ -369,6 +369,19 @@ Adding scheduling information
Some capabilities can also be discovered during `Hardware Inspection`_.
+#. If you wish to perform advanced scheduling of instances based on qualitative
+ attributes of bare metal nodes, you may add traits to each bare metal node
+ that will be exposed to the Compute scheduler (see: :ref:`scheduling-traits`
+ for a more in-depth discussion of traits in the Bare Metal service). For
+ example, to add the standard trait ``HW_CPU_X86_VMX`` and a custom trait
+ ``CUSTOM_TRAIT1`` to a node:
+
+ .. code-block:: console
+
+ $ openstack baremetal node add trait $NODE_UUID \
+ CUSTOM_TRAIT1 HW_CPU_X86_VMX
+
+
Validating node information
~~~~~~~~~~~~~~~~~~~~~~~~~~~