Example #1
0
    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)
Example #2
0
    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')
Example #4
0
    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')
Example #5
0
    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
Example #6
0
    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