def delete(self, context, share_group): """Delete share group.""" share_group_id = share_group['id'] if not share_group['host']: self.db.share_group_destroy(context.elevated(), share_group_id) return statuses = (constants.STATUS_AVAILABLE, constants.STATUS_ERROR) if not share_group['status'] in statuses: msg = (_("Share group status must be one of %(statuses)s") % { "statuses": statuses }) raise exception.InvalidShareGroup(reason=msg) # NOTE(ameade): check for group_snapshots in the group if self.db.count_share_group_snapshots_in_share_group( context, share_group_id): msg = (_("Cannot delete a share group with snapshots")) raise exception.InvalidShareGroup(reason=msg) # NOTE(ameade): check for shares in the share group if self.db.count_shares_in_share_group(context, share_group_id): msg = (_("Cannot delete a share group with shares")) raise exception.InvalidShareGroup(reason=msg) share_group = self.db.share_group_update( context, share_group_id, {'status': constants.STATUS_DELETING}) self.share_rpcapi.delete_share_group(context, share_group)
def delete(self, context, share_group): """Delete share group.""" share_group_id = share_group['id'] if not share_group['host']: self.db.share_group_destroy(context.elevated(), share_group_id) return statuses = (constants.STATUS_AVAILABLE, constants.STATUS_ERROR) if not share_group['status'] in statuses: msg = (_("Share group status must be one of %(statuses)s") % { "statuses": statuses }) raise exception.InvalidShareGroup(reason=msg) # NOTE(ameade): check for group_snapshots in the group if self.db.count_share_group_snapshots_in_share_group( context, share_group_id): msg = (_("Cannot delete a share group with snapshots")) raise exception.InvalidShareGroup(reason=msg) # NOTE(ameade): check for shares in the share group if self.db.count_shares_in_share_group(context, share_group_id): msg = (_("Cannot delete a share group with shares")) raise exception.InvalidShareGroup(reason=msg) share_group = self.db.share_group_update( context, share_group_id, {'status': constants.STATUS_DELETING}) try: reservations = QUOTAS.reserve( context, share_groups=-1, project_id=share_group['project_id'], user_id=share_group['user_id'], ) except exception.OverQuota as e: reservations = None LOG.exception( ("Failed to update quota for deleting share group: %s"), e) try: self.share_rpcapi.delete_share_group(context, share_group) except Exception: with excutils.save_and_reraise_exception(): QUOTAS.rollback(context, reservations) if reservations: QUOTAS.commit( context, reservations, project_id=share_group['project_id'], user_id=share_group['user_id'], )
def test_create_invalid_share_group(self): fake_id = six.text_type(uuidutils.generate_uuid()) body = {"share_group_snapshot": {"share_group_id": fake_id}} self.mock_object( self.controller.share_group_api, 'create_share_group_snapshot', mock.Mock(side_effect=exception.InvalidShareGroup( reason='bad_status'))) self.assertRaises( webob.exc.HTTPConflict, self.controller.create, self.request, body) self.mock_policy_check.assert_called_once_with( self.context, self.resource_name, 'create')
def test_share_group_delete_in_conflicting_status(self): fake, expected = self._get_fake_share_group() self.mock_object( share_group_api.API, 'get', mock.Mock(return_value=fake)) self.mock_object(share_group_api.API, 'delete', mock.Mock( side_effect=exception.InvalidShareGroup(reason='blah'))) self.assertRaises( webob.exc.HTTPConflict, self.controller.delete, self.request, fake['id']) self.mock_policy_check.assert_called_once_with( self.context, self.resource_name, 'delete')
def create_share_group_snapshot(self, context, name=None, description=None, share_group_id=None): """Create new share group snapshot.""" options = { 'share_group_id': share_group_id, 'name': name, 'description': description, 'user_id': context.user_id, 'project_id': context.project_id, 'status': constants.STATUS_CREATING, } share_group = self.db.share_group_get(context, share_group_id) # Check status of group, must be active if not share_group['status'] == constants.STATUS_AVAILABLE: msg = (_("Share group status must be %s") % constants.STATUS_AVAILABLE) raise exception.InvalidShareGroup(reason=msg) # Create members for every share in the group shares = self.db.share_get_all_by_share_group_id( context, share_group_id) # Check status of all shares, they must be active in order to snap # the group for s in shares: if not s['status'] == constants.STATUS_AVAILABLE: msg = (_("Share %(s)s in share group must have status " "of %(status)s in order to create a group snapshot") % { "s": s['id'], "status": constants.STATUS_AVAILABLE }) raise exception.InvalidShareGroup(reason=msg) try: reservations = QUOTAS.reserve(context, share_group_snapshots=1) except exception.OverQuota as e: overs = e.kwargs['overs'] usages = e.kwargs['usages'] quotas = e.kwargs['quotas'] def _consumed(name): return (usages[name]['reserved'] + usages[name]['in_use']) if 'share_group_snapshots' in overs: msg = ("Quota exceeded for '%(s_uid)s' user in '%(s_pid)s' " "project. (%(d_consumed)d of " "%(d_quota)d already consumed).") LOG.warning( msg, { 's_pid': context.project_id, 's_uid': context.user_id, 'd_consumed': _consumed('share_group_snapshots'), 'd_quota': quotas['share_group_snapshots'], }) raise exception.ShareGroupSnapshotsLimitExceeded() snap = {} try: snap = self.db.share_group_snapshot_create(context, options) members = [] for s in shares: member_options = { 'share_group_snapshot_id': snap['id'], 'user_id': context.user_id, 'project_id': context.project_id, 'status': constants.STATUS_CREATING, 'size': s['size'], 'share_proto': s['share_proto'], 'share_instance_id': s.instance['id'] } member = self.db.share_group_snapshot_member_create( context, member_options) members.append(member) # Cast to share manager self.share_rpcapi.create_share_group_snapshot( context, snap, share_group['host']) except Exception: with excutils.save_and_reraise_exception(): # This will delete the snapshot and all of it's members if snap: self.db.share_group_snapshot_destroy(context, snap['id']) QUOTAS.rollback(context, reservations) try: QUOTAS.commit(context, reservations) except Exception: with excutils.save_and_reraise_exception(): QUOTAS.rollback(context, reservations) return snap
def create_share_group_snapshot(self, context, name=None, description=None, share_group_id=None): """Create new share group snapshot.""" options = { 'share_group_id': share_group_id, 'name': name, 'description': description, 'user_id': context.user_id, 'project_id': context.project_id, 'status': constants.STATUS_CREATING, } share_group = self.db.share_group_get(context, share_group_id) # Check status of group, must be active if not share_group['status'] == constants.STATUS_AVAILABLE: msg = (_("Share group status must be %s") % constants.STATUS_AVAILABLE) raise exception.InvalidShareGroup(reason=msg) # Create members for every share in the group shares = self.db.share_get_all_by_share_group_id( context, share_group_id) # Check status of all shares, they must be active in order to snap # the group for s in shares: if not s['status'] == constants.STATUS_AVAILABLE: msg = (_("Share %(s)s in share group must have status " "of %(status)s in order to create a group snapshot") % { "s": s['id'], "status": constants.STATUS_AVAILABLE }) raise exception.InvalidShareGroup(reason=msg) snap = self.db.share_group_snapshot_create(context, options) try: members = [] for s in shares: member_options = { 'share_group_snapshot_id': snap['id'], 'user_id': context.user_id, 'project_id': context.project_id, 'status': constants.STATUS_CREATING, 'size': s['size'], 'share_proto': s['share_proto'], 'share_id': s['id'], 'share_instance_id': s.instance['id'] } member = self.db.share_group_snapshot_member_create( context, member_options) members.append(member) # Cast to share manager self.share_rpcapi.create_share_group_snapshot( context, snap, share_group['host']) except Exception: with excutils.save_and_reraise_exception(): # This will delete the snapshot and all of it's members self.db.share_group_snapshot_destroy(context, snap['id']) return snap