diff options
author | Hongbin Lu <hongbin.lu@huawei.com> | 2017-10-01 17:53:50 +0000 |
---|---|---|
committer | Hongbin Lu <hongbin034@gmail.com> | 2017-10-17 12:06:57 -0400 |
commit | da736d115bfeb10c9adf8d019696203bba5cbf8d (patch) | |
tree | 7394f9dd31e243723f7745e42886a06e46434e20 | |
parent | 4188f679d898300004a88f1f83275afc63d23baa (diff) |
Allow multiple binding drivers0.7.0
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
Notes
Notes (review):
Code-Review+2: Liping Mao <limao@cisco.com>
Code-Review+2: Berezovsky Irena <irenab.dev@gmail.com>
Workflow+1: Liping Mao <limao@cisco.com>
Verified+2: Zuul
Submitted-by: Zuul
Submitted-at: Wed, 18 Oct 2017 13:23:51 +0000
Reviewed-on: https://review.openstack.org/508778
Project: openstack/kuryr
Branch: refs/heads/master
-rw-r--r-- | kuryr/lib/binding/__init__.py | 27 | ||||
-rw-r--r-- | kuryr/lib/config.py | 6 | ||||
-rw-r--r-- | kuryr/lib/exceptions.py | 8 | ||||
-rw-r--r-- | kuryr/lib/segmentation_type_drivers/__init__.py | 2 | ||||
-rw-r--r-- | kuryr/tests/unit/binding/__init__.py | 32 | ||||
-rw-r--r-- | kuryr/tests/unit/segmentation_type_drivers/test_vlan.py | 2 | ||||
-rw-r--r-- | kuryr/tests/unit/test_config.py | 2 | ||||
-rw-r--r-- | releasenotes/notes/multiple-binding-driver-512a6a7f620c758e.yaml | 11 |
8 files changed, 81 insertions, 9 deletions
diff --git a/kuryr/lib/binding/__init__.py b/kuryr/lib/binding/__init__.py index 6834ef1..734f026 100644 --- a/kuryr/lib/binding/__init__.py +++ b/kuryr/lib/binding/__init__.py | |||
@@ -12,9 +12,17 @@ | |||
12 | from oslo_config import cfg | 12 | from oslo_config import cfg |
13 | from oslo_utils import importutils | 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 | def port_bind(endpoint_id, port, subnets, network=None, vm_port=None, | 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 | """Binds the Neutron port to the network interface on the host. | 26 | """Binds the Neutron port to the network interface on the host. |
19 | 27 | ||
20 | :param endpoint_id: the ID of the endpoint as string | 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 | port of a container which is running inside this Nova | 37 | port of a container which is running inside this Nova |
30 | instance (either ipvlan/macvlan or a subport). | 38 | instance (either ipvlan/macvlan or a subport). |
31 | :param segmentation_id: ID of the segment for container traffic isolation) | 39 | :param segmentation_id: ID of the segment for container traffic isolation) |
40 | :param driver: the binding driver name | ||
32 | :param kwargs: Additional driver-specific arguments | 41 | :param kwargs: Additional driver-specific arguments |
33 | :returns: the tuple of the names of the veth pair and the tuple of stdout | 42 | :returns: the tuple of the names of the veth pair and the tuple of stdout |
34 | and stderr returned by processutils.execute invoked with the | 43 | and stderr returned by processutils.execute invoked with the |
35 | executable script for binding | 44 | executable script for binding |
36 | :raises: kuryr.common.exceptions.VethCreationFailure, | 45 | :raises: kuryr.common.exceptions.VethCreationFailure, |
46 | kuryr.common.exceptions.DriverNotEnabledException, | ||
37 | processutils.ProcessExecutionError | 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 | return driver.port_bind(endpoint_id, port, subnets, network=network, | 53 | return driver.port_bind(endpoint_id, port, subnets, network=network, |
41 | vm_port=vm_port, | 54 | vm_port=vm_port, |
42 | segmentation_id=segmentation_id, | 55 | segmentation_id=segmentation_id, |
43 | **kwargs) | 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 | """Unbinds the Neutron port from the network interface on the host. | 60 | """Unbinds the Neutron port from the network interface on the host. |
48 | 61 | ||
49 | :param endpoint_id: the ID of the Docker container as string | 62 | :param endpoint_id: the ID of the Docker container as string |
50 | :param neutron_port: a port dictionary returned from python-neutronclient | 63 | :param neutron_port: a port dictionary returned from python-neutronclient |
64 | :param driver: the binding driver name | ||
51 | :param kwargs: Additional driver-specific arguments | 65 | :param kwargs: Additional driver-specific arguments |
52 | :returns: the tuple of stdout and stderr returned by processutils.execute | 66 | :returns: the tuple of stdout and stderr returned by processutils.execute |
53 | invoked with the executable script for unbinding | 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 | return driver.port_unbind(endpoint_id, neutron_port, **kwargs) | 75 | return driver.port_unbind(endpoint_id, neutron_port, **kwargs) |
diff --git a/kuryr/lib/config.py b/kuryr/lib/config.py index 413eb29..6e65558 100644 --- a/kuryr/lib/config.py +++ b/kuryr/lib/config.py | |||
@@ -68,9 +68,13 @@ binding_opts = [ | |||
68 | default='eth', | 68 | default='eth', |
69 | help=_('The name prefix of the veth endpoint put inside the ' | 69 | help=_('The name prefix of the veth endpoint put inside the ' |
70 | 'container.')), | 70 | 'container.')), |
71 | cfg.StrOpt('driver', | 71 | cfg.StrOpt('default_driver', |
72 | default='kuryr.lib.binding.drivers.veth', | 72 | default='kuryr.lib.binding.drivers.veth', |
73 | deprecated_name='driver', | ||
73 | help=_('Driver to use for binding and unbinding ports.')), | 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 | cfg.StrOpt('link_iface', | 78 | cfg.StrOpt('link_iface', |
75 | default='', | 79 | default='', |
76 | help=_('Specifies the name of the Nova instance interface to ' | 80 | help=_('Specifies the name of the Nova instance interface to ' |
diff --git a/kuryr/lib/exceptions.py b/kuryr/lib/exceptions.py index 60fbccd..e504241 100644 --- a/kuryr/lib/exceptions.py +++ b/kuryr/lib/exceptions.py | |||
@@ -118,3 +118,11 @@ class AddressInUseException(KuryrException): | |||
118 | This exception is thrown when a specific address is requested and the | 118 | This exception is thrown when a specific address is requested and the |
119 | requested ip address already exists and is used. | 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 | """ | ||
diff --git a/kuryr/lib/segmentation_type_drivers/__init__.py b/kuryr/lib/segmentation_type_drivers/__init__.py index ddef6a9..516beb8 100644 --- a/kuryr/lib/segmentation_type_drivers/__init__.py +++ b/kuryr/lib/segmentation_type_drivers/__init__.py | |||
@@ -22,7 +22,7 @@ _driver = "" | |||
22 | def _get_driver(): | 22 | def _get_driver(): |
23 | global _driver | 23 | global _driver |
24 | if not _driver: | 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 | # REVISIT(vikasc): Need to remove this if check | 27 | # REVISIT(vikasc): Need to remove this if check |
28 | if driver_name == 'vlan': | 28 | if driver_name == 'vlan': |
diff --git a/kuryr/tests/unit/binding/__init__.py b/kuryr/tests/unit/binding/__init__.py index e69de29..e6db7aa 100644 --- a/kuryr/tests/unit/binding/__init__.py +++ b/kuryr/tests/unit/binding/__init__.py | |||
@@ -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) | ||
diff --git a/kuryr/tests/unit/segmentation_type_drivers/test_vlan.py b/kuryr/tests/unit/segmentation_type_drivers/test_vlan.py index 15f0123..47f7fdf 100644 --- a/kuryr/tests/unit/segmentation_type_drivers/test_vlan.py +++ b/kuryr/tests/unit/segmentation_type_drivers/test_vlan.py | |||
@@ -29,7 +29,7 @@ class VlanSegmentationDriverTest(base.TestCase): | |||
29 | 29 | ||
30 | def setUp(self): | 30 | def setUp(self): |
31 | super(VlanSegmentationDriverTest, self).setUp() | 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 | def test_allocate_segmentation_id(self): | 34 | def test_allocate_segmentation_id(self): |
35 | vlan_seg_driver = vlan.SegmentationDriver() | 35 | vlan_seg_driver = vlan.SegmentationDriver() |
diff --git a/kuryr/tests/unit/test_config.py b/kuryr/tests/unit/test_config.py index 90cf118..9bf4efb 100644 --- a/kuryr/tests/unit/test_config.py +++ b/kuryr/tests/unit/test_config.py | |||
@@ -30,4 +30,4 @@ class ConfigurationTest(base.TestCase): | |||
30 | self.assertEqual('baremetal', | 30 | self.assertEqual('baremetal', |
31 | cfg.CONF.deployment_type) | 31 | cfg.CONF.deployment_type) |
32 | self.assertEqual('kuryr.lib.binding.drivers.veth', | 32 | self.assertEqual('kuryr.lib.binding.drivers.veth', |
33 | cfg.CONF.binding.driver) | 33 | cfg.CONF.binding.default_driver) |
diff --git a/releasenotes/notes/multiple-binding-driver-512a6a7f620c758e.yaml b/releasenotes/notes/multiple-binding-driver-512a6a7f620c758e.yaml new file mode 100644 index 0000000..e669e51 --- /dev/null +++ b/releasenotes/notes/multiple-binding-driver-512a6a7f620c758e.yaml | |||
@@ -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. | ||