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_config import cfg
|
||||||
from oslo_utils import importutils
|
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,
|
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.
|
"""Binds the Neutron port to the network interface on the host.
|
||||||
|
|
||||||
:param endpoint_id: the ID of the endpoint as string
|
: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
|
port of a container which is running inside this Nova
|
||||||
instance (either ipvlan/macvlan or a subport).
|
instance (either ipvlan/macvlan or a subport).
|
||||||
:param segmentation_id: ID of the segment for container traffic isolation)
|
:param segmentation_id: ID of the segment for container traffic isolation)
|
||||||
|
:param driver: the binding driver name
|
||||||
:param kwargs: Additional driver-specific arguments
|
:param kwargs: Additional driver-specific arguments
|
||||||
:returns: the tuple of the names of the veth pair and the tuple of stdout
|
:returns: the tuple of the names of the veth pair and the tuple of stdout
|
||||||
and stderr returned by processutils.execute invoked with the
|
and stderr returned by processutils.execute invoked with the
|
||||||
executable script for binding
|
executable script for binding
|
||||||
:raises: kuryr.common.exceptions.VethCreationFailure,
|
:raises: kuryr.common.exceptions.VethCreationFailure,
|
||||||
|
kuryr.common.exceptions.DriverNotEnabledException,
|
||||||
processutils.ProcessExecutionError
|
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,
|
return driver.port_bind(endpoint_id, port, subnets, network=network,
|
||||||
vm_port=vm_port,
|
vm_port=vm_port,
|
||||||
segmentation_id=segmentation_id,
|
segmentation_id=segmentation_id,
|
||||||
**kwargs)
|
**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.
|
"""Unbinds the Neutron port from the network interface on the host.
|
||||||
|
|
||||||
:param endpoint_id: the ID of the Docker container as string
|
:param endpoint_id: the ID of the Docker container as string
|
||||||
:param neutron_port: a port dictionary returned from python-neutronclient
|
:param neutron_port: a port dictionary returned from python-neutronclient
|
||||||
|
:param driver: the binding driver name
|
||||||
:param kwargs: Additional driver-specific arguments
|
:param kwargs: Additional driver-specific arguments
|
||||||
:returns: the tuple of stdout and stderr returned by processutils.execute
|
:returns: the tuple of stdout and stderr returned by processutils.execute
|
||||||
invoked with the executable script for unbinding
|
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)
|
return driver.port_unbind(endpoint_id, neutron_port, **kwargs)
|
||||||
|
|
|
@ -68,9 +68,13 @@ binding_opts = [
|
||||||
default='eth',
|
default='eth',
|
||||||
help=_('The name prefix of the veth endpoint put inside the '
|
help=_('The name prefix of the veth endpoint put inside the '
|
||||||
'container.')),
|
'container.')),
|
||||||
cfg.StrOpt('driver',
|
cfg.StrOpt('default_driver',
|
||||||
default='kuryr.lib.binding.drivers.veth',
|
default='kuryr.lib.binding.drivers.veth',
|
||||||
|
deprecated_name='driver',
|
||||||
help=_('Driver to use for binding and unbinding ports.')),
|
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',
|
cfg.StrOpt('link_iface',
|
||||||
default='',
|
default='',
|
||||||
help=_('Specifies the name of the Nova instance interface to '
|
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
|
This exception is thrown when a specific address is requested and the
|
||||||
requested ip address already exists and is used.
|
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():
|
def _get_driver():
|
||||||
global _driver
|
global _driver
|
||||||
if not _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
|
# REVISIT(vikasc): Need to remove this if check
|
||||||
if driver_name == 'vlan':
|
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):
|
def setUp(self):
|
||||||
super(VlanSegmentationDriverTest, self).setUp()
|
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):
|
def test_allocate_segmentation_id(self):
|
||||||
vlan_seg_driver = vlan.SegmentationDriver()
|
vlan_seg_driver = vlan.SegmentationDriver()
|
||||||
|
|
|
@ -30,4 +30,4 @@ class ConfigurationTest(base.TestCase):
|
||||||
self.assertEqual('baremetal',
|
self.assertEqual('baremetal',
|
||||||
cfg.CONF.deployment_type)
|
cfg.CONF.deployment_type)
|
||||||
self.assertEqual('kuryr.lib.binding.drivers.veth',
|
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