From 92735379fe1511139829003527777dec0396b211 Mon Sep 17 00:00:00 2001 From: Ann Kamyshnikova Date: Wed, 21 Oct 2015 17:37:34 +0300 Subject: [PATCH] Skip bindings with agent_id=None To avoid having extra L3HARouterAgentPortBinding with l3_agent as None, operation of setting l3_agent should be atomic. For this purpose, transaction was added in methods create_ha_port_and_bind and _bind_ha_router_to_agents in change Iaad82fe522cfd70061daecf411c924fdc11b7e41 In case if router was just created and l3 agent was not scheduled yet, so l3_agent_id is None, l3-agent-list-hosting-router will fail. This change makes it work by skipping binding with agent_id=None. Partial-bug: #1499647 Change-Id: I1aaf4b651f738febc26b0e1105aeabe066bca2a0 (cherry picked from commit 0b8f9d0948cdb429c4b67ba138640ae515ffa1b2) --- neutron/db/l3_hamode_db.py | 3 ++- neutron/tests/unit/db/test_l3_hamode_db.py | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/neutron/db/l3_hamode_db.py b/neutron/db/l3_hamode_db.py index e25eea014ee..076ccc1f0e1 100644 --- a/neutron/db/l3_hamode_db.py +++ b/neutron/db/l3_hamode_db.py @@ -502,7 +502,8 @@ class L3_HA_NAT_db_mixin(l3_dvr_db.L3_NAT_with_dvr_db_mixin): self, context, router_id): """Return a list of [(agent, ha_state), ...].""" bindings = self.get_ha_router_port_bindings(context, [router_id]) - return [(binding.agent, binding.state) for binding in bindings] + return [(binding.agent, binding.state) for binding in bindings + if binding.agent is not None] def get_active_host_for_ha_router(self, context, router_id): bindings = self.get_l3_bindings_hosting_router_with_ha_states( diff --git a/neutron/tests/unit/db/test_l3_hamode_db.py b/neutron/tests/unit/db/test_l3_hamode_db.py index 3daab316a93..af05a0c8e11 100644 --- a/neutron/tests/unit/db/test_l3_hamode_db.py +++ b/neutron/tests/unit/db/test_l3_hamode_db.py @@ -161,8 +161,27 @@ class L3HATestCase(L3HATestFramework): self.assertIn((self.agent1['id'], 'active'), agent_ids) self.assertIn((self.agent2['id'], 'standby'), agent_ids) + def test_get_l3_bindings_hosting_router_with_ha_states_agent_none(self): + router = self._create_router() + # Do not bind router to leave agents as None + res = self.admin_ctx.session.query( + l3_hamode_db.L3HARouterAgentPortBinding).filter( + l3_hamode_db.L3HARouterAgentPortBinding.router_id == router['id'] + ).all() + # Check that agents are None + self.assertEqual([None, None], [r.agent for r in res]) + bindings = self.plugin.get_l3_bindings_hosting_router_with_ha_states( + self.admin_ctx, router['id']) + self.assertEqual([], bindings) + def test_get_l3_bindings_hosting_router_with_ha_states_not_scheduled(self): router = self._create_router(ha=False) + # Check that there no L3 agents scheduled for this router + res = self.admin_ctx.session.query( + l3_hamode_db.L3HARouterAgentPortBinding).filter( + l3_hamode_db.L3HARouterAgentPortBinding.router_id == router['id'] + ).all() + self.assertEqual([], [r.agent for r in res]) bindings = self.plugin.get_l3_bindings_hosting_router_with_ha_states( self.admin_ctx, router['id']) self.assertEqual([], bindings)