From 9e0c075bf169ed6f3d768cf23be6f47aeae0f98e Mon Sep 17 00:00:00 2001 From: Jakub Libosvar Date: Thu, 12 Aug 2021 16:48:59 +0200 Subject: [PATCH] ovn: Don't fail db-sync if port binding changes During migration from OVS to OVN it can happen that gateway ports are scheduled to a different gateway chassis when Neutron is running. This patch doesn't fail in such case. The migration procedure runs the db sync twice in a row so it should be good to not perform any action when this happens and let the next migration handle that. Change-Id: I28a4a5fef20d5049f4887d43006947b434de3d78 Closes-Bug: #1939704 Signed-off-by: Jakub Libosvar --- .../plugins/ml2/drivers/ovn/db_migration.py | 9 ++++++- .../ml2/drivers/ovn/test_db_migration.py | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/neutron/plugins/ml2/drivers/ovn/db_migration.py b/neutron/plugins/ml2/drivers/ovn/db_migration.py index c5e3d8c78f9..7180c30d802 100644 --- a/neutron/plugins/ml2/drivers/ovn/db_migration.py +++ b/neutron/plugins/ml2/drivers/ovn/db_migration.py @@ -15,6 +15,7 @@ from neutron_lib.api.definitions import portbindings as pb_api from neutron_lib import context as n_context from neutron_lib.db import api as db_api +from neutron_lib import exceptions from neutron.db.models.plugins.ml2 import geneveallocation from neutron.db.models.plugins.ml2 import vxlanallocation @@ -66,7 +67,13 @@ def migrate_neutron_database_to_ovn(plugin): pass if vif_details != pb.vif_details: pb.vif_details = vif_details - pb.update() + try: + pb.update() + except exceptions.ObjectNotFound: + # When Neutron server is running, it could happen that + # for example gateway port has been rescheduled to a + # different gateway chassis. + pass for trunk in trunk_obj.Trunk.get_objects(ctx): for subport in trunk.sub_ports: diff --git a/neutron/tests/unit/plugins/ml2/drivers/ovn/test_db_migration.py b/neutron/tests/unit/plugins/ml2/drivers/ovn/test_db_migration.py index a70e84f67cb..31761e05023 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/ovn/test_db_migration.py +++ b/neutron/tests/unit/plugins/ml2/drivers/ovn/test_db_migration.py @@ -12,10 +12,13 @@ # License for the specific language governing permissions and limitations # under the License. +from unittest import mock + from neutron_lib.api.definitions import portbindings as pb from neutron_lib.api.definitions import provider_net as pnet from neutron_lib import context as n_context from neutron_lib.db import api as db_api +from neutron_lib import exceptions from oslo_utils import uuidutils from neutron.db.models.plugins.ml2 import geneveallocation @@ -156,3 +159,25 @@ class TestMigrateNeutronDatabaseToOvn( self._create_ml2_ovs_test_resources(vif_details_list) db_migration.migrate_neutron_database_to_ovn(self.mech_driver._plugin) self._validate_resources_after_migration(expected_vif_details) + + def test_db_migration_with_pb_not_found(self): + vif_details_list = [ + {pb.CAP_PORT_FILTER: "true", + pb.OVS_HYBRID_PLUG: "true", + pb.VIF_DETAILS_BRIDGE_NAME: "foo", + pb.VIF_DETAILS_CONNECTIVITY: "l2"}, + {pb.CAP_PORT_FILTER: "true", + pb.VIF_DETAILS_BRIDGE_NAME: "foo"}, + {"foo": "bar"}, + {}, + ] + + self._create_ml2_ovs_test_resources(vif_details_list) + with mock.patch.object( + port_obj.PortBinding, 'update', + side_effect=exceptions.ObjectNotFound(id='foo')): + with mock.patch.object(trunk_obj.Trunk, 'get_objects', + return_value=[]): + db_migration.migrate_neutron_database_to_ovn( + self.mech_driver._plugin) + self._validate_resources_after_migration(vif_details_list)