# Example of interface_driver option for OVS based plugins(OVS, Ryu, NEC, NVP,
# BigSwitch/Floodlight)
-# interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver
+# interface_driver = openvswitch
# Name of Open vSwitch bridge to use
# ovs_integration_bridge = br-int
# ovs_use_veth = False
# Example of interface_driver option for LinuxBridge
-# interface_driver = neutron.agent.linux.interface.BridgeInterfaceDriver
+# interface_driver = linuxbridge
# The agent can use other DHCP drivers. Dnsmasq is the simplest and requires
# no additional setup of the DHCP server.
# Example of interface_driver option for OVS based plugins (OVS, Ryu, NEC)
# that supports L3 agent
-# interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver
+# interface_driver = openvswitch
# Use veth for an OVS interface or not.
# Support kernels with limited namespace support
# ovs_use_veth = False
# Example of interface_driver option for LinuxBridge
-# interface_driver = neutron.agent.linux.interface.BridgeInterfaceDriver
+# interface_driver = linuxbridge
# Allow overlapping IP (Must have kernel build with CONFIG_NET_NS=y and
# iproute2 package that supports namespaces). This option is deprecated and
from oslo_config import cfg
from oslo_log import log as logging
-from oslo_utils import importutils
from neutron.agent.common import config
+from neutron.common import utils as neutron_utils
from neutron.i18n import _LE
LOG = logging.getLogger(__name__)
config.register_root_helper(cfg.CONF)
+INTERFACE_NAMESPACE = 'neutron.interface_drivers'
+
execute = utils.execute
def load_interface_driver(conf):
- if not conf.interface_driver:
- LOG.error(_LE('An interface driver must be specified'))
- raise SystemExit(1)
+ """Load interface driver for agents like DHCP or L3 agent.
+
+ :param conf: driver configuration object
+ :raises SystemExit of 1 if driver cannot be loaded
+ """
+
try:
- return importutils.import_object(conf.interface_driver, conf)
- except ImportError as e:
- LOG.error(_LE("Error importing interface driver "
- "'%(driver)s': %(inner)s"),
- {'driver': conf.interface_driver,
- 'inner': e})
+ loaded_class = neutron_utils.load_class_by_alias_or_classname(
+ INTERFACE_NAMESPACE, conf.interface_driver)
+ return loaded_class(conf)
+ except ImportError:
+ LOG.error(_LE("Error loading interface driver '%s'"),
+ conf.interface_driver)
raise SystemExit(1)
import random
import signal
import socket
+import sys
import tempfile
import uuid
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import excutils
+from oslo_utils import importutils
import six
+from stevedore import driver
from neutron.common import constants as n_const
+from neutron.i18n import _LE
TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
LOG = logging.getLogger(__name__)
tmp_file.write(data)
os.chmod(tmp_file.name, 0o644)
os.rename(tmp_file.name, file_name)
+
+
+def load_class_by_alias_or_classname(namespace, name):
+ """Load class using stevedore alias or the class name
+ :param namespace: namespace where the alias is defined
+ :param name: alias or class name of the class to be loaded
+ :returns class if calls can be loaded
+ :raises ImportError if class cannot be loaded
+ """
+
+ if not name:
+ LOG.error(_LE("Alias or class name is not set"))
+ raise ImportError(_("Class not found."))
+ try:
+ # Try to resolve class by alias
+ mgr = driver.DriverManager(namespace, name)
+ class_to_load = mgr.driver
+ except RuntimeError:
+ e1_info = sys.exc_info()
+ # Fallback to class name
+ try:
+ class_to_load = importutils.import_class(name)
+ except (ImportError, ValueError):
+ LOG.error(_LE("Error loading class by alias"),
+ exc_info=e1_info)
+ LOG.error(_LE("Error loading class by class name"),
+ exc_info=True)
+ raise ImportError(_("Class not found."))
+ return class_to_load
# License for the specific language governing permissions and limitations
# under the License.
-import sys
import weakref
from oslo_config import cfg
from oslo_log import log as logging
import oslo_messaging
from oslo_service import periodic_task
-from oslo_utils import importutils
import six
from neutron.common import utils
from neutron.db import flavors_db
-from neutron.i18n import _LE, _LI
+from neutron.i18n import _LI
from neutron.plugins.common import constants
-from stevedore import driver
-
LOG = logging.getLogger(__name__)
@staticmethod
def load_class_for_provider(namespace, plugin_provider):
- if not plugin_provider:
- LOG.error(_LE("Error, plugin is not set"))
- raise ImportError(_("Plugin not found."))
+ """Loads plugin using alias or class name
+ :param namespace: namespace where alias is defined
+ :param plugin_provider: plugin alias or class name
+ :returns plugin that is loaded
+ :raises ImportError if fails to load plugin
+ """
+
try:
- # Try to resolve plugin by name
- mgr = driver.DriverManager(namespace, plugin_provider)
- plugin_class = mgr.driver
- except RuntimeError:
- e1_info = sys.exc_info()
- # fallback to class name
- try:
- plugin_class = importutils.import_class(plugin_provider)
- except ImportError:
- LOG.error(_LE("Error loading plugin by name"),
- exc_info=e1_info)
- LOG.error(_LE("Error loading plugin by class"),
- exc_info=True)
- raise ImportError(_("Plugin not found."))
- return plugin_class
+ return utils.load_class_by_alias_or_classname(namespace,
+ plugin_provider)
+ except ImportError:
+ raise ImportError(_("Plugin '%s' not found.") % plugin_provider)
def _get_plugin_instance(self, namespace, plugin_provider):
plugin_class = self.load_class_for_provider(namespace, plugin_provider)
def test_load_interface_driver_does_not_consume_irrelevant_errors(self):
self.conf.set_override('interface_driver',
'neutron.agent.linux.interface.NullDriver')
- with mock.patch('oslo_utils.importutils.import_object',
+ with mock.patch('oslo_utils.importutils.import_class',
side_effect=RuntimeError()):
with testlib_api.ExpectedException(RuntimeError):
utils.load_interface_driver(self.conf)
'neutron.agent.linux.interface.NullDriver')
self.assertIsInstance(utils.load_interface_driver(self.conf),
interface.NullDriver)
+
+ def test_load_null_interface_driver_success(self):
+ self.conf.set_override('interface_driver',
+ 'null')
+ self.assertIsInstance(utils.load_interface_driver(self.conf),
+ interface.NullDriver)
+
+ def test_load_ivs_interface_driver_success(self):
+ self.conf.set_override('interface_driver',
+ 'ivs')
+ self.assertIsInstance(utils.load_interface_driver(self.conf),
+ interface.IVSInterfaceDriver)
+
+ def test_load_linuxbridge_interface_driver_success(self):
+ self.conf.set_override('interface_driver',
+ 'linuxbridge')
+ self.assertIsInstance(utils.load_interface_driver(self.conf),
+ interface.BridgeInterfaceDriver)
+
+ def test_load_midonet_interface_driver_success(self):
+ self.conf.set_override('interface_driver',
+ 'midonet')
+ self.assertIsInstance(utils.load_interface_driver(self.conf),
+ interface.MidonetInterfaceDriver)
+
+ def test_load_ovs_interface_driver_success(self):
+ self.conf.set_override('interface_driver',
+ 'openvswitch')
+ self.assertIsInstance(utils.load_interface_driver(self.conf),
+ interface.OVSInterfaceDriver)
+
+ def test_load_interface_driver_as_alias_wrong_driver(self):
+ self.conf.set_override('interface_driver', 'openvswitchXX')
+ with testlib_api.ExpectedException(SystemExit):
+ utils.load_interface_driver(self.conf)
from neutron.plugins.common import constants
from neutron.tests import base
from neutron.tests.unit import dummy_plugin
+from neutron.tests.unit import testlib_api
LOG = logging.getLogger(__name__)
'dummy': 'dummy_agent_notifier'}
core_plugin = manager.NeutronManager.get_plugin()
self.assertEqual(expected, core_plugin.agent_notifiers)
+
+ def test_load_class_for_provider(self):
+ manager.NeutronManager.load_class_for_provider(
+ 'neutron.core_plugins', 'ml2')
+
+ def test_load_class_for_provider_wrong_plugin(self):
+ with testlib_api.ExpectedException(ImportError):
+ manager.NeutronManager.load_class_for_provider(
+ 'neutron.core_plugins', 'ml2XXXXXX')
neutron.openstack.common.notifier.test_notifier = oslo_messaging.notify._impl_test:TestDriver
neutron.db.alembic_migrations =
neutron = neutron.db.migration:alembic_migrations
+neutron.interface_drivers =
+ ivs = neutron.agent.linux.interface:IVSInterfaceDriver
+ linuxbridge = neutron.agent.linux.interface:BridgeInterfaceDriver
+ midonet = neutron.agent.linux.interface:MidonetInterfaceDriver
+ null = neutron.agent.linux.interface:NullDriver
+ openvswitch = neutron.agent.linux.interface:OVSInterfaceDriver
[build_sphinx]
all_files = 1