Example #1
0
 def test_cg_create_source_cgsnapshot_not_in_available(self):
     fake_snap_id = six.text_type(uuid.uuid4())
     body = {"consistency_group": {"source_cgsnapshot_id": fake_snap_id}}
     self.mock_object(
         self.controller.cg_api, 'create',
         mock.Mock(side_effect=exception.InvalidCGSnapshot(reason='blah')))
     self.assertRaises(webob.exc.HTTPConflict, self.controller.create,
                       self.request, body)
Example #2
0
    def test_delete_in_conflicting_status(self):
        fake_snap, expected_snap = self._get_fake_cgsnapshot()
        self.mock_object(self.controller.cg_api, 'get_cgsnapshot',
                         mock.Mock(return_value=fake_snap))
        self.mock_object(
            self.controller.cg_api, 'delete_cgsnapshot',
            mock.Mock(side_effect=exception.InvalidCGSnapshot(reason='blah')))

        self.assertRaises(webob.exc.HTTPConflict, self.controller.delete,
                          self.request, fake_snap['id'])
Example #3
0
    def test_cg_create_invalid_cgsnapshot_state(self):
        fake_snap_id = six.text_type(uuid.uuid4())
        self.mock_object(self.controller.cg_api, 'create',
                         mock.Mock(side_effect=exception.InvalidCGSnapshot(
                             reason='bad status'
                         )))

        body = {"consistency_group": {"source_cgsnapshot_id": fake_snap_id}}
        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 delete_cgsnapshot(self, context, snap):
        """Delete consistency group snapshot."""

        snap_id = snap['id']

        cg = self.db.consistency_group_get(context,
                                           snap['consistency_group_id'])

        statuses = (constants.STATUS_AVAILABLE, constants.STATUS_ERROR)
        if not snap['status'] in statuses:
            msg = (_("Consistency group snapshot status must be one of"
                     " %(statuses)s") % {
                         "statuses": statuses
                     })
            raise exception.InvalidCGSnapshot(reason=msg)

        self.db.cgsnapshot_update(context, snap_id,
                                  {'status': constants.STATUS_DELETING})

        # Cast to share manager
        self.share_rpcapi.delete_cgsnapshot(context, snap, cg['host'])
Example #5
0
    def create(self,
               context,
               name=None,
               description=None,
               share_type_ids=None,
               source_cgsnapshot_id=None,
               share_network_id=None):
        """Create new consistency group."""

        cgsnapshot = None
        original_cg = None
        # NOTE(gouthamr): share_server_id is inherited from the parent CG if a
        # CG snapshot is specified, else, it will be set in the share manager.
        share_server_id = None
        if source_cgsnapshot_id:
            cgsnapshot = self.db.cgsnapshot_get(context, source_cgsnapshot_id)
            if cgsnapshot['status'] != constants.STATUS_AVAILABLE:
                msg = (_("Consistency group snapshot status must be %s") %
                       constants.STATUS_AVAILABLE)
                raise exception.InvalidCGSnapshot(reason=msg)

            original_cg = self.db.consistency_group_get(
                context, cgsnapshot['consistency_group_id'])
            share_type_ids = [
                s['share_type_id'] for s in original_cg['share_types']
            ]
            share_network_id = original_cg['share_network_id']
            share_server_id = original_cg['share_server_id']

        # Get share_type_objects
        share_type_objects = []
        driver_handles_share_servers = None
        for share_type_id in (share_type_ids or []):
            try:
                share_type_object = share_types.get_share_type(
                    context, share_type_id)
            except exception.ShareTypeNotFound:
                msg = _("Share type with id %s could not be found")
                raise exception.InvalidInput(msg % share_type_id)
            share_type_objects.append(share_type_object)

            extra_specs = share_type_object.get('extra_specs')
            if extra_specs:
                share_type_handle_ss = strutils.bool_from_string(
                    extra_specs.get(
                        constants.ExtraSpecs.DRIVER_HANDLES_SHARE_SERVERS))
                if driver_handles_share_servers is None:
                    driver_handles_share_servers = share_type_handle_ss
                elif not driver_handles_share_servers == share_type_handle_ss:
                    # NOTE(ameade): if the share types have conflicting values
                    #  for driver_handles_share_servers then raise bad request
                    msg = _("The specified share_types cannot have "
                            "conflicting values for the "
                            "driver_handles_share_servers extra spec.")
                    raise exception.InvalidInput(reason=msg)

                if (not share_type_handle_ss) and share_network_id:
                    msg = _("When using a share types with the "
                            "driver_handles_share_servers extra spec as "
                            "False, a share_network_id must not be provided.")
                    raise exception.InvalidInput(reason=msg)

        try:
            if share_network_id:
                self.db.share_network_get(context, share_network_id)
        except exception.ShareNetworkNotFound:
            msg = _("The specified share network does not exist.")
            raise exception.InvalidInput(reason=msg)

        if (driver_handles_share_servers
                and not (source_cgsnapshot_id or share_network_id)):
            msg = _("When using a share type with the "
                    "driver_handles_share_servers extra spec as "
                    "True, a share_network_id must be provided.")
            raise exception.InvalidInput(reason=msg)

        options = {
            'source_cgsnapshot_id': source_cgsnapshot_id,
            'share_network_id': share_network_id,
            'share_server_id': share_server_id,
            'name': name,
            'description': description,
            'user_id': context.user_id,
            'project_id': context.project_id,
            'status': constants.STATUS_CREATING,
            'share_types': share_type_ids
        }
        if original_cg:
            options['host'] = original_cg['host']

        cg = self.db.consistency_group_create(context, options)

        try:
            if cgsnapshot:
                members = self.db.cgsnapshot_members_get_all(
                    context, source_cgsnapshot_id)
                for member in members:
                    share_type = share_types.get_share_type(
                        context, member['share_type_id'])
                    member['share_instance'] = self.db.share_instance_get(
                        context,
                        member['share_instance_id'],
                        with_share_data=True)
                    self.share_api.create(context,
                                          member['share_proto'],
                                          member['size'],
                                          None,
                                          None,
                                          consistency_group_id=cg['id'],
                                          cgsnapshot_member=member,
                                          share_type=share_type,
                                          share_network_id=share_network_id)
        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.consistency_group_destroy(context.elevated(), cg['id'])

        request_spec = {'consistency_group_id': cg['id']}
        request_spec.update(options)
        request_spec['share_types'] = share_type_objects

        if cgsnapshot and original_cg:
            self.share_rpcapi.create_consistency_group(context, cg,
                                                       original_cg['host'])
        else:
            self.scheduler_rpcapi.create_consistency_group(
                context,
                cg_id=cg['id'],
                request_spec=request_spec,
                filter_properties={})

        return cg