From: Eugene Nikanorov Date: Thu, 4 Jun 2015 21:46:22 +0000 (+0400) Subject: Skip rescheduling networks if no DHCP agents available X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=1318437a0caf38e695a819848832a955fef7d909;p=openstack-build%2Fneutron-build.git Skip rescheduling networks if no DHCP agents available This eliminates the problem of unscheduled networks in case of communication failure between agents and servers which can occur if messaging queue service fails. Change-Id: Ied4fa301fc3d475bee25c47f3a01c2381ae9a01e Closes-Bug: #1461714 --- diff --git a/neutron/db/agentschedulers_db.py b/neutron/db/agentschedulers_db.py index 61eff9b07..b9d9c11db 100644 --- a/neutron/db/agentschedulers_db.py +++ b/neutron/db/agentschedulers_db.py @@ -271,7 +271,16 @@ class DhcpAgentSchedulerDbMixin(dhcpagentscheduler dhcp_notifier = self.agent_notifiers.get(constants.AGENT_TYPE_DHCP) try: - for binding in self._filter_bindings(context, down_bindings): + dead_bindings = [b for b in + self._filter_bindings(context, down_bindings)] + dead_agents = set([b.dhcp_agent_id for b in dead_bindings]) + agents = self.get_agents_db( + context, {'agent_type': [constants.AGENT_TYPE_DHCP]}) + if len(agents) == len(dead_agents): + LOG.warn(_LW("No DHCP agents available, " + "skipping rescheduling")) + return + for binding in dead_bindings: LOG.warn(_LW("Removing network %(network)s from agent " "%(agent)s because the agent did not report " "to the server in the last %(dead_time)s " diff --git a/neutron/tests/unit/scheduler/test_dhcp_agent_scheduler.py b/neutron/tests/unit/scheduler/test_dhcp_agent_scheduler.py index 5ee1adb16..260a5b01a 100644 --- a/neutron/tests/unit/scheduler/test_dhcp_agent_scheduler.py +++ b/neutron/tests/unit/scheduler/test_dhcp_agent_scheduler.py @@ -21,6 +21,7 @@ import testscenarios from neutron.common import constants from neutron import context from neutron.db import agentschedulers_db as sched_db +from neutron.db import common_db_mixin from neutron.db import models_v2 from neutron.extensions import dhcpagentscheduler from neutron.scheduler import dhcp_agent_scheduler @@ -177,7 +178,8 @@ class TestAutoScheduleNetworks(TestDhcpSchedulerBaseTestCase): class TestNetworksFailover(TestDhcpSchedulerBaseTestCase, - sched_db.DhcpAgentSchedulerDbMixin): + sched_db.DhcpAgentSchedulerDbMixin, + common_db_mixin.CommonDbMixin): def test_reschedule_network_from_down_agent(self): agents = self._create_and_set_agents_down(['host-a', 'host-b'], 1) self._test_schedule_bind_network([agents[0]], self.network_id) @@ -201,7 +203,7 @@ class TestNetworksFailover(TestDhcpSchedulerBaseTestCase, mock.ANY, self.network_id, agents[1].host) def _test_failed_rescheduling(self, rn_side_effect=None): - agents = self._create_and_set_agents_down(['host-a'], 1) + agents = self._create_and_set_agents_down(['host-a', 'host-b'], 1) self._test_schedule_bind_network([agents[0]], self.network_id) with mock.patch.object(self, 'remove_network_from_dhcp_agent', @@ -257,6 +259,14 @@ class TestNetworksFailover(TestDhcpSchedulerBaseTestCase, # just make sure that no exception is raised self.remove_networks_from_down_agents() + def test_reschedule_doesnt_occur_if_no_agents(self): + agents = self._create_and_set_agents_down(['host-a'], 1) + self._test_schedule_bind_network([agents[0]], self.network_id) + with mock.patch.object( + self, 'remove_network_from_dhcp_agent') as rn: + self.remove_networks_from_down_agents() + self.assertFalse(rn.called) + class DHCPAgentWeightSchedulerTestCase(TestDhcpSchedulerBaseTestCase): """Unit test scenarios for WeightScheduler.schedule."""