def add_tunnel_endpoint(ip, max_retries=10): """Return the endpoint of the given IP address or generate a new one.""" # NOTE(rpodolyaka): generation of a new tunnel endpoint must be put into a # repeatedly executed transactional block to ensure it # doesn't conflict with any other concurrently executed # DB transactions in spite of the specified transactions # isolation level value for i in xrange(max_retries): LOG.debug(_('Adding a tunnel endpoint for %s'), ip) try: session = db.get_session() with session.begin(subtransactions=True): tunnel = (session.query( ovs_models_v2.TunnelEndpoint).filter_by( ip_address=ip).with_lockmode('update').first()) if tunnel is None: tunnel_id = _generate_tunnel_id(session) tunnel = ovs_models_v2.TunnelEndpoint(ip, tunnel_id) session.add(tunnel) return tunnel except db_exc.DBDuplicateEntry: # a concurrent transaction has been committed, try again LOG.debug( _('Adding a tunnel endpoint failed due to a concurrent' 'transaction had been committed (%s attempts left)'), max_retries - (i + 1)) raise q_exc.NeutronException( message=_('Unable to generate a new tunnel id'))
def test_add_tunnel_endpoint_retrieve_an_existing_endpoint(self): addr = '10.0.0.1' self.session.add(ovs_models.TunnelEndpoint(ip_address=addr, id=1)) self.session.flush() tunnel = ovs_db_v2.add_tunnel_endpoint(addr) self.assertEqual(tunnel.id, 1) self.assertEqual(tunnel.ip_address, addr)
def add_tunnel_endpoint(ip): session = db.get_session() try: tunnel = (session.query(ovs_models_v2.TunnelEndpoint).filter_by( ip_address=ip).with_lockmode('update').one()) except exc.NoResultFound: tunnel_id = _generate_tunnel_id(session) tunnel = ovs_models_v2.TunnelEndpoint(ip, tunnel_id) session.add(tunnel) session.flush() return tunnel