def vm_resource_backup_metadata_delete(context, metadata_ref, session=None): """ Used internally by vm_resource_backup_metadata_create and vm_resource_backup_metadata_update """ session = get_session() metadata_ref.delete(session=session) return metadata_ref
def quota_destroy_all_by_project(context, project_id): session = get_session() with session.begin(): quotas = model_query(context, models.Quota, session=session, read_deleted="no").\ filter_by(project_id=project_id).\ all() for quota_ref in quotas: quota_ref.delete(session=session) quota_usages = model_query(context, models.QuotaUsage, session=session, read_deleted="no").\ filter_by(project_id=project_id).\ all() for quota_usage_ref in quota_usages: quota_usage_ref.delete(session=session) reservations = model_query(context, models.Reservation, session=session, read_deleted="no").\ filter_by(project_id=project_id).\ all() for reservation_ref in reservations: reservation_ref.delete(session=session)
def quota_class_update(context, class_name, resource, limit): session = get_session() with session.begin(): quota_class_ref = quota_class_get(context, class_name, resource, session=session) quota_class_ref.hard_limit = limit quota_class_ref.save(session=session)
def model_query(context, *args, **kwargs): """Query helper that accounts for context's `read_deleted` field. :param context: context to query under :param session: if present, the session to use :param read_deleted: if present, overrides context's read_deleted field. :param project_only: if present and context is user-type, then restrict query to match the context's project_id. """ session = kwargs.get('session') or get_session() read_deleted = kwargs.get('read_deleted') or context.read_deleted project_only = kwargs.get('project_only') query = session.query(*args) if read_deleted == 'no': query = query.filter_by(deleted=False) elif read_deleted == 'yes': pass # omit the filter to include deleted and active elif read_deleted == 'only': query = query.filter_by(deleted=True) else: raise Exception( _("Unrecognized read_deleted value '%s'") % read_deleted) if project_only and is_user_context(context): query = query.filter_by(project_id=context.project_id) return query
def quota_class_destroy(context, class_name, resource): session = get_session() with session.begin(): quota_class_ref = quota_class_get(context, class_name, resource, session=session) quota_class_ref.delete(session=session)
def vm_resource_backups_destroy(context, backupjobrun_vm_resource_id): session = get_session() with session.begin(): session.query(models.VMResourceBackups).\ filter_by(backupjobrun_vm_resource_id=backupjobrun_vm_resource_id).\ update({'status': 'deleted', 'deleted': True, 'deleted_at': timeutils.utcnow(), 'updated_at': literal_column('updated_at')})
def vault_service_destroy(context, id): session = get_session() with session.begin(): session.query(models.VaultServices).\ filter_by(id=id).\ update({'status': 'deleted', 'deleted': True, 'deleted_at': timeutils.utcnow(), 'updated_at': literal_column('updated_at')})
def backupjob_destroy(context, backupjob_id): session = get_session() with session.begin(): session.query(models.BackupJob).\ filter_by(id=backupjob_id).\ update({'status': 'deleted', 'deleted': True, 'deleted_at': timeutils.utcnow(), 'updated_at': literal_column('updated_at')})
def _vm_resource_backup_metadata_update(context, metadata_ref, values, session=None): """ Used internally by vm_resource_backup_metadata_create and vm_resource_backup_metadata_update """ session = get_session() values["deleted"] = False metadata_ref.update(values) metadata_ref.save(session=session) return metadata_ref
def vm_recent_backupjobrun_destroy(context, vm_id): session = get_session() with session.begin(): session.query(models.VMRecentBackupJobRun).\ filter_by(vm_id=vm_id).\ update({'status': 'deleted', 'deleted': True, 'deleted_at': timeutils.utcnow(), 'updated_at': literal_column('updated_at')})
def scheduledjob_delete(context, id): session = get_session() with session.begin(): session.query(models.ScheduledJobs).\ filter_by(id=id).\ update({'status': 'deleted', 'deleted': True, 'deleted_at': timeutils.utcnow(), 'updated_at': literal_column('updated_at')})
def quota_class_destroy_all_by_name(context, class_name): session = get_session() with session.begin(): quota_classes = model_query(context, models.QuotaClass, session=session, read_deleted="no").\ filter_by(class_name=class_name).\ all() for quota_class_ref in quota_classes: quota_class_ref.delete(session=session)
def save(self, session=None): """Save this object.""" if not session: session = get_session() session.add(self) try: session.flush() except IntegrityError, e: if str(e).endswith('is not unique'): raise exception.Duplicate(str(e)) else: raise
def service_get_all_volume_sorted(context): session = get_session() with session.begin(): topic = FLAGS.volume_topic label = 'volume_gigabytes' subq = model_query(context, models.Volume.host, func.sum(models.Volume.size).label(label), session=session, read_deleted="no").\ group_by(models.Volume.host).\ subquery() return _service_get_all_topic_subquery(context, session, topic, subq, label)
def reservation_rollback(context, reservations, project_id=None): session = get_session() with session.begin(): usages = _get_quota_usages(context, session, project_id) for reservation in _quota_reservations(session, context, reservations): usage = usages[reservation.resource] if reservation.delta >= 0: usage.reserved -= reservation.delta reservation.delete(session=session) for usage in usages.values(): usage.save(session=session)
def backupjob_update(context, backupjob_id, values): session = get_session() with session.begin(): backupjob = model_query(context, models.BackupJob, session=session, read_deleted="yes").\ filter_by(id=backupjob_id).first() if not backupjob: raise exception.BackupJobNotFound( _("No backup job with id %(backupjob_id)s") % locals()) backupjob.update(values) backupjob.save(session=session) return backupjob
def vm_resource_backup_get(context, vm_resource_backup_id, session=None): session = get_session() try: query = session.query(models.VMResourceBackups)\ .options(sa_orm.joinedload(models.VMResourceBackups.metadata))\ .filter_by(id= vm_resource_backup_id) #TODO(gbasava): filter out deleted resource backups if context disallows it vm_resource_backup = query.one() except sa_orm.exc.NoResultFound: raise exception.VMResourceBackupsNotFound(vm_resource_backup_id = vm_resource_backup_id) return vm_resource_backup
def vm_resource_backup_get(context, vm_resource_backup_id, session=None): session = get_session() try: query = session.query(models.VMResourceBackups)\ .options(sa_orm.joinedload(models.VMResourceBackups.metadata))\ .filter_by(id= vm_resource_backup_id) #TODO(gbasava): filter out deleted resource backups if context disallows it vm_resource_backup = query.one() except sa_orm.exc.NoResultFound: raise exception.VMResourceBackupsNotFound( vm_resource_backup_id=vm_resource_backup_id) return vm_resource_backup
def scheduledjob_update(context, scheduledjob): session = get_session() values = scheduledjob.__getstate__() del values['_sa_instance_state'] with session.begin(): dbjob = model_query(context, models.ScheduledJobs, session=session, read_deleted="yes").\ filter_by(id=scheduledjob.id).first() if not dbjob: raise exception.BackupJobNotFound( _("No backup job with id %s"), scheduledjob.id) dbjob.update(values) dbjob.save(session=session) return dbjob
def scheduledjob_update(context, scheduledjob): session = get_session() values = scheduledjob.__getstate__() del values['_sa_instance_state'] with session.begin(): dbjob = model_query(context, models.ScheduledJobs, session=session, read_deleted="yes").\ filter_by(id=scheduledjob.id).first() if not dbjob: raise exception.BackupJobNotFound(_("No backup job with id %s"), scheduledjob.id) dbjob.update(values) dbjob.save(session=session) return dbjob
def reservation_expire(context): session = get_session() with session.begin(): current_time = timeutils.utcnow() results = model_query(context, models.Reservation, session=session, read_deleted="no").\ filter(models.Reservation.expire < current_time).\ all() if results: for reservation in results: if reservation.delta >= 0: reservation.usage.reserved -= reservation.delta reservation.usage.save(session=session) reservation.delete(session=session)
def vm_recent_backupjobrun_update(context, vm_id, values): session = get_session() with session.begin(): vm_recent_backupjobrun = model_query(context, models.VMRecentBackupJobRun, session=session, read_deleted="yes").\ filter_by(vm_id = vm_id).first() if not vm_recent_backupjobrun: #raise exception.VMRecentBackupJobRunNotFound( # _("Recent backupjobrun for VM %(vm_id)s is not found") % locals()) values['vm_id'] = vm_id vm_recent_backupjobrun = models.VMRecentBackupJobRun() vm_recent_backupjobrun.update(values) vm_recent_backupjobrun.save(session=session) return vm_recent_backupjobrun
def reservation_destroy(context, uuid): session = get_session() with session.begin(): reservation_ref = reservation_get(context, uuid, session=session) reservation_ref.delete(session=session)
def quota_reserve(context, resources, quotas, deltas, expire, until_refresh, max_age, project_id=None): elevated = context.elevated() session = get_session() with session.begin(): if project_id is None: project_id = context.project_id # Get the current usages usages = _get_quota_usages(context, session, project_id) # Handle usage refresh work = set(deltas.keys()) while work: resource = work.pop() # Do we need to refresh the usage? refresh = False if resource not in usages: usages[resource] = quota_usage_create(elevated, project_id, resource, 0, 0, until_refresh or None, session=session) refresh = True elif usages[resource].in_use < 0: # Negative in_use count indicates a desync, so try to # heal from that... refresh = True elif usages[resource].until_refresh is not None: usages[resource].until_refresh -= 1 if usages[resource].until_refresh <= 0: refresh = True elif max_age and (usages[resource].updated_at - timeutils.utcnow()).seconds >= max_age: refresh = True # OK, refresh the usage if refresh: # Grab the sync routine sync = resources[resource].sync updates = sync(elevated, project_id, session) for res, in_use in updates.items(): # Make sure we have a destination for the usage! if res not in usages: usages[res] = quota_usage_create(elevated, project_id, res, 0, 0, until_refresh or None, session=session) # Update the usage usages[res].in_use = in_use usages[res].until_refresh = until_refresh or None # Because more than one resource may be refreshed # by the call to the sync routine, and we don't # want to double-sync, we make sure all refreshed # resources are dropped from the work set. work.discard(res) # NOTE(Vek): We make the assumption that the sync # routine actually refreshes the # resources that it is the sync routine # for. We don't check, because this is # a best-effort mechanism. # Check for deltas that would go negative unders = [ resource for resource, delta in deltas.items() if delta < 0 and delta + usages[resource].in_use < 0 ] # Now, let's check the quotas # NOTE(Vek): We're only concerned about positive increments. # If a project has gone over quota, we want them to # be able to reduce their usage without any # problems. overs = [ resource for resource, delta in deltas.items() if quotas[resource] >= 0 and delta >= 0 and quotas[resource] < delta + usages[resource].total ] # NOTE(Vek): The quota check needs to be in the transaction, # but the transaction doesn't fail just because # we're over quota, so the OverQuota raise is # outside the transaction. If we did the raise # here, our usage updates would be discarded, but # they're not invalidated by being over-quota. # Create the reservations if not overs: reservations = [] for resource, delta in deltas.items(): reservation = reservation_create(elevated, str(uuid.uuid4()), usages[resource], project_id, resource, delta, expire, session=session) reservations.append(reservation.uuid) # Also update the reserved quantity # NOTE(Vek): Again, we are only concerned here about # positive increments. Here, though, we're # worried about the following scenario: # # 1) User initiates resize down. # 2) User allocates a new instance. # 3) Resize down fails or is reverted. # 4) User is now over quota. # # To prevent this, we only update the # reserved value if the delta is positive. if delta > 0: usages[resource].reserved += delta # Apply updates to the usages table for usage_ref in usages.values(): usage_ref.save(session=session) if unders: LOG.warning( _("Change will make usage less than 0 for the following " "resources: %(unders)s") % locals()) if overs: usages = dict((k, dict(in_use=v['in_use'], reserved=v['reserved'])) for k, v in usages.items()) raise exception.OverQuota(overs=sorted(overs), quotas=quotas, usages=usages) return reservations
def service_destroy(context, service_id): session = get_session() with session.begin(): service_ref = service_get(context, service_id, session=session) service_ref.delete(session=session)
def quota_update(context, project_id, resource, limit): session = get_session() with session.begin(): quota_ref = quota_get(context, project_id, resource, session=session) quota_ref.hard_limit = limit quota_ref.save(session=session)
def service_update(context, service_id, values): session = get_session() with session.begin(): service_ref = service_get(context, service_id, session=session) service_ref.update(values) service_ref.save(session=session)
def quota_destroy(context, project_id, resource): session = get_session() with session.begin(): quota_ref = quota_get(context, project_id, resource, session=session) quota_ref.delete(session=session)
def quota_reserve(context, resources, quotas, deltas, expire, until_refresh, max_age, project_id=None): elevated = context.elevated() session = get_session() with session.begin(): if project_id is None: project_id = context.project_id # Get the current usages usages = _get_quota_usages(context, session, project_id) # Handle usage refresh work = set(deltas.keys()) while work: resource = work.pop() # Do we need to refresh the usage? refresh = False if resource not in usages: usages[resource] = quota_usage_create(elevated, project_id, resource, 0, 0, until_refresh or None, session=session) refresh = True elif usages[resource].in_use < 0: # Negative in_use count indicates a desync, so try to # heal from that... refresh = True elif usages[resource].until_refresh is not None: usages[resource].until_refresh -= 1 if usages[resource].until_refresh <= 0: refresh = True elif max_age and (usages[resource].updated_at - timeutils.utcnow()).seconds >= max_age: refresh = True # OK, refresh the usage if refresh: # Grab the sync routine sync = resources[resource].sync updates = sync(elevated, project_id, session) for res, in_use in updates.items(): # Make sure we have a destination for the usage! if res not in usages: usages[res] = quota_usage_create(elevated, project_id, res, 0, 0, until_refresh or None, session=session) # Update the usage usages[res].in_use = in_use usages[res].until_refresh = until_refresh or None # Because more than one resource may be refreshed # by the call to the sync routine, and we don't # want to double-sync, we make sure all refreshed # resources are dropped from the work set. work.discard(res) # NOTE(Vek): We make the assumption that the sync # routine actually refreshes the # resources that it is the sync routine # for. We don't check, because this is # a best-effort mechanism. # Check for deltas that would go negative unders = [resource for resource, delta in deltas.items() if delta < 0 and delta + usages[resource].in_use < 0] # Now, let's check the quotas # NOTE(Vek): We're only concerned about positive increments. # If a project has gone over quota, we want them to # be able to reduce their usage without any # problems. overs = [resource for resource, delta in deltas.items() if quotas[resource] >= 0 and delta >= 0 and quotas[resource] < delta + usages[resource].total] # NOTE(Vek): The quota check needs to be in the transaction, # but the transaction doesn't fail just because # we're over quota, so the OverQuota raise is # outside the transaction. If we did the raise # here, our usage updates would be discarded, but # they're not invalidated by being over-quota. # Create the reservations if not overs: reservations = [] for resource, delta in deltas.items(): reservation = reservation_create(elevated, str(uuid.uuid4()), usages[resource], project_id, resource, delta, expire, session=session) reservations.append(reservation.uuid) # Also update the reserved quantity # NOTE(Vek): Again, we are only concerned here about # positive increments. Here, though, we're # worried about the following scenario: # # 1) User initiates resize down. # 2) User allocates a new instance. # 3) Resize down fails or is reverted. # 4) User is now over quota. # # To prevent this, we only update the # reserved value if the delta is positive. if delta > 0: usages[resource].reserved += delta # Apply updates to the usages table for usage_ref in usages.values(): usage_ref.save(session=session) if unders: LOG.warning(_("Change will make usage less than 0 for the following " "resources: %(unders)s") % locals()) if overs: usages = dict((k, dict(in_use=v['in_use'], reserved=v['reserved'])) for k, v in usages.items()) raise exception.OverQuota(overs=sorted(overs), quotas=quotas, usages=usages) return reservations