Merge "Implement experimental features framework"
This commit is contained in:
commit
7c2896963f
37
doc/source/admin/config-experimental-framework.rst
Normal file
37
doc/source/admin/config-experimental-framework.rst
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
.. _config-experimental-framework:
|
||||||
|
|
||||||
|
===============================
|
||||||
|
Experimental features framework
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Some Neutron features are not supported because the community doesn't have
|
||||||
|
the resources and/or technical expertise to maintain them anymore. As they
|
||||||
|
arise, the Neutron team designates these features as experimental. Deployers
|
||||||
|
can continue using these features at their own risk, by explicitly enabling
|
||||||
|
them in the ``experimental`` section of ``neutron.conf``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Of course, the Neutron core team would love to return experimetal features
|
||||||
|
to the supported status, if interested parties step up to maintain them. If
|
||||||
|
you are interested in maintaining any of the experimental features listed
|
||||||
|
below, please contact the PTL shown in the
|
||||||
|
`Neutron project page
|
||||||
|
<https://governance.openstack.org/tc/reference/projects/neutron.html>`_.
|
||||||
|
|
||||||
|
The following table shows the Neutron features currently designated as
|
||||||
|
experimetal:
|
||||||
|
|
||||||
|
.. table:: **Neutron Experimental features**
|
||||||
|
|
||||||
|
========================= ===================================
|
||||||
|
Feature Option in neutron.conf to enable
|
||||||
|
========================= ===================================
|
||||||
|
ML2 Linuxbridge driver linuxbridge
|
||||||
|
========================= ===================================
|
||||||
|
|
||||||
|
This is an example of how to enable the use of an experimental feature:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
[experimental]
|
||||||
|
linuxbridge = true
|
@ -18,6 +18,7 @@ Configuration
|
|||||||
config-dns-int-ext-serv
|
config-dns-int-ext-serv
|
||||||
config-dns-res
|
config-dns-res
|
||||||
config-dvr-ha-snat
|
config-dvr-ha-snat
|
||||||
|
config-experimental-framework
|
||||||
config-fip-port-forwardings
|
config-fip-port-forwardings
|
||||||
config-ipam
|
config-ipam
|
||||||
config-ipv6
|
config-ipv6
|
||||||
|
@ -5,6 +5,7 @@ wrap_width = 79
|
|||||||
namespace = neutron
|
namespace = neutron
|
||||||
namespace = neutron.agent
|
namespace = neutron.agent
|
||||||
namespace = neutron.db
|
namespace = neutron.db
|
||||||
|
namespace = neutron.experimental
|
||||||
namespace = neutron.extensions
|
namespace = neutron.extensions
|
||||||
namespace = nova.auth
|
namespace = nova.auth
|
||||||
namespace = ironic.auth
|
namespace = ironic.auth
|
||||||
|
39
neutron/common/experimental.py
Normal file
39
neutron/common/experimental.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
from oslo_log import log
|
||||||
|
|
||||||
|
from neutron.conf import experimental
|
||||||
|
|
||||||
|
|
||||||
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
experimental.register_experimental_opts()
|
||||||
|
|
||||||
|
|
||||||
|
def validate_experimental_enabled(feature):
|
||||||
|
try:
|
||||||
|
is_enabled = cfg.CONF.experimental[feature]
|
||||||
|
except cfg.NoSuchOptError:
|
||||||
|
LOG.error("Experimental feature '%s' doesn't exist", feature)
|
||||||
|
raise SystemExit(1)
|
||||||
|
if is_enabled:
|
||||||
|
LOG.warning("Feature '%s' is unsupported and is treated as "
|
||||||
|
"experimental. Use at your own risk.", feature)
|
||||||
|
else:
|
||||||
|
LOG.error("Feature '%s' is experimental and has to be explicitly "
|
||||||
|
"enabled in 'cfg.CONF.experimental'", feature)
|
||||||
|
raise SystemExit(1)
|
29
neutron/conf/experimental.py
Normal file
29
neutron/conf/experimental.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
|
||||||
|
from neutron._i18n import _
|
||||||
|
|
||||||
|
EXPERIMENTAL_CFG_GROUP = 'experimental'
|
||||||
|
EXPERIMENTAL_LINUXBRIDGE = 'linuxbridge'
|
||||||
|
experimental_opts = [
|
||||||
|
cfg.BoolOpt(EXPERIMENTAL_LINUXBRIDGE,
|
||||||
|
default=False,
|
||||||
|
help=_('Enable execution of the experimental Linuxbridge '
|
||||||
|
'agent.')),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def register_experimental_opts(cfg=cfg.CONF):
|
||||||
|
cfg.register_opts(experimental_opts, EXPERIMENTAL_CFG_GROUP)
|
@ -37,6 +37,7 @@ import neutron.conf.db.l3_agentschedulers_db
|
|||||||
import neutron.conf.db.l3_dvr_db
|
import neutron.conf.db.l3_dvr_db
|
||||||
import neutron.conf.db.l3_gwmode_db
|
import neutron.conf.db.l3_gwmode_db
|
||||||
import neutron.conf.db.l3_hamode_db
|
import neutron.conf.db.l3_hamode_db
|
||||||
|
import neutron.conf.experimental
|
||||||
import neutron.conf.extensions.allowedaddresspairs
|
import neutron.conf.extensions.allowedaddresspairs
|
||||||
import neutron.conf.extensions.conntrack_helper
|
import neutron.conf.extensions.conntrack_helper
|
||||||
import neutron.conf.plugins.ml2.config
|
import neutron.conf.plugins.ml2.config
|
||||||
@ -361,3 +362,11 @@ def list_sriov_agent_opts():
|
|||||||
('agent',
|
('agent',
|
||||||
neutron.conf.agent.agent_extensions_manager.AGENT_EXT_MANAGER_OPTS)
|
neutron.conf.agent.agent_extensions_manager.AGENT_EXT_MANAGER_OPTS)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def list_experimental_opts():
|
||||||
|
return [
|
||||||
|
(neutron.conf.experimental.EXPERIMENTAL_CFG_GROUP,
|
||||||
|
itertools.chain(neutron.conf.experimental.experimental_opts)
|
||||||
|
),
|
||||||
|
]
|
||||||
|
@ -17,6 +17,8 @@ from neutron_lib.api.definitions import portbindings
|
|||||||
from neutron_lib import constants
|
from neutron_lib import constants
|
||||||
|
|
||||||
from neutron.agent import securitygroups_rpc
|
from neutron.agent import securitygroups_rpc
|
||||||
|
from neutron.common import experimental
|
||||||
|
from neutron.conf import experimental as c_experimental
|
||||||
from neutron.plugins.ml2.drivers import mech_agent
|
from neutron.plugins.ml2.drivers import mech_agent
|
||||||
from neutron.services.qos.drivers.linuxbridge import driver as lb_qos_driver
|
from neutron.services.qos.drivers.linuxbridge import driver as lb_qos_driver
|
||||||
|
|
||||||
@ -32,6 +34,8 @@ class LinuxbridgeMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
experimental.validate_experimental_enabled(
|
||||||
|
c_experimental.EXPERIMENTAL_LINUXBRIDGE)
|
||||||
sg_enabled = securitygroups_rpc.is_firewall_enabled()
|
sg_enabled = securitygroups_rpc.is_firewall_enabled()
|
||||||
vif_details = {portbindings.CAP_PORT_FILTER: sg_enabled,
|
vif_details = {portbindings.CAP_PORT_FILTER: sg_enabled,
|
||||||
portbindings.VIF_DETAILS_CONNECTIVITY:
|
portbindings.VIF_DETAILS_CONNECTIVITY:
|
||||||
|
@ -97,6 +97,9 @@ class NeutronConfigFixture(ConfigFixture):
|
|||||||
'quotas': {
|
'quotas': {
|
||||||
'quota_driver': env_desc.quota_driver
|
'quota_driver': env_desc.quota_driver
|
||||||
},
|
},
|
||||||
|
'experimental': {
|
||||||
|
'linuxbridge': str(env_desc.allow_experimental_linuxbridge)
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
if use_local_apipaste:
|
if use_local_apipaste:
|
||||||
|
@ -44,7 +44,8 @@ class EnvironmentDescription(object):
|
|||||||
dhcp_scheduler_class=None, ml2_extension_drivers=None,
|
dhcp_scheduler_class=None, ml2_extension_drivers=None,
|
||||||
api_workers=1,
|
api_workers=1,
|
||||||
enable_traditional_dhcp=True, local_ip_ext=False,
|
enable_traditional_dhcp=True, local_ip_ext=False,
|
||||||
quota_driver=quota_conf.QUOTA_DB_DRIVER):
|
quota_driver=quota_conf.QUOTA_DB_DRIVER,
|
||||||
|
allow_experimental_linuxbridge=True):
|
||||||
self.network_type = network_type
|
self.network_type = network_type
|
||||||
self.l2_pop = l2_pop
|
self.l2_pop = l2_pop
|
||||||
self.qos = qos
|
self.qos = qos
|
||||||
@ -72,6 +73,7 @@ class EnvironmentDescription(object):
|
|||||||
if self.local_ip_ext:
|
if self.local_ip_ext:
|
||||||
self.service_plugins += ',local_ip'
|
self.service_plugins += ',local_ip'
|
||||||
self.quota_driver = quota_driver
|
self.quota_driver = quota_driver
|
||||||
|
self.allow_experimental_linuxbridge = allow_experimental_linuxbridge
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tunneling_enabled(self):
|
def tunneling_enabled(self):
|
||||||
|
@ -36,6 +36,7 @@ from oslo_config import cfg
|
|||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
import webob.exc
|
import webob.exc
|
||||||
|
|
||||||
|
from neutron.conf import experimental as c_experimental
|
||||||
from neutron.conf.plugins.ml2 import config as ml2_config
|
from neutron.conf.plugins.ml2 import config as ml2_config
|
||||||
from neutron.conf.plugins.ml2.drivers import driver_type
|
from neutron.conf.plugins.ml2.drivers import driver_type
|
||||||
from neutron.db import agents_db
|
from neutron.db import agents_db
|
||||||
@ -874,6 +875,11 @@ class TestMl2HostSegmentMappingOVS(HostSegmentMappingTestCase):
|
|||||||
class TestMl2HostSegmentMappingLinuxBridge(TestMl2HostSegmentMappingOVS):
|
class TestMl2HostSegmentMappingLinuxBridge(TestMl2HostSegmentMappingOVS):
|
||||||
_mechanism_drivers = ['linuxbridge', 'logger']
|
_mechanism_drivers = ['linuxbridge', 'logger']
|
||||||
|
|
||||||
|
def setUp(self, plugin=None):
|
||||||
|
cfg.CONF.set_override(c_experimental.EXPERIMENTAL_LINUXBRIDGE, True,
|
||||||
|
group=c_experimental.EXPERIMENTAL_CFG_GROUP)
|
||||||
|
super(TestMl2HostSegmentMappingLinuxBridge, self).setUp(plugin=plugin)
|
||||||
|
|
||||||
def _register_agent(self, host, mappings=None, plugin=None):
|
def _register_agent(self, host, mappings=None, plugin=None):
|
||||||
helpers.register_linuxbridge_agent(host=host,
|
helpers.register_linuxbridge_agent(host=host,
|
||||||
bridge_mappings=mappings,
|
bridge_mappings=mappings,
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
|
|
||||||
from neutron_lib.api.definitions import portbindings
|
from neutron_lib.api.definitions import portbindings
|
||||||
from neutron_lib import constants
|
from neutron_lib import constants
|
||||||
|
from oslo_config import cfg
|
||||||
|
|
||||||
|
from neutron.conf import experimental as c_experimental
|
||||||
from neutron.plugins.ml2.drivers.linuxbridge.mech_driver \
|
from neutron.plugins.ml2.drivers.linuxbridge.mech_driver \
|
||||||
import mech_linuxbridge
|
import mech_linuxbridge
|
||||||
from neutron.tests.unit.plugins.ml2 import _test_mech_agent as base
|
from neutron.tests.unit.plugins.ml2 import _test_mech_agent as base
|
||||||
@ -65,24 +67,44 @@ class LinuxbridgeMechanismBaseTestCase(base.AgentMechanismBaseTestCase):
|
|||||||
|
|
||||||
class LinuxbridgeMechanismGenericTestCase(LinuxbridgeMechanismBaseTestCase,
|
class LinuxbridgeMechanismGenericTestCase(LinuxbridgeMechanismBaseTestCase,
|
||||||
base.AgentMechanismGenericTestCase):
|
base.AgentMechanismGenericTestCase):
|
||||||
pass
|
|
||||||
|
def setUp(self):
|
||||||
|
cfg.CONF.set_override(c_experimental.EXPERIMENTAL_LINUXBRIDGE, True,
|
||||||
|
group=c_experimental.EXPERIMENTAL_CFG_GROUP)
|
||||||
|
super(LinuxbridgeMechanismGenericTestCase, self).setUp()
|
||||||
|
|
||||||
|
|
||||||
class LinuxbridgeMechanismLocalTestCase(LinuxbridgeMechanismBaseTestCase,
|
class LinuxbridgeMechanismLocalTestCase(LinuxbridgeMechanismBaseTestCase,
|
||||||
base.AgentMechanismLocalTestCase):
|
base.AgentMechanismLocalTestCase):
|
||||||
pass
|
|
||||||
|
def setUp(self):
|
||||||
|
cfg.CONF.set_override(c_experimental.EXPERIMENTAL_LINUXBRIDGE, True,
|
||||||
|
group=c_experimental.EXPERIMENTAL_CFG_GROUP)
|
||||||
|
super(LinuxbridgeMechanismLocalTestCase, self).setUp()
|
||||||
|
|
||||||
|
|
||||||
class LinuxbridgeMechanismFlatTestCase(LinuxbridgeMechanismBaseTestCase,
|
class LinuxbridgeMechanismFlatTestCase(LinuxbridgeMechanismBaseTestCase,
|
||||||
base.AgentMechanismFlatTestCase):
|
base.AgentMechanismFlatTestCase):
|
||||||
pass
|
|
||||||
|
def setUp(self):
|
||||||
|
cfg.CONF.set_override(c_experimental.EXPERIMENTAL_LINUXBRIDGE, True,
|
||||||
|
group=c_experimental.EXPERIMENTAL_CFG_GROUP)
|
||||||
|
super(LinuxbridgeMechanismFlatTestCase, self).setUp()
|
||||||
|
|
||||||
|
|
||||||
class LinuxbridgeMechanismVlanTestCase(LinuxbridgeMechanismBaseTestCase,
|
class LinuxbridgeMechanismVlanTestCase(LinuxbridgeMechanismBaseTestCase,
|
||||||
base.AgentMechanismVlanTestCase):
|
base.AgentMechanismVlanTestCase):
|
||||||
pass
|
|
||||||
|
def setUp(self):
|
||||||
|
cfg.CONF.set_override(c_experimental.EXPERIMENTAL_LINUXBRIDGE, True,
|
||||||
|
group=c_experimental.EXPERIMENTAL_CFG_GROUP)
|
||||||
|
super(LinuxbridgeMechanismVlanTestCase, self).setUp()
|
||||||
|
|
||||||
|
|
||||||
class LinuxbridgeMechanismGreTestCase(LinuxbridgeMechanismBaseTestCase,
|
class LinuxbridgeMechanismGreTestCase(LinuxbridgeMechanismBaseTestCase,
|
||||||
base.AgentMechanismGreTestCase):
|
base.AgentMechanismGreTestCase):
|
||||||
pass
|
|
||||||
|
def setUp(self):
|
||||||
|
cfg.CONF.set_override(c_experimental.EXPERIMENTAL_LINUXBRIDGE, True,
|
||||||
|
group=c_experimental.EXPERIMENTAL_CFG_GROUP)
|
||||||
|
super(LinuxbridgeMechanismGreTestCase, self).setUp()
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
prelude: >
|
||||||
|
Introduce the experimental features framework.
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Some Neutron features are not supported due to lack of resources or
|
||||||
|
technical expertise to maintain them. As they arise, those features will
|
||||||
|
be marked as experimental by the Neutron core team.
|
||||||
|
Deployers will be able to continue using experimental features by
|
||||||
|
explicitly enabling them in the 'experimental' section of neutron.conf.
|
||||||
|
The ML2 linuxbridge driver is the first feature to be marked as
|
||||||
|
experimental. To continue using it, deployers have to set to True the
|
||||||
|
'linuxbridge' option in the 'experimental' section of neutron.conf.
|
||||||
|
deprecations:
|
||||||
|
- |
|
||||||
|
The ML2 linuxbridge agent has been marked as experimental due to lack
|
||||||
|
of resources to maintain it. To continue using it, deployers have to set
|
||||||
|
to True the 'linuxbridge' option in the 'experimental' section of
|
||||||
|
neutron.conf
|
@ -157,6 +157,7 @@ oslo.config.opts =
|
|||||||
neutron.base.agent = neutron.opts:list_base_agent_opts
|
neutron.base.agent = neutron.opts:list_base_agent_opts
|
||||||
neutron.db = neutron.opts:list_db_opts
|
neutron.db = neutron.opts:list_db_opts
|
||||||
neutron.dhcp.agent = neutron.opts:list_dhcp_agent_opts
|
neutron.dhcp.agent = neutron.opts:list_dhcp_agent_opts
|
||||||
|
neutron.experimental = neutron.opts:list_experimental_opts
|
||||||
neutron.extensions = neutron.opts:list_extension_opts
|
neutron.extensions = neutron.opts:list_extension_opts
|
||||||
neutron.l3.agent = neutron.opts:list_l3_agent_opts
|
neutron.l3.agent = neutron.opts:list_l3_agent_opts
|
||||||
neutron.metadata.agent = neutron.opts:list_metadata_agent_opts
|
neutron.metadata.agent = neutron.opts:list_metadata_agent_opts
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
OSPROFILER_COLLECTOR: redis
|
OSPROFILER_COLLECTOR: redis
|
||||||
OSPROFILER_HMAC_KEYS: "neutron-hmac-key-used-in-zuul-ci"
|
OSPROFILER_HMAC_KEYS: "neutron-hmac-key-used-in-zuul-ci"
|
||||||
Q_ML2_TENANT_NETWORK_TYPE: vxlan
|
Q_ML2_TENANT_NETWORK_TYPE: vxlan
|
||||||
Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch,linuxbridge
|
Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch
|
||||||
Q_AGENT: openvswitch
|
Q_AGENT: openvswitch
|
||||||
KEYSTONE_ADMIN_ENDPOINT: true
|
KEYSTONE_ADMIN_ENDPOINT: true
|
||||||
rally_task: rally-jobs/task-neutron.yaml
|
rally_task: rally-jobs/task-neutron.yaml
|
||||||
|
@ -178,7 +178,7 @@
|
|||||||
DEFAULT_IMAGE_NAME: cirros-0.5.1-x86_64-uec
|
DEFAULT_IMAGE_NAME: cirros-0.5.1-x86_64-uec
|
||||||
DEFAULT_IMAGE_FILE_NAME: cirros-0.5.1-x86_64-uec.tar.gz
|
DEFAULT_IMAGE_FILE_NAME: cirros-0.5.1-x86_64-uec.tar.gz
|
||||||
Q_ML2_TENANT_NETWORK_TYPE: vxlan
|
Q_ML2_TENANT_NETWORK_TYPE: vxlan
|
||||||
Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch,linuxbridge
|
Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch
|
||||||
Q_AGENT: openvswitch
|
Q_AGENT: openvswitch
|
||||||
devstack_plugins:
|
devstack_plugins:
|
||||||
neutron: https://opendev.org/openstack/neutron.git
|
neutron: https://opendev.org/openstack/neutron.git
|
||||||
|
Loading…
Reference in New Issue
Block a user