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
This commit is contained in:
parent
4188f679d8
commit
da736d115b
|
@ -12,9 +12,17 @@
|
|||
from oslo_config import cfg
|
||||
from oslo_utils import importutils
|
||||
|
||||
from kuryr.lib import exceptions
|
||||
|
||||
|
||||
def _verify_driver(driver):
|
||||
if driver.__name__ not in cfg.CONF.binding.enabled_drivers:
|
||||
raise exceptions.DriverNotEnabledException(
|
||||
'Driver %s is not enabled' % driver.__name__)
|
||||
|
||||
|
||||
def port_bind(endpoint_id, port, subnets, network=None, vm_port=None,
|
||||
segmentation_id=None, **kwargs):
|
||||
segmentation_id=None, driver=None, **kwargs):
|
||||
"""Binds the Neutron port to the network interface on the host.
|
||||
|
||||
: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,
|
|||
port of a container which is running inside this Nova
|
||||
instance (either ipvlan/macvlan or a subport).
|
||||
:param segmentation_id: ID of the segment for container traffic isolation)
|
||||
:param driver: the binding driver name
|
||||
:param kwargs: Additional driver-specific arguments
|
||||
:returns: the tuple of the names of the veth pair and the tuple of stdout
|
||||
and stderr returned by processutils.execute invoked with the
|
||||
executable script for binding
|
||||
:raises: kuryr.common.exceptions.VethCreationFailure,
|
||||
kuryr.common.exceptions.DriverNotEnabledException,
|
||||
processutils.ProcessExecutionError
|
||||
"""
|
||||
driver = importutils.import_module(cfg.CONF.binding.driver)
|
||||
driver = importutils.import_module(
|
||||
driver or cfg.CONF.binding.default_driver)
|
||||
_verify_driver(driver)
|
||||
|
||||
return driver.port_bind(endpoint_id, port, subnets, network=network,
|
||||
vm_port=vm_port,
|
||||
segmentation_id=segmentation_id,
|
||||
**kwargs)
|
||||
|
||||
|
||||
def port_unbind(endpoint_id, neutron_port, **kwargs):
|
||||
def port_unbind(endpoint_id, neutron_port, driver=None, **kwargs):
|
||||
"""Unbinds the Neutron port from the network interface on the host.
|
||||
|
||||
:param endpoint_id: the ID of the Docker container as string
|
||||
:param neutron_port: a port dictionary returned from python-neutronclient
|
||||
:param driver: the binding driver name
|
||||
:param kwargs: Additional driver-specific arguments
|
||||
:returns: the tuple of stdout and stderr returned by processutils.execute
|
||||
invoked with the executable script for unbinding
|
||||
:raises: processutils.ProcessExecutionError, pyroute2.NetlinkError
|
||||
:raises: processutils.ProcessExecutionError, pyroute2.NetlinkError,
|
||||
kuryr.common.exceptions.DriverNotEnabledException,
|
||||
"""
|
||||
driver = importutils.import_module(cfg.CONF.binding.driver)
|
||||
driver = importutils.import_module(
|
||||
driver or cfg.CONF.binding.default_driver)
|
||||
_verify_driver(driver)
|
||||
|
||||
return driver.port_unbind(endpoint_id, neutron_port, **kwargs)
|
||||
|
|
|
@ -68,9 +68,13 @@ binding_opts = [
|
|||
default='eth',
|
||||
help=_('The name prefix of the veth endpoint put inside the '
|
||||
'container.')),
|
||||
cfg.StrOpt('driver',
|
||||
cfg.StrOpt('default_driver',
|
||||
default='kuryr.lib.binding.drivers.veth',
|
||||
deprecated_name='driver',
|
||||
help=_('Driver to use for binding and unbinding ports.')),
|
||||
cfg.ListOpt('enabled_drivers',
|
||||
default=['kuryr.lib.binding.drivers.veth'],
|
||||
help=_('Drivers to use for binding and unbinding ports.')),
|
||||
cfg.StrOpt('link_iface',
|
||||
default='',
|
||||
help=_('Specifies the name of the Nova instance interface to '
|
||||
|
|
|
@ -118,3 +118,11 @@ class AddressInUseException(KuryrException):
|
|||
This exception is thrown when a specific address is requested and the
|
||||
requested ip address already exists and is used.
|
||||
"""
|
||||
|
||||
|
||||
class DriverNotEnabledException(KuryrException):
|
||||
"""Exception represents the binding driver is not enabled.
|
||||
|
||||
This exception is thrown when kuryr tries to load a specific binding driver
|
||||
but the driver is not enabled.
|
||||
"""
|
||||
|
|
|
@ -22,7 +22,7 @@ _driver = ""
|
|||
def _get_driver():
|
||||
global _driver
|
||||
if not _driver:
|
||||
driver_name = cfg.CONF.binding.driver.rsplit('.', 1)[1]
|
||||
driver_name = cfg.CONF.binding.default_driver.rsplit('.', 1)[1]
|
||||
|
||||
# REVISIT(vikasc): Need to remove this if check
|
||||
if driver_name == 'vlan':
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# 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_utils import importutils
|
||||
|
||||
from kuryr.lib import binding
|
||||
from kuryr.lib import exceptions
|
||||
from kuryr.tests.unit import base
|
||||
|
||||
|
||||
class TestBinding(base.TestCase):
|
||||
"""Unit tests for binding module"""
|
||||
|
||||
def test__verify_driver(self):
|
||||
cfg.CONF.set_override('enabled_drivers',
|
||||
['kuryr.lib.binding.drivers.veth'],
|
||||
group='binding')
|
||||
driver = importutils.import_module('kuryr.lib.binding.drivers.veth')
|
||||
binding._verify_driver(driver) # assert no exception raise
|
||||
driver = importutils.import_module('kuryr.lib.binding.drivers.vlan')
|
||||
self.assertRaises(exceptions.DriverNotEnabledException,
|
||||
binding._verify_driver, driver)
|
|
@ -29,7 +29,7 @@ class VlanSegmentationDriverTest(base.TestCase):
|
|||
|
||||
def setUp(self):
|
||||
super(VlanSegmentationDriverTest, self).setUp()
|
||||
cfg.CONF.binding.driver = 'kuryr.lib.binding.drivers.vlan'
|
||||
cfg.CONF.binding.default_driver = 'kuryr.lib.binding.drivers.vlan'
|
||||
|
||||
def test_allocate_segmentation_id(self):
|
||||
vlan_seg_driver = vlan.SegmentationDriver()
|
||||
|
|
|
@ -30,4 +30,4 @@ class ConfigurationTest(base.TestCase):
|
|||
self.assertEqual('baremetal',
|
||||
cfg.CONF.deployment_type)
|
||||
self.assertEqual('kuryr.lib.binding.drivers.veth',
|
||||
cfg.CONF.binding.driver)
|
||||
cfg.CONF.binding.default_driver)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
Add support for multiple binding drivers. Introduce a new config
|
||||
called 'enabled_drivers' which specifies a list of binding drivers
|
||||
allowed to use.
|
||||
deprecations:
|
||||
- |
|
||||
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.
|
Loading…
Reference in New Issue