Merge "ML2 mechanism driver for SR-IOV capable NIC based switching, Part 1"
This commit is contained in:
commit
e3826f749a
12
etc/neutron/plugins/ml2/ml2_conf_sriov.ini
Normal file
12
etc/neutron/plugins/ml2/ml2_conf_sriov.ini
Normal file
@ -0,0 +1,12 @@
|
||||
# Defines configuration options for SRIOV NIC Switch MechanismDriver
|
||||
|
||||
[ml2_sriov]
|
||||
# (ListOpt) Comma-separated list of
|
||||
# supported Vendor PCI Devices, in format vendor_id:product_id
|
||||
#
|
||||
# supported_vendor_pci_devs = 15b3:1004
|
||||
# Example: supported_vendor_pci_devs = 15b3:1004, 8086:10c9
|
||||
#
|
||||
# (BoolOpt) Requires SRIOV neutron agent for port binding
|
||||
# agent_required = True
|
||||
|
@ -87,6 +87,7 @@ AGENT_TYPE_MLNX = 'Mellanox plugin agent'
|
||||
AGENT_TYPE_METERING = 'Metering agent'
|
||||
AGENT_TYPE_METADATA = 'Metadata agent'
|
||||
AGENT_TYPE_SDNVE = 'IBM SDN-VE agent'
|
||||
AGENT_TYPE_NIC_SWITCH = 'NIC Switch agent'
|
||||
L2_AGENT_TOPIC = 'N/A'
|
||||
|
||||
PAGINATION_INFINITE = 'infinite'
|
||||
|
@ -45,6 +45,7 @@ PROFILE = 'binding:profile'
|
||||
# strategy for OVS should be used
|
||||
CAP_PORT_FILTER = 'port_filter'
|
||||
OVS_HYBRID_PLUG = 'ovs_hybrid_plug'
|
||||
VIF_DETAILS_VLAN = 'vlan'
|
||||
|
||||
VIF_TYPE_UNBOUND = 'unbound'
|
||||
VIF_TYPE_BINDING_FAILED = 'binding_failed'
|
||||
@ -58,11 +59,13 @@ VIF_TYPE_HYPERV = 'hyperv'
|
||||
VIF_TYPE_MIDONET = 'midonet'
|
||||
VIF_TYPE_MLNX_DIRECT = 'mlnx_direct'
|
||||
VIF_TYPE_MLNX_HOSTDEV = 'hostdev'
|
||||
VIF_TYPE_HW_VEB = 'hw_veb'
|
||||
VIF_TYPE_OTHER = 'other'
|
||||
VIF_TYPES = [VIF_TYPE_UNBOUND, VIF_TYPE_BINDING_FAILED, VIF_TYPE_OVS,
|
||||
VIF_TYPE_IVS, VIF_TYPE_BRIDGE, VIF_TYPE_802_QBG,
|
||||
VIF_TYPE_802_QBH, VIF_TYPE_HYPERV, VIF_TYPE_MIDONET,
|
||||
VIF_TYPE_MLNX_DIRECT, VIF_TYPE_MLNX_HOSTDEV, VIF_TYPE_OTHER]
|
||||
VIF_TYPE_MLNX_DIRECT, VIF_TYPE_MLNX_HOSTDEV, VIF_TYPE_HW_VEB,
|
||||
VIF_TYPE_OTHER]
|
||||
|
||||
VNIC_NORMAL = 'normal'
|
||||
VNIC_DIRECT = 'direct'
|
||||
|
0
neutron/plugins/ml2/drivers/mech_sriov/__init__.py
Normal file
0
neutron/plugins/ml2/drivers/mech_sriov/__init__.py
Normal file
184
neutron/plugins/ml2/drivers/mech_sriov/mech_driver.py
Normal file
184
neutron/plugins/ml2/drivers/mech_sriov/mech_driver.py
Normal file
@ -0,0 +1,184 @@
|
||||
# Copyright 2014 Mellanox Technologies, Ltd
|
||||
#
|
||||
# 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 neutron.common import constants
|
||||
from neutron.extensions import portbindings
|
||||
from neutron.openstack.common import log
|
||||
from neutron.plugins.common import constants as p_const
|
||||
from neutron.plugins.ml2 import driver_api as api
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
sriov_opts = [
|
||||
cfg.ListOpt('supported_pci_vendor_devs',
|
||||
default=['15b3:1004', '8086:10c9'],
|
||||
help=_("Supported PCI vendor devices, defined by "
|
||||
"vendor_id:product_id according to the PCI ID "
|
||||
"Repository. Default enables support for Intel "
|
||||
"and Mellanox SR-IOV capable NICs")),
|
||||
cfg.BoolOpt('agent_required',
|
||||
default=False,
|
||||
help=_("SRIOV neutron agent is required for port binding")),
|
||||
|
||||
]
|
||||
|
||||
cfg.CONF.register_opts(sriov_opts, "ml2_sriov")
|
||||
|
||||
|
||||
class SriovNicSwitchMechanismDriver(api.MechanismDriver):
|
||||
"""Mechanism Driver for SR-IOV capable NIC based switching.
|
||||
|
||||
The SriovNicSwitchMechanismDriver integrates the ml2 plugin with the
|
||||
sriovNicSwitch L2 agent depending on configuration option.
|
||||
Port binding with this driver may require the sriovNicSwitch agent
|
||||
to be running on the port's host, and that agent to have connectivity
|
||||
to at least one segment of the port's network.
|
||||
L2 agent is not essential for port binding; port binding is handled by
|
||||
VIF Driver via libvirt domain XML.
|
||||
L2 Agent presents in order to manage port update events.
|
||||
If vendor NIC does not support updates, setting agent_required = False
|
||||
will allow to use Mechanism Driver without L2 agent.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
agent_type=constants.AGENT_TYPE_NIC_SWITCH,
|
||||
vif_type=portbindings.VIF_TYPE_HW_VEB,
|
||||
vif_details={portbindings.CAP_PORT_FILTER: False},
|
||||
supported_vnic_types=[portbindings.VNIC_DIRECT,
|
||||
portbindings.VNIC_MACVTAP],
|
||||
supported_pci_vendor_info=None):
|
||||
"""Initialize base class for SriovNicSwitch L2 agent type.
|
||||
|
||||
:param agent_type: Constant identifying agent type in agents_db
|
||||
:param vif_type: Value for binding:vif_type when bound
|
||||
:param vif_details: Dictionary with details for VIF driver when bound
|
||||
:param supported_vnic_types: The binding:vnic_type values we can bind
|
||||
:param supported_pci_vendor_info: The pci_vendor_info values to bind
|
||||
"""
|
||||
self.agent_type = agent_type
|
||||
self.supported_vnic_types = supported_vnic_types
|
||||
self.vif_type = vif_type
|
||||
self.vif_details = vif_details
|
||||
|
||||
def initialize(self):
|
||||
try:
|
||||
self.pci_vendor_info = self._parse_pci_vendor_config(
|
||||
cfg.CONF.ml2_sriov.supported_pci_vendor_devs)
|
||||
self.agent_required = cfg.CONF.ml2_sriov.agent_required
|
||||
except ValueError:
|
||||
LOG.exception(_("Failed to parse supported PCI vendor devices"))
|
||||
raise cfg.Error(_("Parsing supported pci_vendor_devs failed"))
|
||||
|
||||
def bind_port(self, context):
|
||||
LOG.debug("Attempting to bind port %(port)s on "
|
||||
"network %(network)s",
|
||||
{'port': context.current['id'],
|
||||
'network': context.network.current['id']})
|
||||
vnic_type = context.current.get(portbindings.VNIC_TYPE,
|
||||
portbindings.VNIC_NORMAL)
|
||||
if vnic_type not in self.supported_vnic_types:
|
||||
LOG.debug("Refusing to bind due to unsupported vnic_type: %s",
|
||||
vnic_type)
|
||||
return
|
||||
|
||||
if not self._check_supported_pci_vendor_device(context):
|
||||
LOG.debug("Refusing to bind due to unsupported pci_vendor device")
|
||||
return
|
||||
|
||||
if self.agent_required:
|
||||
for agent in context.host_agents(self.agent_type):
|
||||
LOG.debug("Checking agent: %s", agent)
|
||||
if agent['alive']:
|
||||
if self.try_to_bind(context, agent):
|
||||
return
|
||||
else:
|
||||
LOG.warning(_("Attempting to bind with dead agent: %s"),
|
||||
agent)
|
||||
else:
|
||||
self.try_to_bind(context)
|
||||
|
||||
def try_to_bind(self, context, agent=None):
|
||||
for segment in context.network.network_segments:
|
||||
if self.check_segment(segment, agent):
|
||||
context.set_binding(segment[api.ID],
|
||||
self.vif_type,
|
||||
self.get_vif_details(context, segment),
|
||||
constants.PORT_STATUS_ACTIVE)
|
||||
LOG.debug("Bound using segment: %s", segment)
|
||||
return True
|
||||
return False
|
||||
|
||||
def check_segment(self, segment, agent=None):
|
||||
"""Check if segment can be bound.
|
||||
|
||||
:param segment: segment dictionary describing segment to bind
|
||||
:param agent: agents_db entry describing agent to bind or None
|
||||
:returns: True if segment can be bound for agent
|
||||
"""
|
||||
network_type = segment[api.NETWORK_TYPE]
|
||||
if network_type == p_const.TYPE_VLAN:
|
||||
if agent:
|
||||
mappings = agent['configurations'].get('device_mappings', {})
|
||||
LOG.debug("Checking segment: %(segment)s "
|
||||
"for mappings: %(mappings)s ",
|
||||
{'segment': segment, 'mappings': mappings})
|
||||
return segment[api.PHYSICAL_NETWORK] in mappings
|
||||
return True
|
||||
return False
|
||||
|
||||
def _check_supported_pci_vendor_device(self, context):
|
||||
if self.pci_vendor_info:
|
||||
profile = context.current.get(portbindings.PROFILE, {})
|
||||
if not profile:
|
||||
LOG.debug("Missing profile in port binding")
|
||||
return False
|
||||
pci_vendor_info = profile.get('pci_vendor_info')
|
||||
if not pci_vendor_info:
|
||||
LOG.debug("Missing pci vendor info in profile")
|
||||
return False
|
||||
if pci_vendor_info not in self.pci_vendor_info:
|
||||
LOG.debug("Unsupported pci_vendor %s", pci_vendor_info)
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_vif_details(self, context, segment):
|
||||
if segment[api.NETWORK_TYPE] == p_const.TYPE_VLAN:
|
||||
vlan_id = str(segment[api.SEGMENTATION_ID])
|
||||
self.vif_details[portbindings.VIF_DETAILS_VLAN] = vlan_id
|
||||
return self.vif_details
|
||||
|
||||
def _parse_pci_vendor_config(self, pci_vendor_list):
|
||||
parsed_list = []
|
||||
for elem in pci_vendor_list:
|
||||
elem = elem.strip()
|
||||
if not elem:
|
||||
continue
|
||||
split_result = elem.split(':')
|
||||
if len(split_result) != 2:
|
||||
raise ValueError(_("Invalid pci_vendor_info: '%s'") % elem)
|
||||
vendor_id = split_result[0].strip()
|
||||
if not vendor_id:
|
||||
raise ValueError(_("Missing vendor_id in: '%s'") % elem)
|
||||
product_id = split_result[1].strip()
|
||||
if not product_id:
|
||||
raise ValueError(_("Missing product_id in: '%s'") % elem)
|
||||
parsed_list.append(elem)
|
||||
return parsed_list
|
@ -125,7 +125,8 @@ class RpcCallbacks(n_rpc.RpcCallback,
|
||||
'segmentation_id': segment[api.SEGMENTATION_ID],
|
||||
'physical_network': segment[api.PHYSICAL_NETWORK],
|
||||
'fixed_ips': port['fixed_ips'],
|
||||
'device_owner': port['device_owner']}
|
||||
'device_owner': port['device_owner'],
|
||||
'profile': port[portbindings.PROFILE]}
|
||||
LOG.debug(_("Returning: %s"), entry)
|
||||
return entry
|
||||
|
||||
|
@ -0,0 +1,236 @@
|
||||
# Copyright 2014 Mellanox Technologies, Ltd
|
||||
#
|
||||
# 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.
|
||||
|
||||
import mock
|
||||
from oslo.config import cfg
|
||||
|
||||
from neutron.common import constants
|
||||
from neutron.extensions import portbindings
|
||||
from neutron.plugins.common import constants as p_const
|
||||
from neutron.plugins.ml2 import config # noqa
|
||||
from neutron.plugins.ml2 import driver_api as api
|
||||
from neutron.plugins.ml2.drivers.mech_sriov import mech_driver
|
||||
from neutron.tests.unit.ml2 import _test_mech_agent as base
|
||||
|
||||
MELLANOX_CONNECTX3_PCI_INFO = '15b3:1004'
|
||||
DEFAULT_PCI_INFO = ['15b3:1004', '8086:10c9']
|
||||
|
||||
|
||||
class TestFakePortContext(base.FakePortContext):
|
||||
def __init__(self, agent_type, agents, segments,
|
||||
vnic_type=portbindings.VNIC_NORMAL,
|
||||
profile={'pci_vendor_info':
|
||||
MELLANOX_CONNECTX3_PCI_INFO}):
|
||||
super(TestFakePortContext, self).__init__(agent_type,
|
||||
agents,
|
||||
segments,
|
||||
vnic_type)
|
||||
self._bound_profile = profile
|
||||
|
||||
@property
|
||||
def current(self):
|
||||
return {'id': base.PORT_ID,
|
||||
'binding:vnic_type': self._bound_vnic_type,
|
||||
'binding:profile': self._bound_profile}
|
||||
|
||||
def set_binding(self, segment_id, vif_type, vif_details, state):
|
||||
self._bound_segment_id = segment_id
|
||||
self._bound_vif_type = vif_type
|
||||
self._bound_vif_details = vif_details
|
||||
self._bound_state = state
|
||||
|
||||
|
||||
class SriovNicSwitchMechanismBaseTestCase(base.AgentMechanismBaseTestCase):
|
||||
VIF_TYPE = portbindings.VIF_TYPE_HW_VEB
|
||||
CAP_PORT_FILTER = False
|
||||
AGENT_TYPE = constants.AGENT_TYPE_NIC_SWITCH
|
||||
VLAN_SEGMENTS = base.AgentMechanismVlanTestCase.VLAN_SEGMENTS
|
||||
|
||||
GOOD_MAPPINGS = {'fake_physical_network': 'fake_device'}
|
||||
GOOD_CONFIGS = {'device_mappings': GOOD_MAPPINGS}
|
||||
|
||||
BAD_MAPPINGS = {'wrong_physical_network': 'wrong_device'}
|
||||
BAD_CONFIGS = {'device_mappings': BAD_MAPPINGS}
|
||||
|
||||
AGENTS = [{'alive': True,
|
||||
'configurations': GOOD_CONFIGS}]
|
||||
AGENTS_DEAD = [{'alive': False,
|
||||
'configurations': GOOD_CONFIGS}]
|
||||
AGENTS_BAD = [{'alive': False,
|
||||
'configurations': GOOD_CONFIGS},
|
||||
{'alive': True,
|
||||
'configurations': BAD_CONFIGS}]
|
||||
|
||||
def setUp(self):
|
||||
cfg.CONF.set_override('supported_pci_vendor_devs',
|
||||
DEFAULT_PCI_INFO,
|
||||
'ml2_sriov')
|
||||
cfg.CONF.set_override('agent_required', True, 'ml2_sriov')
|
||||
super(SriovNicSwitchMechanismBaseTestCase, self).setUp()
|
||||
self.driver = mech_driver.SriovNicSwitchMechanismDriver()
|
||||
self.driver.initialize()
|
||||
|
||||
def test_check_segment(self):
|
||||
"""Validate the check_segment call."""
|
||||
segment = {'api.NETWORK_TYPE': ""}
|
||||
segment[api.NETWORK_TYPE] = p_const.TYPE_VLAN
|
||||
self.assertTrue(self.driver.check_segment(segment))
|
||||
# Validate a network type not currently supported
|
||||
segment[api.NETWORK_TYPE] = p_const.TYPE_GRE
|
||||
self.assertFalse(self.driver.check_segment(segment))
|
||||
|
||||
|
||||
class SriovSwitchMechGenericTestCase(SriovNicSwitchMechanismBaseTestCase,
|
||||
base.AgentMechanismGenericTestCase):
|
||||
pass
|
||||
|
||||
|
||||
class SriovMechVlanTestCase(SriovNicSwitchMechanismBaseTestCase,
|
||||
base.AgentMechanismBaseTestCase):
|
||||
VLAN_SEGMENTS = [{api.ID: 'unknown_segment_id',
|
||||
api.NETWORK_TYPE: 'no_such_type'},
|
||||
{api.ID: 'vlan_segment_id',
|
||||
api.NETWORK_TYPE: 'vlan',
|
||||
api.PHYSICAL_NETWORK: 'fake_physical_network',
|
||||
api.SEGMENTATION_ID: 1234}]
|
||||
|
||||
def test_type_vlan(self):
|
||||
context = TestFakePortContext(self.AGENT_TYPE,
|
||||
self.AGENTS,
|
||||
self.VLAN_SEGMENTS,
|
||||
portbindings.VNIC_DIRECT)
|
||||
self.driver.bind_port(context)
|
||||
self._check_bound(context, self.VLAN_SEGMENTS[1])
|
||||
|
||||
def test_type_vlan_bad(self):
|
||||
context = TestFakePortContext(self.AGENT_TYPE,
|
||||
self.AGENTS_BAD,
|
||||
self.VLAN_SEGMENTS,
|
||||
portbindings.VNIC_DIRECT)
|
||||
self.driver.bind_port(context)
|
||||
self._check_unbound(context)
|
||||
|
||||
|
||||
class SriovSwitchMechVnicTypeTestCase(SriovNicSwitchMechanismBaseTestCase):
|
||||
def _check_vif_type_for_vnic_type(self, vnic_type,
|
||||
expected_vif_type):
|
||||
context = TestFakePortContext(self.AGENT_TYPE,
|
||||
self.AGENTS,
|
||||
self.VLAN_SEGMENTS,
|
||||
vnic_type)
|
||||
self.driver.bind_port(context)
|
||||
self.assertEqual(expected_vif_type, context._bound_vif_type)
|
||||
vlan = int(context._bound_vif_details[portbindings.VIF_DETAILS_VLAN])
|
||||
self.assertEqual(1234, vlan)
|
||||
|
||||
def test_vnic_type_direct(self):
|
||||
self._check_vif_type_for_vnic_type(portbindings.VNIC_DIRECT,
|
||||
portbindings.VIF_TYPE_HW_VEB)
|
||||
|
||||
def test_vnic_type_macvtap(self):
|
||||
self._check_vif_type_for_vnic_type(portbindings.VNIC_MACVTAP,
|
||||
portbindings.VIF_TYPE_HW_VEB)
|
||||
|
||||
|
||||
class SriovSwitchMechProfileTestCase(SriovNicSwitchMechanismBaseTestCase):
|
||||
def _check_vif_for_pci_info(self, pci_vendor_info, expected_vif_type):
|
||||
context = TestFakePortContext(self.AGENT_TYPE,
|
||||
self.AGENTS,
|
||||
self.VLAN_SEGMENTS,
|
||||
portbindings.VNIC_DIRECT,
|
||||
{'pci_vendor_info': pci_vendor_info})
|
||||
self.driver.bind_port(context)
|
||||
self.assertEqual(expected_vif_type, context._bound_vif_type)
|
||||
|
||||
def test_profile_supported_pci_info(self):
|
||||
self._check_vif_for_pci_info(MELLANOX_CONNECTX3_PCI_INFO,
|
||||
portbindings.VIF_TYPE_HW_VEB)
|
||||
|
||||
def test_profile_unsupported_pci_info(self):
|
||||
with mock.patch('neutron.plugins.ml2.drivers.mech_sriov.'
|
||||
'mech_driver.LOG') as log_mock:
|
||||
self._check_vif_for_pci_info('xxxx:yyyy', None)
|
||||
log_mock.debug.assert_called_with('Refusing to bind due to '
|
||||
'unsupported pci_vendor device')
|
||||
|
||||
|
||||
class SriovSwitchMechProfileFailTestCase(SriovNicSwitchMechanismBaseTestCase):
|
||||
def _check_for_pci_vendor_info(self, pci_vendor_info):
|
||||
context = TestFakePortContext(self.AGENT_TYPE,
|
||||
self.AGENTS,
|
||||
self.VLAN_SEGMENTS,
|
||||
portbindings.VNIC_DIRECT,
|
||||
pci_vendor_info)
|
||||
self.driver._check_supported_pci_vendor_device(context)
|
||||
|
||||
def test_profile_missing_profile(self):
|
||||
with mock.patch('neutron.plugins.ml2.drivers.mech_sriov.'
|
||||
'mech_driver.LOG') as log_mock:
|
||||
self._check_for_pci_vendor_info({})
|
||||
log_mock.debug.assert_called_with("Missing profile in port"
|
||||
" binding")
|
||||
|
||||
def test_profile_missing_pci_vendor_info(self):
|
||||
with mock.patch('neutron.plugins.ml2.drivers.mech_sriov.'
|
||||
'mech_driver.LOG') as log_mock:
|
||||
self._check_for_pci_vendor_info({'aa': 'bb'})
|
||||
log_mock.debug.assert_called_with("Missing pci vendor"
|
||||
" info in profile")
|
||||
|
||||
|
||||
class SriovSwitchMechVifDetailsTestCase(SriovNicSwitchMechanismBaseTestCase):
|
||||
def test_vif_details_contains_vlan_id(self):
|
||||
VLAN_SEGMENTS = [{api.ID: 'vlan_segment_id',
|
||||
api.NETWORK_TYPE: 'vlan',
|
||||
api.PHYSICAL_NETWORK: 'fake_physical_network',
|
||||
api.SEGMENTATION_ID: 1234}]
|
||||
|
||||
context = TestFakePortContext(self.AGENT_TYPE,
|
||||
self.AGENTS,
|
||||
VLAN_SEGMENTS,
|
||||
portbindings.VNIC_DIRECT)
|
||||
|
||||
self.driver.bind_port(context)
|
||||
vif_details = context._bound_vif_details
|
||||
self.assertIsNotNone(vif_details)
|
||||
vlan_id = int(vif_details.get(portbindings.VIF_DETAILS_VLAN))
|
||||
self.assertEqual(1234, vlan_id)
|
||||
|
||||
|
||||
class SriovSwitchMechConfigTestCase(SriovNicSwitchMechanismBaseTestCase):
|
||||
def _set_config(self, pci_devs=['aa:bb']):
|
||||
cfg.CONF.set_override('mechanism_drivers',
|
||||
['logger', 'sriovnicswitch'], 'ml2')
|
||||
cfg.CONF.set_override('supported_pci_vendor_devs', pci_devs,
|
||||
'ml2_sriov')
|
||||
|
||||
def test_pci_vendor_config_single_entry(self):
|
||||
self._set_config()
|
||||
self.driver.initialize()
|
||||
self.assertEqual(['aa:bb'], self.driver.pci_vendor_info)
|
||||
|
||||
def test_pci_vendor_config_multiple_entry(self):
|
||||
self._set_config(['x:y', 'a:b'])
|
||||
self.driver.initialize()
|
||||
self.assertEqual(['x:y', 'a:b'], self.driver.pci_vendor_info)
|
||||
|
||||
def test_pci_vendor_config_default_entry(self):
|
||||
self.driver.initialize()
|
||||
self.assertEqual(DEFAULT_PCI_INFO,
|
||||
self.driver.pci_vendor_info)
|
||||
|
||||
def test_pci_vendor_config_wrong_entry(self):
|
||||
self._set_config('wrong_entry')
|
||||
self.assertRaises(cfg.Error, self.driver.initialize)
|
@ -71,6 +71,7 @@ data_files =
|
||||
etc/neutron/plugins/ml2/ml2_conf_odl.ini
|
||||
etc/neutron/plugins/ml2/ml2_conf_ofa.ini
|
||||
etc/neutron/plugins/ml2/ml2_conf_fslsdn.ini
|
||||
etc/neutron/plugins/ml2/ml2_conf_sriov.ini
|
||||
etc/neutron/plugins/mlnx = etc/neutron/plugins/mlnx/mlnx_conf.ini
|
||||
etc/neutron/plugins/nec = etc/neutron/plugins/nec/nec.ini
|
||||
etc/neutron/plugins/nuage = etc/neutron/plugins/nuage/nuage_plugin.ini
|
||||
@ -167,6 +168,7 @@ neutron.ml2.mechanism_drivers =
|
||||
mlnx = neutron.plugins.ml2.drivers.mlnx.mech_mlnx:MlnxMechanismDriver
|
||||
brocade = neutron.plugins.ml2.drivers.brocade.mechanism_brocade:BrocadeMechanism
|
||||
fslsdn = neutron.plugins.ml2.drivers.mechanism_fslsdn:FslsdnMechanismDriver
|
||||
sriovnicswitch = neutron.plugins.ml2.drivers.mech_sriov.mech_driver:SriovNicSwitchMechanismDriver
|
||||
neutron.openstack.common.cache.backends =
|
||||
memory = neutron.openstack.common.cache._backends.memory:MemoryBackend
|
||||
# These are for backwards compat with Icehouse notification_driver configuration values
|
||||
|
Loading…
x
Reference in New Issue
Block a user