def bind(self, context, agents, network_id): """Bind the network to the agents.""" # customize the bind logic bound_agents = agents[:] for agent in agents: # saving agent_id to use it after rollback to avoid # DetachedInstanceError agent_id = agent.id binding = agentschedulers_db.NetworkDhcpAgentBinding() binding.dhcp_agent_id = agent_id binding.network_id = network_id try: with db_api.autonested_transaction(context.session): context.session.add(binding) # try to actually write the changes and catch integrity # DBDuplicateEntry except db_exc.DBDuplicateEntry: # it's totally ok, someone just did our job! bound_agents.remove(agent) LOG.info(_LI('Agent %s already present'), agent_id) LOG.debug( 'Network %(network_id)s is scheduled to be ' 'hosted by DHCP agent %(agent_id)s', { 'network_id': network_id, 'agent_id': agent_id }) super(DhcpFilter, self).bind(context, bound_agents, network_id)
def test_filter_bindings(self): bindings = [ sched_db.NetworkDhcpAgentBinding(network_id='foo1', dhcp_agent={'id': 'id1'}), sched_db.NetworkDhcpAgentBinding(network_id='foo2', dhcp_agent={'id': 'id1'}), sched_db.NetworkDhcpAgentBinding(network_id='foo3', dhcp_agent={'id': 'id2'}), sched_db.NetworkDhcpAgentBinding(network_id='foo4', dhcp_agent={'id': 'id2'})] with mock.patch.object(self, 'agent_starting_up', side_effect=[True, False]): res = [b for b in self._filter_bindings(None, bindings)] # once per each agent id1 and id2 self.assertEqual(2, len(res)) res_ids = [b.network_id for b in res] self.assertIn('foo3', res_ids) self.assertIn('foo4', res_ids)
def _schedule_bind_network(self, context, agent, network_id): binding = agentschedulers_db.NetworkDhcpAgentBinding() binding.dhcp_agent = agent binding.network_id = network_id context.session.add(binding) LOG.debug( _('Network %(network_id)s is scheduled to be hosted by ' 'DHCP agent %(agent_id)s'), { 'network_id': network_id, 'agent_id': agent })
def test_remove_networks_from_down_agents_catches_all(self): with contextlib.nested( mock.patch.object( self, 'remove_network_from_dhcp_agent', side_effect=Exception("Unexpected exception!")), mock.patch.object( self, '_filter_bindings', return_value=[sched_db.NetworkDhcpAgentBinding( network_id='foo', dhcp_agent_id='bar')]) ): self.remove_networks_from_down_agents()
def _schedule_bind_network(self, context, agent, network_id): try: binding = agentschedulers_db.NetworkDhcpAgentBinding() binding.dhcp_agent = agent binding.network_id = network_id context.session.add(binding) # try to actually write the changes and catch integrity # DBDuplicateEntry context.session.flush() except db_exc.DBDuplicateEntry: # it's totally ok, someone just did our job! pass LOG.debug(_('Network %(network_id)s is scheduled to be hosted by ' 'DHCP agent %(agent_id)s'), {'network_id': network_id, 'agent_id': agent})
def _schedule_bind_network(self, context, agents, network_id): for agent in agents: context.session.begin(subtransactions=True) try: binding = agentschedulers_db.NetworkDhcpAgentBinding() binding.dhcp_agent = agent binding.network_id = network_id context.session.add(binding) # try to actually write the changes and catch integrity # DBDuplicateEntry context.session.commit() except db_exc.DBDuplicateEntry: # it's totally ok, someone just did our job! context.session.rollback() LOG.info(_LI('Agent %s already present'), agent) LOG.debug('Network %(network_id)s is scheduled to be ' 'hosted by DHCP agent %(agent_id)s', {'network_id': network_id, 'agent_id': agent})
def auto_schedule_networks(self, plugin, context, host): """Schedule non-hosted networks to the DHCP agent on the specified host. """ agents_per_network = cfg.CONF.dhcp_agents_per_network with context.session.begin(subtransactions=True): query = context.session.query(agents_db.Agent) query = query.filter(agents_db.Agent.agent_type == constants.AGENT_TYPE_DHCP, agents_db.Agent.host == host, agents_db.Agent.admin_state_up == True) dhcp_agents = query.all() for dhcp_agent in dhcp_agents: if agents_db.AgentDbMixin.is_agent_down( dhcp_agent.heartbeat_timestamp): LOG.warn(_('DHCP agent %s is not active'), dhcp_agent.id) continue fields = ['network_id', 'enable_dhcp'] subnets = plugin.get_subnets(context, fields=fields) net_ids = set(s['network_id'] for s in subnets if s['enable_dhcp']) if not net_ids: LOG.debug(_('No non-hosted networks')) return False for net_id in net_ids: agents = plugin.get_dhcp_agents_hosting_networks( context, [net_id], active=True) if len(agents) >= agents_per_network: continue if any(dhcp_agent.id == agent.id for agent in agents): continue binding = agentschedulers_db.NetworkDhcpAgentBinding() binding.dhcp_agent = dhcp_agent binding.network_id = net_id context.session.add(binding) return True