DVR:don't reschedule the l3 agent running on compute node
For a DVR router, when it updates router gateway_ip, it should not reschedule the l3 agents running on compute nodes whose mode is dvr, it just need to reschedule the l3 agents running on network nodes whose mode is dvr_snat. Change-Id: Ib8ea6797c88cefb473eff9a8a7b2517a6aa90ca4 Closes-bug: #1496204 Co-Authored-By: Oleg Bondarev <obondarev@mirantis.com>
This commit is contained in:
parent
5b804251ac
commit
13ce7c8555
|
@ -279,6 +279,11 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
|
|||
RouterL3AgentBinding.l3_agent_id == agent_id)
|
||||
query.delete()
|
||||
|
||||
def _unschedule_router(self, context, router_id, agents_ids):
|
||||
with context.session.begin(subtransactions=True):
|
||||
for agent_id in agents_ids:
|
||||
self._unbind_router(context, router_id, agent_id)
|
||||
|
||||
def reschedule_router(self, context, router_id, candidates=None):
|
||||
"""Reschedule router to (a) new l3 agent(s)
|
||||
|
||||
|
@ -288,8 +293,8 @@ class L3AgentSchedulerDbMixin(l3agentscheduler.L3AgentSchedulerPluginBase,
|
|||
cur_agents = self.list_l3_agents_hosting_router(
|
||||
context, router_id)['agents']
|
||||
with context.session.begin(subtransactions=True):
|
||||
for agent in cur_agents:
|
||||
self._unbind_router(context, router_id, agent['id'])
|
||||
cur_agents_ids = [agent['id'] for agent in cur_agents]
|
||||
self._unschedule_router(context, router_id, cur_agents_ids)
|
||||
|
||||
self.schedule_router(context, router_id, candidates=candidates)
|
||||
new_agents = self.list_l3_agents_hosting_router(
|
||||
|
|
|
@ -389,12 +389,14 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
|
|||
context, router_id, chosen_agent)
|
||||
return chosen_agent
|
||||
|
||||
def _unbind_router(self, context, router_id, agent_id):
|
||||
def _unschedule_router(self, context, router_id, agents_ids):
|
||||
router = self.get_router(context, router_id)
|
||||
super(L3_DVRsch_db_mixin, self)._unbind_router(context, router_id,
|
||||
agent_id)
|
||||
if router.get('distributed', False):
|
||||
self.unbind_snat(context, router_id, agent_id)
|
||||
# for DVR router unscheduling means just unscheduling SNAT portion
|
||||
self.unbind_snat_servicenode(context, router_id)
|
||||
else:
|
||||
super(L3_DVRsch_db_mixin, self)._unschedule_router(
|
||||
context, router_id, agents_ids)
|
||||
|
||||
def _get_active_l3_agent_routers_sync_data(self, context, host, agent,
|
||||
router_ids):
|
||||
|
|
|
@ -755,21 +755,20 @@ class OvsAgentSchedulerTestCase(OvsAgentSchedulerTestCaseBase):
|
|||
self.assertFalse(ret_b)
|
||||
|
||||
def test_router_is_not_rescheduled_from_dvr_agent(self):
|
||||
router = {'name': 'router1',
|
||||
'admin_state_up': True,
|
||||
'distributed': True}
|
||||
subnet_ids = {'id': '1234'}
|
||||
r = self.l3plugin.create_router(
|
||||
self.adminContext, {'router': router})
|
||||
dvr_agent = self._register_dvr_agents()[1]
|
||||
with self.subnet() as s, \
|
||||
mock.patch.object(
|
||||
self.l3plugin,
|
||||
'check_ports_exist_on_l3agent') as port_exists:
|
||||
net_id = s['subnet']['network_id']
|
||||
self._set_net_external(net_id)
|
||||
router = {'name': 'router1',
|
||||
'admin_state_up': True,
|
||||
'external_gateway_info': {'network_id': net_id},
|
||||
'distributed': True}
|
||||
r = self.l3plugin.create_router(
|
||||
self.adminContext, {'router': router})
|
||||
dvr_snat_agent, dvr_agent = self._register_dvr_agents()
|
||||
|
||||
with mock.patch.object(
|
||||
self.l3plugin,
|
||||
'check_ports_exist_on_l3agent') as port_exists,\
|
||||
mock.patch.object(
|
||||
self.l3plugin,
|
||||
'get_subnet_ids_on_router') as rtr_subnets:
|
||||
rtr_subnets.return_value = [subnet_ids]
|
||||
port_exists.return_value = True
|
||||
self.l3plugin.schedule_router(
|
||||
self.adminContext, r['id'])
|
||||
|
@ -777,12 +776,24 @@ class OvsAgentSchedulerTestCase(OvsAgentSchedulerTestCaseBase):
|
|||
self.assertEqual(2, len(agents['agents']))
|
||||
self.assertIn(dvr_agent['host'],
|
||||
[a['host'] for a in agents['agents']])
|
||||
# router should not be unscheduled from dvr agent
|
||||
self._take_down_agent_and_run_reschedule(dvr_agent['host'])
|
||||
agents = self._list_l3_agents_hosting_router(r['id'])
|
||||
self.assertEqual(2, len(agents['agents']))
|
||||
self.assertIn(dvr_agent['host'],
|
||||
[a['host'] for a in agents['agents']])
|
||||
|
||||
# another dvr_snat agent is needed to test that router is not
|
||||
# unscheduled from dead dvr agent in case rescheduling between
|
||||
# dvr_snat agents happens
|
||||
helpers.register_l3_agent(
|
||||
host='hostC', agent_mode=constants.L3_AGENT_MODE_DVR_SNAT)
|
||||
self._take_down_agent_and_run_reschedule(dvr_snat_agent['host'])
|
||||
agents = self._list_l3_agents_hosting_router(r['id'])
|
||||
self.assertEqual(2, len(agents['agents']))
|
||||
self.assertIn(dvr_agent['host'],
|
||||
[a['host'] for a in agents['agents']])
|
||||
|
||||
def test_router_reschedule_succeeded_after_failed_notification(self):
|
||||
l3_plugin = (manager.NeutronManager.get_service_plugins()
|
||||
[service_constants.L3_ROUTER_NAT])
|
||||
|
|
Loading…
Reference in New Issue