Merge "OvsPort to reference lport, not just hold its id"

This commit is contained in:
Jenkins 2017-08-30 13:04:57 +00:00 committed by Gerrit Code Review
commit cee332c33f
8 changed files with 46 additions and 45 deletions

View File

@ -18,7 +18,6 @@ from ryu.ofproto import nicira_ext
from dragonflow.controller.common import constants as const
from dragonflow.controller import df_base_app
from dragonflow.db.models import constants as model_constants
from dragonflow.db.models import l2
from dragonflow.db.models import ovs
@ -43,14 +42,14 @@ class ClassifierApp(df_base_app.DFlowApp):
@df_base_app.register_event(ovs.OvsPort, model_constants.EVENT_UPDATED)
def _ovs_port_created(self, ovs_port, orig_ovs_port=None):
ofport = ovs_port.ofport
lport_id = ovs_port.iface_id
if not lport_id:
lport_ref = ovs_port.lport
if not lport_ref:
return # Not relevant
if orig_ovs_port and orig_ovs_port.ofport != ofport:
self._ovs_port_deleted(ovs_port)
if not ofport or ofport == -1:
return # Not ready yet, or error
lport = self.nb_api.get(l2.LogicalPort(id=lport_id))
lport = self.nb_api.get(lport_ref)
self._ofport_unique_key_map[ovs_port.id] = (ofport, lport.unique_key)
LOG.info("Add local ovs port %(ovs_port)s, logical port "
"%(lport)s for classification",

View File

@ -139,7 +139,7 @@ class Topology(object):
return False
if (port_type == constants.OVS_VM_INTERFACE and
ovs_port.iface_id is None):
ovs_port.lport is None):
return False
return True
@ -187,8 +187,7 @@ class Topology(object):
ovs_port, n_const.PORT_STATUS_ACTIVE)
def _vm_port_updated(self, ovs_port):
lport_id = ovs_port.iface_id
lport = self._get_lport(lport_id)
lport = self._get_lport(ovs_port)
if lport is None:
LOG.warning("No logical port found for ovs port: %s",
ovs_port)
@ -196,10 +195,10 @@ class Topology(object):
topic = lport.topic
if not topic:
return
self._add_to_topic_subscribed(topic, lport_id)
self._add_to_topic_subscribed(topic, lport.id)
self.ovs_to_lport_mapping[ovs_port.id] = OvsLportMapping(
lport_id=lport_id, topic=topic)
lport_id=lport.id, topic=topic)
chassis = lport.binding.chassis
# check if migration occurs
@ -207,13 +206,13 @@ class Topology(object):
device_owner = lport.device_owner
if n_const.DEVICE_OWNER_COMPUTE_PREFIX in device_owner:
LOG.info("Prepare migrate lport %(lport)s to %(chassis)s",
{"lport": lport_id, "chassis": chassis})
{"lport": lport.id, "chassis": chassis})
self.nb_api.create(migration.Migration(
id=lport_id, dest_chassis=self.chassis_name,
id=lport.id, dest_chassis=self.chassis_name,
status=migration.MIGRATION_STATUS_DEST_PLUG))
return
cached_lport = self.db_store.get_one(l2.LogicalPort(id=lport_id))
cached_lport = ovs_port.lport.get_object()
if not cached_lport:
# If the logical port is not in db store it has not been applied
# to dragonflow apps. We need to update it in dragonflow controller
@ -226,15 +225,15 @@ class Topology(object):
def _vm_port_deleted(self, ovs_port):
ovs_port_id = ovs_port.id
lport_id = ovs_port.iface_id
lport = self.db_store.get_one(l2.LogicalPort(id=lport_id))
lport_ref = ovs_port.lport
lport = lport_ref.get_object()
if lport is None:
lport = self.ovs_to_lport_mapping.get(ovs_port_id)
if lport is None:
return
topic = lport.topic
del self.ovs_to_lport_mapping[ovs_port_id]
self._del_from_topic_subscribed(topic, lport_id)
self._del_from_topic_subscribed(topic, lport.id)
return
topic = lport.topic
@ -243,21 +242,22 @@ class Topology(object):
try:
self.controller.delete(lport)
except Exception:
LOG.exception(
'Failed to process logical port offline event %s', lport_id)
LOG.exception('Failed to process logical port offline event %s',
lport_ref.id)
finally:
self.controller.notify_port_status(
ovs_port, n_const.PORT_STATUS_DOWN)
migration_obj = self.nb_api.get(migration.Migration(id=lport_id))
migration_obj = self.nb_api.get(
migration.Migration(id=lport_ref.id))
if migration_obj and migration_obj.chassis:
LOG.info("Sending migrating event for %s", lport_id)
migration_obj.lport = lport_id
LOG.info("Sending migrating event for %s", lport_ref.id)
migration_obj.lport = lport_ref
migration_obj.status = migration.MIGRATION_STATUS_SRC_UNPLUG
self.nb_api.update(migration_obj)
del self.ovs_to_lport_mapping[ovs_port_id]
self._del_from_topic_subscribed(topic, lport_id)
self._del_from_topic_subscribed(topic, lport_ref.id)
def _add_to_topic_subscribed(self, topic, lport_id):
if not self.enable_selective_topo_dist or not topic:
@ -291,15 +291,12 @@ class Topology(object):
# set, which represents no topic is subscribed now.
return set(self.topic_subscribed)
def _get_lport(self, port_id, topic=None):
if topic is None:
lean_lport = l2.LogicalPort(id=port_id)
else:
lean_lport = l2.LogicalPort(id=port_id, topic=topic)
lport = self.db_store.get_one(lean_lport)
def _get_lport(self, ovs_port):
if not ovs_port.lport:
return None
lport = ovs_port.lport.get_object()
if lport is None:
lport = self.nb_api.get(lean_lport)
lport = self.nb_api.get(ovs_port.lport)
return lport
def check_topology_info(self):
@ -314,8 +311,7 @@ class Topology(object):
delete_ovs_to_lport_mapping = self.ovs_to_lport_mapping
for key, ovs_port in self.ovs_ports.items():
if ovs_port.type == constants.OVS_VM_INTERFACE:
lport_id = ovs_port.iface_id
lport = self._get_lport(lport_id)
lport = self._get_lport(ovs_port)
if lport is None:
LOG.warning("No logical port found for ovs port: %s",
ovs_port)
@ -324,10 +320,10 @@ class Topology(object):
if not topic:
continue
new_ovs_to_lport_mapping[key] = OvsLportMapping(
lport_id=lport_id, topic=topic)
lport_id=lport.id, topic=topic)
if not delete_ovs_to_lport_mapping.pop(key, None):
add_ovs_to_lport_mapping[key] = OvsLportMapping(
lport_id=lport_id, topic=topic)
lport_id=lport.id, topic=topic)
self.ovs_to_lport_mapping = new_ovs_to_lport_mapping
for value in add_ovs_to_lport_mapping.values():
lport_id = value.lport_id

View File

@ -14,6 +14,7 @@ from jsonmodels import fields
from dragonflow.common import constants
import dragonflow.db.field_types as df_fields
import dragonflow.db.model_framework as mf
from dragonflow.db.models import l2
from dragonflow.db.models import mixins
@ -44,7 +45,7 @@ class OvsPort(mf.ModelBase, mixins.BasicEvents, mixins.Name):
ofport = fields.IntField()
admin_state = df_fields.EnumField(('up', 'down'))
iface_id = fields.StringField()
lport = df_fields.ReferenceField(l2.LogicalPort)
type = df_fields.EnumField(
(
constants.OVS_BRIDGE_INTERFACE,
@ -84,9 +85,9 @@ class OvsPort(mf.ModelBase, mixins.BasicEvents, mixins.Name):
res.tunnel_type = row.type
external_ids = row.external_ids
iface_id = external_ids.get('iface-id')
if iface_id is not None:
res.iface_id = iface_id
lport_id = external_ids.get('iface-id')
if lport_id is not None:
res.lport = lport_id
attached_mac = external_ids.get('attached-mac')
if attached_mac is not None:

View File

@ -79,8 +79,8 @@ class NbApiNeutronNotifier(neutron_notifier_api.NeutronNotifierDriver):
self.heart_beat_reporter.daemonize()
def notify_port_status(self, ovs_port, status):
port_id = ovs_port.iface_id
self._send_event(l2.LogicalPort.table_name, port_id, 'update', status)
port = ovs_port.lport
self._send_event(l2.LogicalPort.table_name, port.id, 'update', status)
def _send_event(self, table, key, action, value):
listeners = self.nb_api.get_all(core.Listener)

View File

@ -23,6 +23,7 @@ import six
from dragonflow.common import exceptions
from dragonflow.controller.common import constants as df_const
from dragonflow.db import db_store
from dragonflow.db import model_proxy
from dragonflow.db.models import l2
from dragonflow.ovsdb import vswitch_impl
from dragonflow.tests.common import constants as const
@ -245,7 +246,11 @@ def with_nb_objects(*objs):
return res
def _get(obj):
objs = _get_all(type(obj))
if model_proxy.is_model_proxy(obj):
model = obj.get_proxied_model()
else:
model = type(obj)
objs = _get_all(model)
for o in objs:
if obj.id == o.id:
return o

View File

@ -37,7 +37,7 @@ class TestOvsdbMonitor(test_base.DFTestBase):
return False
elif _interface.type != constants.OVS_VM_INTERFACE:
return False
elif _interface.iface_id is None:
elif _interface.lport is None:
return False
elif _interface.ofport <= 0:
return False
@ -58,7 +58,7 @@ class TestOvsdbMonitor(test_base.DFTestBase):
return False
elif _interface.type != constants.OVS_VM_INTERFACE:
return False
elif _interface.iface_id is None:
elif _interface.lport is None:
return False
else:
return True

View File

@ -250,7 +250,7 @@ fake_ovs_port1 = ovs.OvsPort(
name='tap-fake_port1',
admin_state='up',
type=constants.OVS_VM_INTERFACE,
iface_id='fake_port1',
lport='fake_port1',
attached_mac='fa:16:3e:8c:2e:b3',
)
@ -268,7 +268,7 @@ fake_ovs_port2 = ovs.OvsPort(
name='tap-fake_port2',
admin_state='up',
type=constants.OVS_VM_INTERFACE,
iface_id='fake_port2',
lport='fake_port2',
attached_mac='fa:16:3e:8c:2e:b4',
)

View File

@ -55,7 +55,7 @@ class TestClassifierAppForVlan(testscenarios.WithScenarios,
self.controller.update(fake_local_vlan_port)
self.app.mod_flow.assert_not_called()
ovs_port = ovs.OvsPort(id='fake_ovs_port',
iface_id=fake_local_vlan_port.id,
lport=fake_local_vlan_port.id,
ofport=1, admin_state='up',
type=constants.OVS_VM_INTERFACE)
self.controller.update(ovs_port)