def _lock_subnetpool(self): """Lock subnetpool associated row. This method disallows to allocate concurrently 2 subnets in the same subnetpool, it's required to ensure non-overlapping cidrs in the same subnetpool. """ with db_api.CONTEXT_READER.using(self._context): current_hash = (self._context.session.query( models_v2.SubnetPool.hash).filter_by( id=self._subnetpool['id']).scalar()) if current_hash is None: # NOTE(cbrandily): subnetpool has been deleted raise exceptions.SubnetPoolNotFound( subnetpool_id=self._subnetpool['id']) new_hash = uuidutils.generate_uuid() # NOTE(cbrandily): the update disallows 2 concurrent subnet allocation # to succeed: at most 1 transaction will succeed, others will be # rolled back and be caught in neutron.db.v2.base with db_api.CONTEXT_WRITER.using(self._context): query = (self._context.session.query( models_v2.SubnetPool).filter_by(id=self._subnetpool['id'], hash=current_hash)) count = query.update({'hash': new_hash}) if not count: raise db_exc.RetryRequest( exceptions.SubnetPoolInUse( subnet_pool_id=self._subnetpool['id']))
def _get_subnetpool(self, context, id): subnetpool = subnetpool_obj.SubnetPool.get_object( context, id=id) if not subnetpool: raise exceptions.SubnetPoolNotFound(subnetpool_id=id) return subnetpool