diff --git a/neutron/agent/linux/ovsdb_monitor.py b/neutron/agent/linux/ovsdb_monitor.py index bf1edf3b19b..a830de740e3 100644 --- a/neutron/agent/linux/ovsdb_monitor.py +++ b/neutron/agent/linux/ovsdb_monitor.py @@ -26,6 +26,7 @@ LOG = logging.getLogger(__name__) OVSDB_ACTION_INITIAL = 'initial' OVSDB_ACTION_INSERT = 'insert' OVSDB_ACTION_DELETE = 'delete' +OVSDB_ACTION_NEW = 'new' class OvsdbMonitor(async_process.AsyncProcess): @@ -85,6 +86,7 @@ class SimpleInterfaceMonitor(OvsdbMonitor): def process_events(self): devices_added = [] devices_removed = [] + dev_to_ofport = {} for row in self.iter_stdout(): json = jsonutils.loads(row).get('data') for ovs_id, action, name, ofport, external_ids in json: @@ -99,8 +101,14 @@ class SimpleInterfaceMonitor(OvsdbMonitor): devices_added.append(device) elif action == OVSDB_ACTION_DELETE: devices_removed.append(device) + elif action == OVSDB_ACTION_NEW: + dev_to_ofport[name] = ofport + self.new_events['added'].extend(devices_added) self.new_events['removed'].extend(devices_removed) + # update any events with ofports received from 'new' action + for event in self.new_events['added']: + event['ofport'] = dev_to_ofport.get(event['name'], event['ofport']) def start(self, block=False, timeout=5): super(SimpleInterfaceMonitor, self).start() diff --git a/neutron/tests/functional/agent/linux/test_ovsdb_monitor.py b/neutron/tests/functional/agent/linux/test_ovsdb_monitor.py index d2e206a46d6..d83d17a598b 100644 --- a/neutron/tests/functional/agent/linux/test_ovsdb_monitor.py +++ b/neutron/tests/functional/agent/linux/test_ovsdb_monitor.py @@ -24,6 +24,7 @@ Tests in this module will be skipped unless: from oslo_config import cfg +from neutron.agent.common import ovs_lib from neutron.agent.linux import ovsdb_monitor from neutron.agent.linux import utils from neutron.tests.common import net_helpers @@ -133,3 +134,18 @@ class TestSimpleInterfaceMonitor(BaseMonitorTest): devices = self.monitor.get_events() self.assertTrue(devices.get('added'), 'Initial call should always be true') + + def test_get_events_includes_ofport(self): + utils.wait_until_true(lambda: self.monitor.has_updates) + self.monitor.get_events() # clear initial events + br = self.useFixture(net_helpers.OVSBridgeFixture()) + p1 = self.useFixture(net_helpers.OVSPortFixture(br.bridge)) + + def p1_event_has_ofport(): + if not self.monitor.has_updates: + return + for e in self.monitor.new_events['added']: + if (e['name'] == p1.port.name and + e['ofport'] != ovs_lib.UNASSIGNED_OFPORT): + return True + utils.wait_until_true(p1_event_has_ofport)