From 7f0413c84c4515cd2fae31d823613c4d7ea43110 Mon Sep 17 00:00:00 2001 From: Miguel Lavalle Date: Wed, 8 Jun 2022 18:23:25 -0500 Subject: [PATCH] Implement experimental features framework During the Zed PTG it was decided to handle unsupported features in Neutron as experimental. See section titled "When we say something is not supported?", day 2 in [1]. The agreement was: "We keep existing jobs for linuxbridge driver for example, but when the tests start to fail we skip them and finally we stop the job also. To make it clear for operators we add warning logs highlighting that the given feature/driver is experimental, and introduce cfg option to enable such features explicitly." This commit implements this agreement, initially with Linuxbridge Depends-On: https://review.opendev.org/c/openstack/neutron-tempest-plugin/+/845646 [1] https://lists.openstack.org/pipermail/openstack-discuss/2022-April/028164.html Change-Id: Ib18efa3f472736b58c8967847b1061da0e3897d7 --- .../admin/config-experimental-framework.rst | 37 ++++++++++++++++++ doc/source/admin/config.rst | 1 + etc/oslo-config-generator/neutron.conf | 1 + neutron/common/experimental.py | 39 +++++++++++++++++++ neutron/conf/experimental.py | 29 ++++++++++++++ neutron/opts.py | 9 +++++ .../mech_driver/mech_linuxbridge.py | 4 ++ neutron/tests/fullstack/resources/config.py | 3 ++ .../tests/fullstack/resources/environment.py | 4 +- neutron/tests/unit/extensions/test_segment.py | 6 +++ .../mech_driver/test_mech_linuxbridge.py | 32 ++++++++++++--- ...l-features-framework-8c34291b5b0be367.yaml | 19 +++++++++ setup.cfg | 1 + zuul.d/rally.yaml | 2 +- zuul.d/tempest-multinode.yaml | 2 +- 15 files changed, 181 insertions(+), 8 deletions(-) create mode 100644 doc/source/admin/config-experimental-framework.rst create mode 100644 neutron/common/experimental.py create mode 100644 neutron/conf/experimental.py create mode 100644 releasenotes/notes/Experimental-features-framework-8c34291b5b0be367.yaml diff --git a/doc/source/admin/config-experimental-framework.rst b/doc/source/admin/config-experimental-framework.rst new file mode 100644 index 00000000000..6d520ff6075 --- /dev/null +++ b/doc/source/admin/config-experimental-framework.rst @@ -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 + `_. + +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 diff --git a/doc/source/admin/config.rst b/doc/source/admin/config.rst index 4a617b96614..ddf57b2e37e 100644 --- a/doc/source/admin/config.rst +++ b/doc/source/admin/config.rst @@ -18,6 +18,7 @@ Configuration config-dns-int-ext-serv config-dns-res config-dvr-ha-snat + config-experimental-framework config-fip-port-forwardings config-ipam config-ipv6 diff --git a/etc/oslo-config-generator/neutron.conf b/etc/oslo-config-generator/neutron.conf index 9f3212badfe..599552e19ba 100644 --- a/etc/oslo-config-generator/neutron.conf +++ b/etc/oslo-config-generator/neutron.conf @@ -5,6 +5,7 @@ wrap_width = 79 namespace = neutron namespace = neutron.agent namespace = neutron.db +namespace = neutron.experimental namespace = neutron.extensions namespace = nova.auth namespace = ironic.auth diff --git a/neutron/common/experimental.py b/neutron/common/experimental.py new file mode 100644 index 00000000000..50dc2c48853 --- /dev/null +++ b/neutron/common/experimental.py @@ -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) diff --git a/neutron/conf/experimental.py b/neutron/conf/experimental.py new file mode 100644 index 00000000000..463ab4a88ba --- /dev/null +++ b/neutron/conf/experimental.py @@ -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) diff --git a/neutron/opts.py b/neutron/opts.py index 31f8fa88dcf..66592b35f69 100644 --- a/neutron/opts.py +++ b/neutron/opts.py @@ -37,6 +37,7 @@ import neutron.conf.db.l3_agentschedulers_db import neutron.conf.db.l3_dvr_db import neutron.conf.db.l3_gwmode_db import neutron.conf.db.l3_hamode_db +import neutron.conf.experimental import neutron.conf.extensions.allowedaddresspairs import neutron.conf.extensions.conntrack_helper import neutron.conf.plugins.ml2.config @@ -361,3 +362,11 @@ def list_sriov_agent_opts(): ('agent', 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) + ), + ] diff --git a/neutron/plugins/ml2/drivers/linuxbridge/mech_driver/mech_linuxbridge.py b/neutron/plugins/ml2/drivers/linuxbridge/mech_driver/mech_linuxbridge.py index c63da7fd2f4..12f21c354ad 100644 --- a/neutron/plugins/ml2/drivers/linuxbridge/mech_driver/mech_linuxbridge.py +++ b/neutron/plugins/ml2/drivers/linuxbridge/mech_driver/mech_linuxbridge.py @@ -17,6 +17,8 @@ from neutron_lib.api.definitions import portbindings from neutron_lib import constants 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.services.qos.drivers.linuxbridge import driver as lb_qos_driver @@ -32,6 +34,8 @@ class LinuxbridgeMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase): """ def __init__(self): + experimental.validate_experimental_enabled( + c_experimental.EXPERIMENTAL_LINUXBRIDGE) sg_enabled = securitygroups_rpc.is_firewall_enabled() vif_details = {portbindings.CAP_PORT_FILTER: sg_enabled, portbindings.VIF_DETAILS_CONNECTIVITY: diff --git a/neutron/tests/fullstack/resources/config.py b/neutron/tests/fullstack/resources/config.py index 42285e31607..3ebabd6fcd9 100644 --- a/neutron/tests/fullstack/resources/config.py +++ b/neutron/tests/fullstack/resources/config.py @@ -97,6 +97,9 @@ class NeutronConfigFixture(ConfigFixture): 'quotas': { 'quota_driver': env_desc.quota_driver }, + 'experimental': { + 'linuxbridge': str(env_desc.allow_experimental_linuxbridge) + }, }) if use_local_apipaste: diff --git a/neutron/tests/fullstack/resources/environment.py b/neutron/tests/fullstack/resources/environment.py index ce8c7a6495a..0f164f88d63 100644 --- a/neutron/tests/fullstack/resources/environment.py +++ b/neutron/tests/fullstack/resources/environment.py @@ -44,7 +44,8 @@ class EnvironmentDescription(object): dhcp_scheduler_class=None, ml2_extension_drivers=None, api_workers=1, 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.l2_pop = l2_pop self.qos = qos @@ -72,6 +73,7 @@ class EnvironmentDescription(object): if self.local_ip_ext: self.service_plugins += ',local_ip' self.quota_driver = quota_driver + self.allow_experimental_linuxbridge = allow_experimental_linuxbridge @property def tunneling_enabled(self): diff --git a/neutron/tests/unit/extensions/test_segment.py b/neutron/tests/unit/extensions/test_segment.py index 3a4d64e0d18..6b92e6f4b7f 100644 --- a/neutron/tests/unit/extensions/test_segment.py +++ b/neutron/tests/unit/extensions/test_segment.py @@ -36,6 +36,7 @@ from oslo_config import cfg from oslo_utils import uuidutils 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.drivers import driver_type from neutron.db import agents_db @@ -874,6 +875,11 @@ class TestMl2HostSegmentMappingOVS(HostSegmentMappingTestCase): class TestMl2HostSegmentMappingLinuxBridge(TestMl2HostSegmentMappingOVS): _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): helpers.register_linuxbridge_agent(host=host, bridge_mappings=mappings, diff --git a/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/mech_driver/test_mech_linuxbridge.py b/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/mech_driver/test_mech_linuxbridge.py index e7115080c3e..7e25f4d03a2 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/mech_driver/test_mech_linuxbridge.py +++ b/neutron/tests/unit/plugins/ml2/drivers/linuxbridge/mech_driver/test_mech_linuxbridge.py @@ -15,7 +15,9 @@ from neutron_lib.api.definitions import portbindings 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 \ import mech_linuxbridge from neutron.tests.unit.plugins.ml2 import _test_mech_agent as base @@ -65,24 +67,44 @@ class LinuxbridgeMechanismBaseTestCase(base.AgentMechanismBaseTestCase): class LinuxbridgeMechanismGenericTestCase(LinuxbridgeMechanismBaseTestCase, 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, 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, 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, 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, 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() diff --git a/releasenotes/notes/Experimental-features-framework-8c34291b5b0be367.yaml b/releasenotes/notes/Experimental-features-framework-8c34291b5b0be367.yaml new file mode 100644 index 00000000000..06e59ba2f28 --- /dev/null +++ b/releasenotes/notes/Experimental-features-framework-8c34291b5b0be367.yaml @@ -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 diff --git a/setup.cfg b/setup.cfg index 7dcc2507a2b..7f52a8138f1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -157,6 +157,7 @@ oslo.config.opts = neutron.base.agent = neutron.opts:list_base_agent_opts neutron.db = neutron.opts:list_db_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.l3.agent = neutron.opts:list_l3_agent_opts neutron.metadata.agent = neutron.opts:list_metadata_agent_opts diff --git a/zuul.d/rally.yaml b/zuul.d/rally.yaml index 14523bcb68a..3b8db37ed66 100644 --- a/zuul.d/rally.yaml +++ b/zuul.d/rally.yaml @@ -10,7 +10,7 @@ OSPROFILER_COLLECTOR: redis OSPROFILER_HMAC_KEYS: "neutron-hmac-key-used-in-zuul-ci" Q_ML2_TENANT_NETWORK_TYPE: vxlan - Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch,linuxbridge + Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch Q_AGENT: openvswitch KEYSTONE_ADMIN_ENDPOINT: true rally_task: rally-jobs/task-neutron.yaml diff --git a/zuul.d/tempest-multinode.yaml b/zuul.d/tempest-multinode.yaml index f185499faec..e672a33f654 100644 --- a/zuul.d/tempest-multinode.yaml +++ b/zuul.d/tempest-multinode.yaml @@ -178,7 +178,7 @@ DEFAULT_IMAGE_NAME: cirros-0.5.1-x86_64-uec DEFAULT_IMAGE_FILE_NAME: cirros-0.5.1-x86_64-uec.tar.gz Q_ML2_TENANT_NETWORK_TYPE: vxlan - Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch,linuxbridge + Q_ML2_PLUGIN_MECHANISM_DRIVERS: openvswitch Q_AGENT: openvswitch devstack_plugins: neutron: https://opendev.org/openstack/neutron.git