def create_volume(self, volume): LOG.debug('create_volume, volume %s.', volume['id']) volume_name = VOLUME_PREFIX + volume['id'][-12:] pool_name = volume_utils.extract_host(volume['host'], 'pool') ret = self._cmd.create_volume( volume_name, str(volume['size']), pool_name) if ret['key'] == 310: msg = _('Volume: %s with same name ' 'already exists on the system.') % volume_name raise exception.VolumeBackendAPIException(data=msg) elif ret['key'] == 102: allow_size = 0 for p in self._stats['pools']: if p['pool_name'] == pool_name: allow_size = p['free_capacity_gb'] break raise exception.VolumeSizeExceedsLimit(size=int(volume['size']), limit=allow_size) elif ret['key'] == 307: raise exception.VolumeLimitExceeded(allowed=96, name=volume_name) elif ret['key'] == 308: raise exception.VolumeLimitExceeded(allowed=4096, name=volume_name) model_update = None return model_update
def execute(self, context, size, volume_type_id, group_snapshot, optional_args): try: values = {'per_volume_gigabytes': size} QUOTAS.limit_check(context, project_id=context.project_id, **values) except exception.OverQuota as e: quotas = e.kwargs['quotas'] raise exception.VolumeSizeExceedsLimit( size=size, limit=quotas['per_volume_gigabytes']) try: if group_snapshot: reserve_opts = {'volumes': 1} else: reserve_opts = {'volumes': 1, 'gigabytes': size} if ('update_size' in optional_args and optional_args['update_size']): reserve_opts.pop('volumes', None) QUOTAS.add_volume_type_opts(context, reserve_opts, volume_type_id) reservations = QUOTAS.reserve(context, **reserve_opts) return { 'reservations': reservations, } except exception.OverQuota as e: quota_utils.process_reserve_over_quota(context, e, resource='volumes', size=size)
def execute(self, context, size, volume_type_id, optional_args): try: values = {'per_volume_gigabytes': size} QUOTAS.limit_check(context, project_id=context.project_id, **values) except exception.OverQuota as e: quotas = e.kwargs['quotas'] raise exception.VolumeSizeExceedsLimit( size=size, limit=quotas['per_volume_gigabytes']) try: reserve_opts = {'volumes': 1, 'gigabytes': size} QUOTAS.add_volume_type_opts(context, reserve_opts, volume_type_id) reservations = QUOTAS.reserve(context, **reserve_opts) return { 'reservations': reservations, } except exception.OverQuota as e: overs = e.kwargs['overs'] quotas = e.kwargs['quotas'] usages = e.kwargs['usages'] def _consumed(name): return usages[name]['reserved'] + usages[name]['in_use'] def _is_over(name): for over in overs: if name in over: return True return False if _is_over('gigabytes'): msg = _LW("Quota exceeded for %(s_pid)s, tried to create " "%(s_size)sG volume (%(d_consumed)dG " "of %(d_quota)dG already consumed)") LOG.warning( msg, { 's_pid': context.project_id, 's_size': size, 'd_consumed': _consumed('gigabytes'), 'd_quota': quotas['gigabytes'] }) raise exception.VolumeSizeExceedsAvailableQuota( requested=size, consumed=_consumed('gigabytes'), quota=quotas['gigabytes']) elif _is_over('volumes'): msg = _LW("Quota exceeded for %(s_pid)s, tried to create " "volume (%(d_consumed)d volumes " "already consumed)") LOG.warning( msg, { 's_pid': context.project_id, 'd_consumed': _consumed('volumes') }) raise exception.VolumeLimitExceeded(allowed=quotas['volumes']) else: # If nothing was reraised, ensure we reraise the initial error raise
def extend_volume(self, volume, new_size): volume_name = self._convert_name(volume.name) ret = self._cmd.extend_volume(volume_name, int(new_size)) if ret['key'] == 303: raise exception.VolumeNotFound(volume_id=volume_name) elif ret['key'] == 321: msg = _('Volume capacity shall not be ' 'less than the current size %sG.') % volume['size'] raise exception.VolumeBackendAPIException(data=msg) elif ret['key'] == 102: pool_name = volume_utils.extract_host(volume['host'], 'pool') allow_size = 0 for p in self._stats['pools']: if p['pool_name'] == pool_name: allow_size = p['free_capacity_gb'] break raise exception.VolumeSizeExceedsLimit(size=int(new_size), limit=allow_size) elif ret['key'] != 0: msg = (_('Failed to extend_volume %(vol)s to size %(size)s, ' 'code=%(ret)s, error=%(msg)s.') % { 'vol': volume_name, 'size': new_size, 'ret': ret['key'], 'msg': ret['msg'] }) raise exception.VolumeBackendAPIException(data=msg)
def create_volume(self, volume): LOG.debug('create_volume, volume %s.', volume['id']) volume_name = self._convert_name(volume.name) pool_name = volume_utils.extract_host(volume['host'], 'pool') ret = self._cmd.create_volume(volume_name, str(volume['size']), pool_name) if ret['key'] == 310: msg = _('Volume: %s with same name ' 'already exists on the system.') % volume_name raise exception.VolumeBackendAPIException(data=msg) elif ret['key'] == 102: allow_size = 0 for p in self._stats['pools']: if p['pool_name'] == pool_name: allow_size = p['free_capacity_gb'] break raise exception.VolumeSizeExceedsLimit(size=int(volume['size']), limit=allow_size) elif ret['key'] == 307: raise exception.VolumeLimitExceeded(allowed=96, name=volume_name) elif ret['key'] == 308: raise exception.VolumeLimitExceeded(allowed=4096, name=volume_name) elif ret['key'] != 0: msg = (_('Failed to create_volume %(vol)s on pool %(pool)s, ' 'code=%(ret)s, error=%(msg)s.') % { 'vol': volume_name, 'pool': pool_name, 'ret': ret['key'], 'msg': ret['msg'] }) raise exception.VolumeBackendAPIException(data=msg) return None
def extend_volume(self, volume, new_size): volume_name = VOLUME_PREFIX + volume['id'][-12:] ret = self._cmd.extend_volume(volume_name, int(new_size)) if ret['key'] == 303: raise exception.VolumeNotFound(volume_id=volume_name) elif ret['key'] == 321: msg = _('Volume capacity shall not be ' 'less than the current size %sG.') % volume['size'] raise exception.VolumeBackendAPIException(data=msg) elif ret['key'] == 102: pool_name = volume_utils.extract_host(volume['host'], 'pool') allow_size = 0 for p in self._stats['pools']: if p['pool_name'] == pool_name: allow_size = p['free_capacity_gb'] break raise exception.VolumeSizeExceedsLimit(size=int(new_size), limit=allow_size)
def execute(self, context, size, volume_type_id, optional_args): try: values = {'per_volume_gigabytes': size} QUOTAS.limit_check(context, project_id=context.project_id, **values) except exception.OverQuota as e: quotas = e.kwargs['quotas'] raise exception.VolumeSizeExceedsLimit( size=size, limit=quotas['per_volume_gigabytes']) try: reserve_opts = {'volumes': 1, 'gigabytes': size} QUOTAS.add_volume_type_opts(context, reserve_opts, volume_type_id) reservations = QUOTAS.reserve(context, **reserve_opts) return { 'reservations': reservations, } except exception.OverQuota as e: overs = e.kwargs['overs'] quotas = e.kwargs['quotas'] usages = e.kwargs['usages'] def _consumed(name): usage = usages[name] return usage['reserved'] + usage['in_use'] + usage.get( 'allocated', 0) def _get_over(name): for over in overs: if name in over: return over return None over_name = _get_over('gigabytes') exceeded_vol_limit_name = _get_over('volumes') if over_name: # TODO(mc_nair): improve error message for child -1 limit msg = _LW("Quota exceeded for %(s_pid)s, tried to create " "%(s_size)sG volume (%(d_consumed)dG " "of %(d_quota)dG already consumed)") LOG.warning( msg, { 's_pid': context.project_id, 's_size': size, 'd_consumed': _consumed(over_name), 'd_quota': quotas[over_name] }) raise exception.VolumeSizeExceedsAvailableQuota( name=over_name, requested=size, consumed=_consumed(over_name), quota=quotas[over_name]) elif exceeded_vol_limit_name: msg = _LW("Quota %(s_name)s exceeded for %(s_pid)s, tried " "to create volume (%(d_consumed)d volume(s) " "already consumed).") LOG.warning( msg, { 's_name': exceeded_vol_limit_name, 's_pid': context.project_id, 'd_consumed': _consumed(exceeded_vol_limit_name) }) # TODO(mc_nair): improve error message for child -1 limit raise exception.VolumeLimitExceeded( allowed=quotas[exceeded_vol_limit_name], name=exceeded_vol_limit_name) else: # If nothing was reraised, ensure we reraise the initial error raise
def accept(self, context, transfer_id, auth_key): """Accept a volume that has been offered for transfer.""" # We must use an elevated context to see the volume that is still # owned by the donor. context.authorize(policy.ACCEPT_POLICY) transfer = self.db.transfer_get(context.elevated(), transfer_id) crypt_hash = self._get_crypt_hash(transfer['salt'], auth_key) if crypt_hash != transfer['crypt_hash']: msg = (_("Attempt to transfer %s with invalid auth key.") % transfer_id) LOG.error(msg) raise exception.InvalidAuthKey(reason=msg) volume_id = transfer['volume_id'] vol_ref = objects.Volume.get_by_id(context.elevated(), volume_id) if vol_ref['consistencygroup_id']: msg = _("Volume %s must not be part of a consistency " "group.") % vol_ref['id'] LOG.error(msg) raise exception.InvalidVolume(reason=msg) try: values = {'per_volume_gigabytes': vol_ref.size} QUOTAS.limit_check(context, project_id=context.project_id, **values) except exception.OverQuota as e: quotas = e.kwargs['quotas'] raise exception.VolumeSizeExceedsLimit( size=vol_ref.size, limit=quotas['per_volume_gigabytes']) try: reserve_opts = {'volumes': 1, 'gigabytes': vol_ref.size} QUOTAS.add_volume_type_opts(context, reserve_opts, vol_ref.volume_type_id) reservations = QUOTAS.reserve(context, **reserve_opts) except exception.OverQuota as e: quota_utils.process_reserve_over_quota(context, e, resource='volumes', size=vol_ref.size) try: donor_id = vol_ref['project_id'] reserve_opts = {'volumes': -1, 'gigabytes': -vol_ref.size} QUOTAS.add_volume_type_opts(context, reserve_opts, vol_ref.volume_type_id) donor_reservations = QUOTAS.reserve(context.elevated(), project_id=donor_id, **reserve_opts) except Exception: donor_reservations = None LOG.exception( "Failed to update quota donating volume" " transfer id %s", transfer_id) snap_res = None snap_donor_res = None if transfer['no_snapshots'] is False: snapshots = objects.SnapshotList.get_all_for_volume( context.elevated(), volume_id) volume_type_id = vol_ref.volume_type_id snap_res, snap_donor_res = self._handle_snapshot_quota( context, snapshots, volume_type_id, vol_ref['project_id']) volume_utils.notify_about_volume_usage(context, vol_ref, "transfer.accept.start") try: # Transfer ownership of the volume now, must use an elevated # context. self.volume_api.accept_transfer(context, vol_ref, context.user_id, context.project_id, transfer['no_snapshots']) self.db.transfer_accept(context.elevated(), transfer_id, context.user_id, context.project_id, transfer['no_snapshots']) QUOTAS.commit(context, reservations) if snap_res: QUOTAS.commit(context, snap_res) if donor_reservations: QUOTAS.commit(context, donor_reservations, project_id=donor_id) if snap_donor_res: QUOTAS.commit(context, snap_donor_res, project_id=donor_id) LOG.info("Volume %s has been transferred.", volume_id) except Exception: with excutils.save_and_reraise_exception(): QUOTAS.rollback(context, reservations) if snap_res: QUOTAS.rollback(context, snap_res) if donor_reservations: QUOTAS.rollback(context, donor_reservations, project_id=donor_id) if snap_donor_res: QUOTAS.rollback(context, snap_donor_res, project_id=donor_id) vol_ref = objects.Volume.get_by_id(context.elevated(), volume_id) volume_utils.notify_about_volume_usage(context, vol_ref, "transfer.accept.end") return { 'id': transfer_id, 'display_name': transfer['display_name'], 'volume_id': vol_ref['id'] }