Browse Source

Allow multiple binding drivers

In before, only one binding driver is allowed. This patch introduces
a new config to support multiple binding drivers. The first use case
is to allow SR-IOV binding to be co-existed with other binding.

* Rename the config 'driver' to 'default_driver' in 'binding' group.
  This is for making it clear that it is allowed to have more than
  one type of bindings.
* Introduce a new config called 'enabled_drivers'.
* Allow client to pass a driver name to port_bind and port_unbind.
  If this parameter is None, kuryr will load the default driver.

Partial-Implements: blueprint sriov-binding
Change-Id: I14b23379de9f2459ba97d5d82dfdb51553370cb1
Hongbin Lu 1 year ago
parent
commit
da736d115b

+ 22
- 5
kuryr/lib/binding/__init__.py View File

@@ -12,9 +12,17 @@
12 12
 from oslo_config import cfg
13 13
 from oslo_utils import importutils
14 14
 
15
+from kuryr.lib import exceptions
16
+
17
+
18
+def _verify_driver(driver):
19
+    if driver.__name__ not in cfg.CONF.binding.enabled_drivers:
20
+        raise exceptions.DriverNotEnabledException(
21
+            'Driver %s is not enabled' % driver.__name__)
22
+
15 23
 
16 24
 def port_bind(endpoint_id, port, subnets, network=None, vm_port=None,
17
-              segmentation_id=None, **kwargs):
25
+              segmentation_id=None, driver=None, **kwargs):
18 26
     """Binds the Neutron port to the network interface on the host.
19 27
 
20 28
     :param endpoint_id:   the ID of the endpoint as string
@@ -29,30 +37,39 @@ def port_bind(endpoint_id, port, subnets, network=None, vm_port=None,
29 37
                          port of a container which is running inside this Nova
30 38
                          instance (either ipvlan/macvlan or a subport).
31 39
     :param segmentation_id: ID of the segment for container traffic isolation)
40
+    :param driver:       the binding driver name
32 41
     :param kwargs:       Additional driver-specific arguments
33 42
     :returns: the tuple of the names of the veth pair and the tuple of stdout
34 43
               and stderr returned by processutils.execute invoked with the
35 44
               executable script for binding
36 45
     :raises: kuryr.common.exceptions.VethCreationFailure,
46
+             kuryr.common.exceptions.DriverNotEnabledException,
37 47
              processutils.ProcessExecutionError
38 48
     """
39
-    driver = importutils.import_module(cfg.CONF.binding.driver)
49
+    driver = importutils.import_module(
50
+        driver or cfg.CONF.binding.default_driver)
51
+    _verify_driver(driver)
52
+
40 53
     return driver.port_bind(endpoint_id, port, subnets, network=network,
41 54
                             vm_port=vm_port,
42 55
                             segmentation_id=segmentation_id,
43 56
                             **kwargs)
44 57
 
45 58
 
46
-def port_unbind(endpoint_id, neutron_port, **kwargs):
59
+def port_unbind(endpoint_id, neutron_port, driver=None, **kwargs):
47 60
     """Unbinds the Neutron port from the network interface on the host.
48 61
 
49 62
     :param endpoint_id: the ID of the Docker container as string
50 63
     :param neutron_port: a port dictionary returned from python-neutronclient
64
+    :param driver:       the binding driver name
51 65
     :param kwargs:       Additional driver-specific arguments
52 66
     :returns: the tuple of stdout and stderr returned by processutils.execute
53 67
               invoked with the executable script for unbinding
54
-    :raises: processutils.ProcessExecutionError, pyroute2.NetlinkError
68
+    :raises: processutils.ProcessExecutionError, pyroute2.NetlinkError,
69
+             kuryr.common.exceptions.DriverNotEnabledException,
55 70
     """
56
-    driver = importutils.import_module(cfg.CONF.binding.driver)
71
+    driver = importutils.import_module(
72
+        driver or cfg.CONF.binding.default_driver)
73
+    _verify_driver(driver)
57 74
 
58 75
     return driver.port_unbind(endpoint_id, neutron_port, **kwargs)

+ 5
- 1
kuryr/lib/config.py View File

@@ -68,9 +68,13 @@ binding_opts = [
68 68
                default='eth',
69 69
                help=_('The name prefix of the veth endpoint put inside the '
70 70
                       'container.')),
71
-    cfg.StrOpt('driver',
71
+    cfg.StrOpt('default_driver',
72 72
                default='kuryr.lib.binding.drivers.veth',
73
+               deprecated_name='driver',
73 74
                help=_('Driver to use for binding and unbinding ports.')),
75
+    cfg.ListOpt('enabled_drivers',
76
+                default=['kuryr.lib.binding.drivers.veth'],
77
+                help=_('Drivers to use for binding and unbinding ports.')),
74 78
     cfg.StrOpt('link_iface',
75 79
                default='',
76 80
                help=_('Specifies the name of the Nova instance interface to '

+ 8
- 0
kuryr/lib/exceptions.py View File

@@ -118,3 +118,11 @@ class AddressInUseException(KuryrException):
118 118
     This exception is thrown when a specific address is requested and the
119 119
     requested ip address already exists and is used.
120 120
     """
121
+
122
+
123
+class DriverNotEnabledException(KuryrException):
124
+    """Exception represents the binding driver is not enabled.
125
+
126
+    This exception is thrown when kuryr tries to load a specific binding driver
127
+    but the driver is not enabled.
128
+    """

+ 1
- 1
kuryr/lib/segmentation_type_drivers/__init__.py View File

@@ -22,7 +22,7 @@ _driver = ""
22 22
 def _get_driver():
23 23
     global _driver
24 24
     if not _driver:
25
-        driver_name = cfg.CONF.binding.driver.rsplit('.', 1)[1]
25
+        driver_name = cfg.CONF.binding.default_driver.rsplit('.', 1)[1]
26 26
 
27 27
         # REVISIT(vikasc): Need to remove this if check
28 28
         if driver_name == 'vlan':

+ 32
- 0
kuryr/tests/unit/binding/__init__.py View File

@@ -0,0 +1,32 @@
1
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+# not use this file except in compliance with the License. You may obtain
3
+# a copy of the License at
4
+#
5
+#      http://www.apache.org/licenses/LICENSE-2.0
6
+#
7
+# Unless required by applicable law or agreed to in writing, software
8
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+# License for the specific language governing permissions and limitations
11
+# under the License.
12
+
13
+from oslo_config import cfg
14
+from oslo_utils import importutils
15
+
16
+from kuryr.lib import binding
17
+from kuryr.lib import exceptions
18
+from kuryr.tests.unit import base
19
+
20
+
21
+class TestBinding(base.TestCase):
22
+    """Unit tests for binding module"""
23
+
24
+    def test__verify_driver(self):
25
+        cfg.CONF.set_override('enabled_drivers',
26
+                              ['kuryr.lib.binding.drivers.veth'],
27
+                              group='binding')
28
+        driver = importutils.import_module('kuryr.lib.binding.drivers.veth')
29
+        binding._verify_driver(driver)  # assert no exception raise
30
+        driver = importutils.import_module('kuryr.lib.binding.drivers.vlan')
31
+        self.assertRaises(exceptions.DriverNotEnabledException,
32
+                          binding._verify_driver, driver)

+ 1
- 1
kuryr/tests/unit/segmentation_type_drivers/test_vlan.py View File

@@ -29,7 +29,7 @@ class VlanSegmentationDriverTest(base.TestCase):
29 29
 
30 30
     def setUp(self):
31 31
         super(VlanSegmentationDriverTest, self).setUp()
32
-        cfg.CONF.binding.driver = 'kuryr.lib.binding.drivers.vlan'
32
+        cfg.CONF.binding.default_driver = 'kuryr.lib.binding.drivers.vlan'
33 33
 
34 34
     def test_allocate_segmentation_id(self):
35 35
         vlan_seg_driver = vlan.SegmentationDriver()

+ 1
- 1
kuryr/tests/unit/test_config.py View File

@@ -30,4 +30,4 @@ class ConfigurationTest(base.TestCase):
30 30
         self.assertEqual('baremetal',
31 31
                          cfg.CONF.deployment_type)
32 32
         self.assertEqual('kuryr.lib.binding.drivers.veth',
33
-                         cfg.CONF.binding.driver)
33
+                         cfg.CONF.binding.default_driver)

+ 11
- 0
releasenotes/notes/multiple-binding-driver-512a6a7f620c758e.yaml View File

@@ -0,0 +1,11 @@
1
+---
2
+features:
3
+  - |
4
+    Add support for multiple binding drivers. Introduce a new config
5
+    called 'enabled_drivers' which specifies a list of binding drivers
6
+    allowed to use.
7
+deprecations:
8
+  - |
9
+    Rename the config 'driver' to 'default_driver' in 'binding' group.
10
+    This is for making it clear that it is allowed to have more than
11
+    one type of bindings.

Loading…
Cancel
Save