diff --git a/neutron/conf/plugins/ml2/drivers/ovn/ovn_conf.py b/neutron/conf/plugins/ml2/drivers/ovn/ovn_conf.py index e8652081904..7829fe95b44 100644 --- a/neutron/conf/plugins/ml2/drivers/ovn/ovn_conf.py +++ b/neutron/conf/plugins/ml2/drivers/ovn/ovn_conf.py @@ -197,6 +197,13 @@ ovn_opts = [ 'or by checking the output of the following command: \n' 'ovs-appctl -t ovs-vswitchd dpif/show-dp-features ' 'br-int | grep "Check pkt length action".')), + cfg.ListOpt('additional_worker_classes_with_ovn_idl', + default=[], + help=_('Additional worker classes to enable OVN IDLs for.\n' + 'By default only the API and maintenance workers ' + 'have access to the IDL connections. List additional ' + 'worker classes here if necessary. You can use aliases ' + 'from neutron.worker_classes.')), ] cfg.CONF.register_opts(ovn_opts, group='ovn') @@ -304,3 +311,7 @@ def is_ovn_emit_need_to_frag_enabled(): def is_igmp_snooping_enabled(): return cfg.CONF.OVS.igmp_snooping_enable + + +def additional_worker_classes_with_ovn_idl(): + return cfg.CONF.ovn.additional_worker_classes_with_ovn_idl diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py index d80dd53b444..5eae5a45af3 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py @@ -33,6 +33,7 @@ from neutron_lib import context as n_context from neutron_lib import exceptions as n_exc from neutron_lib.plugins import directory from neutron_lib.plugins.ml2 import api +from neutron_lib.utils import runtime from oslo_config import cfg from oslo_db import exception as os_db_exc from oslo_log import log @@ -275,8 +276,26 @@ class OVNMechanismDriver(api.MechanismDriver): @staticmethod def should_post_fork_initialize(worker_class): - return worker_class in (neutron.wsgi.WorkerService, - worker.MaintenanceWorker) + # By default only API and maintenace workers need to initialize + # the OVN IDL connections + if worker_class in (neutron.wsgi.WorkerService, + worker.MaintenanceWorker): + return True + + # Configuration may allow other worker types to use IDL connections. + # Look for a match in additional_worker_classes_with_ovn_idl, + # gracefully skipping unknown classes in the config list. + for worker_type in ovn_conf.additional_worker_classes_with_ovn_idl(): + try: + additional_class = runtime.load_class_by_alias_or_classname( + 'neutron.worker_classes', worker_type) + if worker_class == additional_class: + return True + except ImportError: + # ignore unknown additional worker class + pass + + return False def post_fork_initialize(self, resource, event, trigger, payload=None): # Initialize API/Maintenance workers with OVN IDL connections diff --git a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py index 525fd146f38..923e9d5fdc8 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py +++ b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py @@ -1977,6 +1977,56 @@ class TestOVNMechanismDriver(TestOVNMechanismDriverBase): expected_candidates = [ch0.name, ch2.name] self.assertEqual(sorted(expected_candidates), sorted(candidates)) + def _test_should_post_fork_initialize(self, enabled, disabled): + for worker_class in enabled: + self.assertTrue( + self.mech_driver.should_post_fork_initialize(worker_class)) + for worker_class in disabled: + self.assertFalse( + self.mech_driver.should_post_fork_initialize(worker_class)) + + def test_should_post_fork_initialize_default(self): + enabled = (mech_driver.neutron.wsgi.WorkerService, + mech_driver.worker.MaintenanceWorker) + disabled = (mech_driver.neutron.service.AllServicesNeutronWorker, + mech_driver.neutron.service.RpcWorker) + self._test_should_post_fork_initialize(enabled, disabled) + + def test_should_post_fork_initialize__allservices_worker(self): + ovn_conf.cfg.CONF.set_override( + 'additional_worker_classes_with_ovn_idl', + ['neutron.service.AllServicesNeutronWorker'], + group='ovn') + enabled = (mech_driver.neutron.wsgi.WorkerService, + mech_driver.worker.MaintenanceWorker, + mech_driver.neutron.service.AllServicesNeutronWorker) + disabled = (mech_driver.neutron.service.RpcWorker,) + self._test_should_post_fork_initialize(enabled, disabled) + + def test_should_post_fork_initialize__rpc_workers(self): + ovn_conf.cfg.CONF.set_override( + 'additional_worker_classes_with_ovn_idl', + ['RpcWorker'], + group='ovn') + enabled = (mech_driver.neutron.wsgi.WorkerService, + mech_driver.worker.MaintenanceWorker, + mech_driver.neutron.service.RpcWorker) + disabled = (mech_driver.neutron.service.AllServicesNeutronWorker,) + self._test_should_post_fork_initialize(enabled, disabled) + + def test_should_post_fork_initialize__bad_config(self): + # test that `should_post_fork_initialize` works even with + # unknown alias in additional_worker_classes_with_ovn_idl + ovn_conf.cfg.CONF.set_override( + 'additional_worker_classes_with_ovn_idl', + ['UnknownAlias'], + group='ovn') + enabled = (mech_driver.neutron.wsgi.WorkerService, + mech_driver.worker.MaintenanceWorker) + disabled = (mech_driver.neutron.service.AllServicesNeutronWorker, + mech_driver.neutron.service.RpcWorker) + self._test_should_post_fork_initialize(enabled, disabled) + class OVNMechanismDriverTestCase(test_plugin.Ml2PluginV2TestCase): _mechanism_drivers = ['logger', 'ovn'] diff --git a/releasenotes/notes/config-additional-workers-with-ovn-idl-022a2fb4bcf724ec.yaml b/releasenotes/notes/config-additional-workers-with-ovn-idl-022a2fb4bcf724ec.yaml new file mode 100644 index 00000000000..f009c4981e3 --- /dev/null +++ b/releasenotes/notes/config-additional-workers-with-ovn-idl-022a2fb4bcf724ec.yaml @@ -0,0 +1,7 @@ +--- +other: + - | + Added a new config option ``additional_worker_classes_with_ovn_idl`` + to allow initialization of OVN IDL connections for additional worker + classes. Can be used for plugins or extensions that need IDL connections + for other worker classes than API and maintenance workers. diff --git a/setup.cfg b/setup.cfg index b025f31f55d..51e78c106b7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -266,3 +266,9 @@ neutron.objects = Trunk = neutron.objects.trunk:Trunk neutron.status.upgrade.checks = neutron = neutron.cmd.upgrade_checks.checks:CoreChecks +neutron.worker_classes = + APIWorker = neutron.wsgi:WorkerService + RpcWorker = neutron.service:RpcWorker + RpcReportsWorker = neutron.service:RpcReportsWorker + AllServicesNeutronWorker = neutron.service:AllServicesNeutronWorker + MaintenanceWorker = neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb.worker:MaintenanceWorker