Deal with port commonly when hypervisor is XenServer
When neutron is deployed with hypervisor is XenServer, current implementation will grab port's iface-id via xapi, but this isn't the proper way: Port's iface-id is already set when creating VM or hot plugging VIFs in nova project, so there is no need to grab it via xapi Change-Id: Ie07527cc89ac81ff1e3519db66925cee482f77a4 Closes-Bug: #1649747
This commit is contained in:
@@ -16,7 +16,6 @@ ovs-vsctl: CommandFilter, ovs-vsctl, root
|
|||||||
ovs-ofctl: CommandFilter, ovs-ofctl, root
|
ovs-ofctl: CommandFilter, ovs-ofctl, root
|
||||||
kill_ovsdb_client: KillFilter, root, /usr/bin/ovsdb-client, -9
|
kill_ovsdb_client: KillFilter, root, /usr/bin/ovsdb-client, -9
|
||||||
ovsdb-client: CommandFilter, ovsdb-client, root
|
ovsdb-client: CommandFilter, ovsdb-client, root
|
||||||
xe: CommandFilter, xe, root
|
|
||||||
|
|
||||||
# ip_lib
|
# ip_lib
|
||||||
ip: IpFilter, ip, root
|
ip: IpFilter, ip, root
|
||||||
|
@@ -23,7 +23,6 @@ from debtcollector import removals
|
|||||||
from neutron_lib import exceptions
|
from neutron_lib import exceptions
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import excutils
|
|
||||||
import six
|
import six
|
||||||
import tenacity
|
import tenacity
|
||||||
|
|
||||||
@@ -412,17 +411,6 @@ class OVSBridge(BaseOVS):
|
|||||||
def get_port_stats(self, port_name):
|
def get_port_stats(self, port_name):
|
||||||
return self.db_get_val("Interface", port_name, "statistics")
|
return self.db_get_val("Interface", port_name, "statistics")
|
||||||
|
|
||||||
def get_xapi_iface_id(self, xs_vif_uuid):
|
|
||||||
args = ["xe", "vif-param-get", "param-name=other-config",
|
|
||||||
"param-key=nicira-iface-id", "uuid=%s" % xs_vif_uuid]
|
|
||||||
try:
|
|
||||||
return utils.execute(args, run_as_root=True).strip()
|
|
||||||
except Exception as e:
|
|
||||||
with excutils.save_and_reraise_exception():
|
|
||||||
LOG.error(_LE("Unable to execute %(cmd)s. "
|
|
||||||
"Exception: %(exception)s"),
|
|
||||||
{'cmd': args, 'exception': e})
|
|
||||||
|
|
||||||
def get_ports_attributes(self, table, columns=None, ports=None,
|
def get_ports_attributes(self, table, columns=None, ports=None,
|
||||||
check_error=True, log_errors=True,
|
check_error=True, log_errors=True,
|
||||||
if_exists=False):
|
if_exists=False):
|
||||||
@@ -449,14 +437,6 @@ class OVSBridge(BaseOVS):
|
|||||||
p = VifPort(name, ofport, external_ids["iface-id"],
|
p = VifPort(name, ofport, external_ids["iface-id"],
|
||||||
external_ids["attached-mac"], self)
|
external_ids["attached-mac"], self)
|
||||||
edge_ports.append(p)
|
edge_ports.append(p)
|
||||||
elif ("xs-vif-uuid" in external_ids and
|
|
||||||
"attached-mac" in external_ids):
|
|
||||||
# if this is a xenserver and iface-id is not automatically
|
|
||||||
# synced to OVS from XAPI, we grab it from XAPI directly
|
|
||||||
iface_id = self.get_xapi_iface_id(external_ids["xs-vif-uuid"])
|
|
||||||
p = VifPort(name, ofport, iface_id,
|
|
||||||
external_ids["attached-mac"], self)
|
|
||||||
edge_ports.append(p)
|
|
||||||
|
|
||||||
return edge_ports
|
return edge_ports
|
||||||
|
|
||||||
@@ -496,10 +476,6 @@ class OVSBridge(BaseOVS):
|
|||||||
def portid_from_external_ids(self, external_ids):
|
def portid_from_external_ids(self, external_ids):
|
||||||
if 'iface-id' in external_ids:
|
if 'iface-id' in external_ids:
|
||||||
return external_ids['iface-id']
|
return external_ids['iface-id']
|
||||||
if 'xs-vif-uuid' in external_ids:
|
|
||||||
iface_id = self.get_xapi_iface_id(
|
|
||||||
external_ids['xs-vif-uuid'])
|
|
||||||
return iface_id
|
|
||||||
|
|
||||||
def get_port_tag_dict(self):
|
def get_port_tag_dict(self):
|
||||||
"""Get a dict of port names and associated vlan tags.
|
"""Get a dict of port names and associated vlan tags.
|
||||||
|
@@ -486,29 +486,6 @@ class OVS_Lib_Test(base.BaseTestCase):
|
|||||||
|
|
||||||
tools.verify_mock_calls(self.execute, expected_calls_and_values)
|
tools.verify_mock_calls(self.execute, expected_calls_and_values)
|
||||||
|
|
||||||
def _test_get_vif_ports(self, is_xen=False):
|
|
||||||
pname = "tap99"
|
|
||||||
ofport = 6
|
|
||||||
vif_id = uuidutils.generate_uuid()
|
|
||||||
mac = "ca:fe:de:ad:be:ef"
|
|
||||||
id_field = 'xs-vif-uuid' if is_xen else 'iface-id'
|
|
||||||
external_ids = {"attached-mac": mac, id_field: vif_id}
|
|
||||||
self.br.get_ports_attributes = mock.Mock(return_value=[{
|
|
||||||
'name': pname, 'ofport': ofport, 'external_ids': external_ids}])
|
|
||||||
self.br.get_xapi_iface_id = mock.Mock(return_value=vif_id)
|
|
||||||
|
|
||||||
ports = self.br.get_vif_ports()
|
|
||||||
self.assertEqual(1, len(ports))
|
|
||||||
self.assertEqual(ports[0].port_name, pname)
|
|
||||||
self.assertEqual(ports[0].ofport, ofport)
|
|
||||||
self.assertEqual(ports[0].vif_id, vif_id)
|
|
||||||
self.assertEqual(ports[0].vif_mac, mac)
|
|
||||||
self.assertEqual(ports[0].switch.br_name, self.BR_NAME)
|
|
||||||
self.br.get_ports_attributes.assert_called_once_with(
|
|
||||||
'Interface',
|
|
||||||
columns=['name', 'external_ids', 'ofport'],
|
|
||||||
if_exists=True)
|
|
||||||
|
|
||||||
def _encode_ovs_json(self, headings, data):
|
def _encode_ovs_json(self, headings, data):
|
||||||
# See man ovs-vsctl(8) for the encoding details.
|
# See man ovs-vsctl(8) for the encoding details.
|
||||||
r = {"data": [],
|
r = {"data": [],
|
||||||
@@ -528,12 +505,36 @@ class OVS_Lib_Test(base.BaseTestCase):
|
|||||||
type(cell))
|
type(cell))
|
||||||
return jsonutils.dumps(r)
|
return jsonutils.dumps(r)
|
||||||
|
|
||||||
def _test_get_vif_port_set(self, is_xen):
|
def test_get_vif_port_to_ofport_map(self):
|
||||||
if is_xen:
|
self.execute.return_value = OVSLIST_WITH_UNSET_PORT
|
||||||
id_key = 'xs-vif-uuid'
|
results = self.br.get_vif_port_to_ofport_map()
|
||||||
else:
|
expected = {'2ab72a72-4407-4ef3-806a-b2172f3e4dc7': 2, 'patch-tun': 1}
|
||||||
id_key = 'iface-id'
|
self.assertEqual(expected, results)
|
||||||
|
|
||||||
|
def test_get_vif_ports(self):
|
||||||
|
pname = "tap99"
|
||||||
|
ofport = 6
|
||||||
|
vif_id = uuidutils.generate_uuid()
|
||||||
|
mac = "ca:fe:de:ad:be:ef"
|
||||||
|
id_field = 'iface-id'
|
||||||
|
external_ids = {"attached-mac": mac, id_field: vif_id}
|
||||||
|
self.br.get_ports_attributes = mock.Mock(return_value=[{
|
||||||
|
'name': pname, 'ofport': ofport, 'external_ids': external_ids}])
|
||||||
|
|
||||||
|
ports = self.br.get_vif_ports()
|
||||||
|
self.assertEqual(1, len(ports))
|
||||||
|
self.assertEqual(ports[0].port_name, pname)
|
||||||
|
self.assertEqual(ports[0].ofport, ofport)
|
||||||
|
self.assertEqual(ports[0].vif_id, vif_id)
|
||||||
|
self.assertEqual(ports[0].vif_mac, mac)
|
||||||
|
self.assertEqual(ports[0].switch.br_name, self.BR_NAME)
|
||||||
|
self.br.get_ports_attributes.assert_called_once_with(
|
||||||
|
'Interface',
|
||||||
|
columns=['name', 'external_ids', 'ofport'],
|
||||||
|
if_exists=True)
|
||||||
|
|
||||||
|
def test_get_vif_port_set(self):
|
||||||
|
id_key = 'iface-id'
|
||||||
headings = ['name', 'external_ids', 'ofport']
|
headings = ['name', 'external_ids', 'ofport']
|
||||||
data = [
|
data = [
|
||||||
# A vif port on this bridge:
|
# A vif port on this bridge:
|
||||||
@@ -558,34 +559,9 @@ class OVS_Lib_Test(base.BaseTestCase):
|
|||||||
]
|
]
|
||||||
tools.setup_mock_calls(self.execute, expected_calls_and_values)
|
tools.setup_mock_calls(self.execute, expected_calls_and_values)
|
||||||
|
|
||||||
if is_xen:
|
|
||||||
get_xapi_iface_id = mock.patch.object(self.br,
|
|
||||||
'get_xapi_iface_id').start()
|
|
||||||
get_xapi_iface_id.return_value = 'tap99id'
|
|
||||||
|
|
||||||
port_set = self.br.get_vif_port_set()
|
port_set = self.br.get_vif_port_set()
|
||||||
self.assertEqual(set(['tap99id']), port_set)
|
self.assertEqual(set(['tap99id']), port_set)
|
||||||
tools.verify_mock_calls(self.execute, expected_calls_and_values)
|
tools.verify_mock_calls(self.execute, expected_calls_and_values)
|
||||||
if is_xen:
|
|
||||||
get_xapi_iface_id.assert_called_once_with('tap99id')
|
|
||||||
|
|
||||||
def test_get_vif_port_to_ofport_map(self):
|
|
||||||
self.execute.return_value = OVSLIST_WITH_UNSET_PORT
|
|
||||||
results = self.br.get_vif_port_to_ofport_map()
|
|
||||||
expected = {'2ab72a72-4407-4ef3-806a-b2172f3e4dc7': 2, 'patch-tun': 1}
|
|
||||||
self.assertEqual(expected, results)
|
|
||||||
|
|
||||||
def test_get_vif_ports_nonxen(self):
|
|
||||||
self._test_get_vif_ports(is_xen=False)
|
|
||||||
|
|
||||||
def test_get_vif_ports_xen(self):
|
|
||||||
self._test_get_vif_ports(is_xen=True)
|
|
||||||
|
|
||||||
def test_get_vif_port_set_nonxen(self):
|
|
||||||
self._test_get_vif_port_set(False)
|
|
||||||
|
|
||||||
def test_get_vif_port_set_xen(self):
|
|
||||||
self._test_get_vif_port_set(True)
|
|
||||||
|
|
||||||
def test_get_vif_ports_list_ports_error(self):
|
def test_get_vif_ports_list_ports_error(self):
|
||||||
expected_calls_and_values = [
|
expected_calls_and_values = [
|
||||||
|
Reference in New Issue
Block a user