summaryrefslogtreecommitdiff
path: root/nova
diff options
context:
space:
mode:
authorStephen Finucane <sfinucan@redhat.com>2018-04-10 16:37:46 +0100
committerStephen Finucane <sfinucan@redhat.com>2018-07-24 15:33:49 +0100
commit9dfac2fda76a9bd7810d67f24e1b8ed5c16b549d (patch)
tree56b18595954304c7bfce41e45b66ced20786ecea /nova
parent50713f9cb77ef87002ec67a7c7bf33cfe0318404 (diff)
downloadnova-9dfac2fda76a9bd7810d67f24e1b8ed5c16b549d.tar.gz
conf: Add '[neutron] physnets' and related options
Things are getting a little bit magic here. We don't want to store inventory in configuration and we _really_ don't want to do so with another JSON blob a la the various '[pci]' options. Placement is not yet at a stage where we can avoid the former but we can certainly avoid the latter. Do so through adding some static opts and some dynamic filter configuration, similarly to what Cinder does for backend configuration using its 'enabled_backends' configuration option. None of this is actually used yet - that will come later. Part of blueprint numa-aware-vswitches Change-Id: Id7c2f0b53c8871ff47a836ec4c324c8cce430b79
Diffstat (limited to 'nova')
-rw-r--r--nova/compute/manager.py2
-rw-r--r--nova/conf/neutron.py56
-rw-r--r--nova/tests/unit/conf/__init__.py0
-rw-r--r--nova/tests/unit/conf/test_neutron.py33
4 files changed, 91 insertions, 0 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 539d59b77a..a6f3a5904a 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -1130,6 +1130,8 @@ class ComputeManager(manager.Manager):
# if the configuration is wrong.
whitelist.Whitelist(CONF.pci.passthrough_whitelist)
+ nova.conf.neutron.register_dynamic_opts(CONF)
+
self.driver.init_host(host=self.host)
context = nova.context.get_admin_context()
instances = objects.InstanceList.get_by_host(
diff --git a/nova/conf/neutron.py b/nova/conf/neutron.py
index 48cadc77ce..33fca355dd 100644
--- a/nova/conf/neutron.py
+++ b/nova/conf/neutron.py
@@ -77,6 +77,42 @@ needs to create a resource in Neutron it will requery Neutron for the
extensions that it has loaded. Setting value to 0 will refresh the
extensions with no wait.
"""),
+ cfg.ListOpt('physnets',
+ default=[],
+ help="""
+List of physnets present on this host.
+
+For each *physnet* listed, an additional section,
+``[neutron_physnet_$PHYSNET]``, will be added to the configuration file. Each
+section must be configured with a single configuration option, ``numa_nodes``,
+which should be a list of node IDs for all NUMA nodes this physnet is
+associated with. For example::
+
+ [neutron]
+ physnets = foo, bar
+
+ [neutron_physnet_foo]
+ numa_nodes = 0
+
+ [neutron_physnet_bar]
+ numa_nodes = 0,1
+
+Any *physnet* that is not listed using this option will be treated as having no
+particular NUMA node affinity.
+
+Tunnelled networks (VXLAN, GRE, ...) cannot be accounted for in this way and
+are instead configured using the ``[neutron_tunnel]`` group. For example::
+
+ [neutron_tunnel]
+ numa_nodes = 1
+
+Related options:
+
+* ``[neutron_tunnel] numa_nodes`` can be used to configure NUMA affinity for
+ all tunneled networks
+* ``[neutron_physnet_$PHYSNET] numa_nodes`` must be configured for each value
+ of ``$PHYSNET`` specified by this option
+"""),
]
metadata_proxy_opts = [
@@ -118,6 +154,26 @@ def register_opts(conf):
confutils.register_ksa_opts(conf, neutron_group, DEFAULT_SERVICE_TYPE)
+def register_dynamic_opts(conf):
+ """Register dynamically-generated options and groups.
+
+ This must be called by the service that wishes to use the options **after**
+ the initial configuration has been loaded.
+ """
+ opt = cfg.ListOpt('numa_nodes', default=[], item_type=cfg.types.Integer())
+
+ # Register the '[neutron_tunnel] numa_nodes' opt, implicitly
+ # registering the '[neutron_tunnel]' group in the process. This could
+ # be done statically but is done to avoid this group appearing in
+ # nova.conf documentation while the other group does not.
+ conf.register_opt(opt, group='neutron_tunnel')
+
+ # Register the '[neutron_physnet_$PHYSNET] numa_nodes' opts, implicitly
+ # registering the '[neutron_physnet_$PHYSNET]' groups in the process
+ for physnet in conf.neutron.physnets:
+ conf.register_opt(opt, group='neutron_physnet_%s' % physnet)
+
+
def list_opts():
return {
neutron_group: (
diff --git a/nova/tests/unit/conf/__init__.py b/nova/tests/unit/conf/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/nova/tests/unit/conf/__init__.py
diff --git a/nova/tests/unit/conf/test_neutron.py b/nova/tests/unit/conf/test_neutron.py
new file mode 100644
index 0000000000..b784486f9d
--- /dev/null
+++ b/nova/tests/unit/conf/test_neutron.py
@@ -0,0 +1,33 @@
+# Copyright 2018 Red Hat, Inc.
+#
+# 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.
+
+import nova.conf
+from nova import test
+
+
+CONF = nova.conf.CONF
+
+
+class NeutronConfTestCase(test.NoDBTestCase):
+
+ def test_register_dynamic_opts(self):
+ self.flags(physnets=['foo', 'bar', 'baz'], group='neutron')
+
+ self.assertNotIn('neutron_physnet_foo', CONF)
+ self.assertNotIn('neutron_physnet_bar', CONF)
+
+ nova.conf.neutron.register_dynamic_opts(CONF)
+
+ self.assertIn('neutron_physnet_foo', CONF)
+ self.assertIn('neutron_physnet_bar', CONF)