diff --git a/neutron/common/ovn/utils.py b/neutron/common/ovn/utils.py index 467f0311bdd..b07f484c5ab 100644 --- a/neutron/common/ovn/utils.py +++ b/neutron/common/ovn/utils.py @@ -828,3 +828,10 @@ def get_ovn_chassis_other_config(chassis): return chassis.other_config except AttributeError: return chassis.external_ids + + +def get_requested_chassis(requested_chassis): + """Returns a list with the items in the LSP.options:requested-chassis""" + if isinstance(requested_chassis, str): + return requested_chassis.split(',') + return [] diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovsdb_monitor.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovsdb_monitor.py index f089077a05b..8d509f546ea 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovsdb_monitor.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovsdb_monitor.py @@ -275,6 +275,15 @@ class PortBindingChassisUpdateEvent(row_event.RowEvent): {'port': row.logical_port, 'binding': row.uuid}) return False + req_chassis = utils.get_requested_chassis( + row.options.get(ovn_const.LSP_OPTIONS_REQUESTED_CHASSIS_KEY, '')) + if len(req_chassis) > 1: + # This event has been issued during a LSP migration. During this + # process, the LSP will change the port binding but the port status + # will be handled by the ``LogicalSwitchPortUpdateDownEvent`` and + # ``LogicalSwitchPortUpdateUpEvent`` events. + return False + return bool(lsp.up) def run(self, event, row, old=None): diff --git a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py index c1d4279fcd4..25d62094612 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py +++ b/neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py @@ -356,6 +356,7 @@ class TestPortBindingChassisUpdateEvent(base.BaseTestCase): self.driver.set_port_status_up.assert_called() else: self.driver.set_port_status_up.assert_not_called() + self.driver.set_port_status_up.reset_mock() def test_event_matches(self): # NOTE(twilson) This primarily tests implementation details. If a @@ -365,10 +366,24 @@ class TestPortBindingChassisUpdateEvent(base.BaseTestCase): attrs={'name': 'Port_Binding'}) ovsdb_row = fakes.FakeOvsdbRow.create_one_ovsdb_row self.driver.nb_ovn.lookup.return_value = ovsdb_row(attrs={'up': True}) + + # Port binding change. self._test_event( self.event.ROW_UPDATE, ovsdb_row(attrs={'_table': pbtable, 'chassis': 'one', - 'type': '_fake_', 'logical_port': 'foo'}), + 'type': '_fake_', 'logical_port': 'foo', + 'options': {}}), + ovsdb_row(attrs={'_table': pbtable, 'chassis': 'two', + 'type': '_fake_'})) + + # Port binding change because of a live migration in progress. + options = { + ovn_const.LSP_OPTIONS_REQUESTED_CHASSIS_KEY: 'chassis1,chassis2'} + self._test_event( + self.event.ROW_UPDATE, + ovsdb_row(attrs={'_table': pbtable, 'chassis': 'one', + 'type': '_fake_', 'logical_port': 'foo', + 'options': options}), ovsdb_row(attrs={'_table': pbtable, 'chassis': 'two', 'type': '_fake_'}))