From cd8bf18150c8b0a4bc64979d800726483d9cdb6e Mon Sep 17 00:00:00 2001 From: Slawek Kaplonski Date: Fri, 13 May 2022 11:56:02 +0200 Subject: [PATCH] [L3HA] Don't update HA router's ports if router isn't active on agents In case when HA router isn't active on any L3 agent, _ensure_host_set_on_port method shouldn't try to update port's host to the host from which there was an rpc message sent, as this can be host on which router is in the "standby" mode. This method should only update port's host to the router's "active_host" if there is such active_host found already. Depends-On: https://review.opendev.org/c/openstack/requirements/+/841489 Closes-Bug: #1973162 Closes-Bug: #1942190 Change-Id: Ib3945d294601b35f9b268c25841cd284b52c4ca3 --- neutron/api/rpc/handlers/l3_rpc.py | 17 ++++++++--------- neutron/tests/unit/db/test_l3_hamode_db.py | 12 +++++++++++- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/neutron/api/rpc/handlers/l3_rpc.py b/neutron/api/rpc/handlers/l3_rpc.py index 27557659bb9..6fd3ac274ee 100644 --- a/neutron/api/rpc/handlers/l3_rpc.py +++ b/neutron/api/rpc/handlers/l3_rpc.py @@ -224,22 +224,21 @@ class L3RpcCallback(object): active_host = ( self.l3plugin.get_active_host_for_ha_router( context, router_id)) - if active_host: - host = active_host - # If there is currently no active router instance (For - # example it's a new router), the host that requested - # the routers (Essentially a random host) will do. The - # port binding will be corrected when an active is - # elected. + if not active_host: + LOG.debug("Router %(router)s is not active on any " + "host. Port %(port)s will not be updated " + "now.", + {'router': router_id, 'port': port['id']}) + return try: LOG.debug("Updating router %(router)s port %(port)s " "binding host %(host)s", {"router": router_id, "port": port['id'], - "host": host}) + "host": active_host}) self.plugin.update_port( context, port['id'], - {'port': {portbindings.HOST_ID: host}}) + {'port': {portbindings.HOST_ID: active_host}}) except exceptions.PortNotFound: LOG.debug("Port %(port)s not found while updating " "agent binding for router %(router)s.", diff --git a/neutron/tests/unit/db/test_l3_hamode_db.py b/neutron/tests/unit/db/test_l3_hamode_db.py index aedff2296bf..57e06c042b0 100644 --- a/neutron/tests/unit/db/test_l3_hamode_db.py +++ b/neutron/tests/unit/db/test_l3_hamode_db.py @@ -1246,9 +1246,19 @@ class L3HAModeDbTestCase(L3HATestFramework): self.plugin.list_active_sync_routers_on_active_l3_agent( self.admin_ctx, self.agent1['host'], [router['id']]))[0] - # ensure_host_set_on_ports binds an unbound port callback = l3_rpc.L3RpcCallback() callback._l3plugin = self.plugin + # First ensure that port is not bound if router is not active on any + # agent + callback._ensure_host_set_on_ports( + self.admin_ctx, self.agent1['host'], [router]) + port = self._get_first_interface(router['id']) + self.assertEqual('', port[portbindings.HOST_ID]) + + # Now update router to be active on agent1 + # and ensure_host_set_on_ports binds an unbound port + self.plugin.update_routers_states( + self.admin_ctx, {router['id']: 'active'}, self.agent1['host']) callback._ensure_host_set_on_ports( self.admin_ctx, self.agent1['host'], [router]) port = self._get_first_interface(router['id'])