From 04e9b063ad526778ba80438fc851e03fa16e5085 Mon Sep 17 00:00:00 2001 From: Mohammed Naser Date: Tue, 26 Sep 2023 20:02:55 +0000 Subject: [PATCH] [OVN] Match LSP_TYPE_VIRTUAL in PortBindingUpdateVirtualPortsEvent With newer versions of OVN, port bindings are removed and added for both virtual ports and container ports (aka trunk ports in Neutron world)[1][2]. With this, Neutron recently landed a change in order to handle virtual ports for the update/delete steps[3], however, this has resulted in unexpected behaviour where the binding information is wiped for trunk ports, then subsequently removed on the next maintenance run. We should make sure that we only have row deletes for virtual ports specifically rather than all ports. [1]: https://github.com/ovn-org/ovn/commit/ec933537f9b04b35ef4b79fb2b4743f9095da209 [2]: https://github.com/ovn-org/ovn/commit/28d40c0a024227c9c845117087b7594723ff0ec7 [3]: https://review.opendev.org/c/openstack/neutron/+/883681 Related-Bug: #2024160 Change-Id: Ide3204748274cbab9731310c2e2bd8bd8c9a53ff (cherry picked from commit 1160aaa4716904fdba06a8dcfbc1d5a2ce419e72) --- .../ovn/mech_driver/ovsdb/ovsdb_monitor.py | 2 +- .../mech_driver/ovsdb/test_ovsdb_monitor.py | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) 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 3ea7311b911..f5c5b5c2c03 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 @@ -557,7 +557,7 @@ class PortBindingUpdateVirtualPortsEvent(row_event.RowEvent): if event == self.ROW_DELETE: # The port binding has been deleted, delete the host ID (if the # port was not deleted before). - return True + return row.type == ovn_const.LSP_TYPE_VIRTUAL virtual_parents = (row.options or {}).get( ovn_const.LSP_OPTIONS_VIRTUAL_PARENTS_KEY) diff --git a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py index 1e15019ff50..203f33509bb 100644 --- a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py +++ b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovsdb_monitor.py @@ -360,12 +360,6 @@ class TestNBDbMonitor(base.TestOVNFunctionalBase): # and the corresponding "virtual-parents". self._check_port_binding_type(vip['id'], ovn_const.LSP_TYPE_VIRTUAL) self._check_port_virtual_parents(vip['id'], port['id']) - n_utils.wait_until_true(lambda: mock_update_vip_host.called, - timeout=10) - # The "Port_Binding" has been deleted. Then the "Port_Binding" register - # is created again without virtual_parents, but this event doesn't - # call "update_virtual_port_host". - mock_update_vip_host.assert_called_once_with(vip['id'], None) # 2) Unset the allowed address pairs. # Assign the VIP again and delete the virtual port. @@ -406,6 +400,19 @@ class TestNBDbMonitor(base.TestOVNFunctionalBase): # if this behaviour is changed. mock_update_vip_host.assert_called_with(vip['id'], None) + @mock.patch.object(mech_driver.OVNMechanismDriver, + 'update_virtual_port_host') + def test_non_virtual_port_no_host_update(self, mock_update_vip_host): + # The ``PortBindingUpdateVirtualPortsEvent`` delete event should affect + # only to virtual ports. This check is done for virtual ports in + # ``test_virtual_port_host_update``. + port = self.create_port() + self._delete('ports', port['id']) + # We actively wait for 5 seconds for the ``Port_Binding`` event to + # arrive and be processed, but the port host must not be updated. + self.assertRaises(n_utils.WaitTimeout, n_utils.wait_until_true, + lambda: mock_update_vip_host.called, timeout=5) + class TestNBDbMonitorOverTcp(TestNBDbMonitor): def get_ovsdb_server_protocol(self):