示例#1
0
    def test_as_int(self):
        test_obj_int = '2'
        test_obj_float = '2.2'
        for obj in [test_obj_int, test_obj_float]:
            self.assertEqual(2, utils.as_int(obj))

        obj = 'not_a_number'
        self.assertEqual(obj, utils.as_int(obj))
        self.assertRaises(TypeError,
                          utils.as_int,
                          obj,
                          quiet=False)
示例#2
0
    def _check_image_metadata(self, context, image_id, size):
        """Checks image existence and validates that the image metadata."""

        # Check image existence
        if image_id is None:
            return

        # NOTE(harlowja): this should raise an error if the image does not
        # exist, this is expected as it signals that the image_id is missing.
        image_meta = self.image_service.show(context, image_id)

        # check whether image is active
        if image_meta['status'] != 'active':
            msg = _('Image %(image_id)s is not active.')\
                % {'image_id': image_id}
            raise exception.InvalidInput(reason=msg)

        # Check image size is not larger than volume size.
        image_size = utils.as_int(image_meta['size'], quiet=False)
        image_size_in_gb = (image_size + GB - 1) // GB
        if image_size_in_gb > size:
            msg = _('Size of specified image %(image_size)sGB'
                    ' is larger than volume size %(volume_size)sGB.')
            msg = msg % {'image_size': image_size_in_gb, 'volume_size': size}
            raise exception.InvalidInput(reason=msg)

        # Check image min_disk requirement is met for the particular volume
        min_disk = image_meta.get('min_disk', 0)
        if size < min_disk:
            msg = _('Volume size %(volume_size)sGB cannot be smaller'
                    ' than the image minDisk size %(min_disk)sGB.')
            msg = msg % {'volume_size': size, 'min_disk': min_disk}
            raise exception.InvalidInput(reason=msg)
示例#3
0
 def _populate_request_spec(self, context, volume_id, snapshot_id,
                            image_id):
     # Create the full request spec using the volume_id.
     #
     # NOTE(harlowja): this will fetch the volume from the database, if
     # the volume has been deleted before we got here then this should fail.
     #
     # In the future we might want to have a lock on the volume_id so that
     # the volume can not be deleted while its still being created?
     if not volume_id:
         msg = _("No volume_id provided to populate a request_spec from")
         raise exception.InvalidInput(reason=msg)
     volume_ref = self.db_api.volume_get(context, volume_id)
     volume_type_id = volume_ref.get('volume_type_id')
     vol_type = self.db_api.volume_type_get(context, volume_type_id)
     return {
         'volume_id': volume_id,
         'snapshot_id': snapshot_id,
         'image_id': image_id,
         'volume_properties': {
             'size': utils.as_int(volume_ref.get('size'), quiet=False),
             'availability_zone': volume_ref.get('availability_zone'),
             'volume_type_id': volume_type_id,
         },
         'volume_type': list(dict(vol_type).iteritems()),
     }
示例#4
0
    def _check_image_metadata(self, context, image_id, size):
        """Checks image existence and validates that the image metadata."""

        # Check image existence
        if image_id is None:
            return

        # NOTE(harlowja): this should raise an error if the image does not
        # exist, this is expected as it signals that the image_id is missing.
        image_meta = self.image_service.show(context, image_id)

        # Check image size is not larger than volume size.
        image_size = utils.as_int(image_meta["size"], quiet=False)
        image_size_in_gb = (image_size + GB - 1) / GB
        if image_size_in_gb > size:
            msg = _("Size of specified image %(image_size)sGB" " is larger than volume size %(volume_size)sGB.")
            msg = msg % {"image_size": image_size_in_gb, "volume_size": size}
            raise exception.InvalidInput(reason=msg)

        # Check image min_disk requirement is met for the particular volume
        min_disk = image_meta.get("min_disk", 0)
        if size < min_disk:
            msg = _("Volume size %(volume_size)sGB cannot be smaller" " than the image minDisk size %(min_disk)sGB.")
            msg = msg % {"volume_size": size, "min_disk": min_disk}
            raise exception.InvalidInput(reason=msg)
示例#5
0
    def _extract_size(size, source_volume, snapshot):
        """Extracts and validates the volume size.

        This function will validate or when not provided fill in the provided
        size variable from the source_volume or snapshot and then does
        validation on the size that is found and returns said validated size.
        """

        def validate_snap_size(size):
            if snapshot and size < snapshot.volume_size:
                msg = _(
                    "Volume size '%(size)s'GB cannot be smaller than"
                    " the snapshot size %(snap_size)sGB. "
                    "They must be >= original snapshot size."
                )
                msg = msg % {"size": size, "snap_size": snapshot.volume_size}
                raise exception.InvalidInput(reason=msg)

        def validate_source_size(size):
            if source_volume and size < source_volume["size"]:
                msg = _(
                    "Volume size '%(size)s'GB cannot be smaller than "
                    "original volume size  %(source_size)sGB. "
                    "They must be >= original volume size."
                )
                msg = msg % {"size": size, "source_size": source_volume["size"]}
                raise exception.InvalidInput(reason=msg)

        def validate_int(size):
            if not isinstance(size, int) or size <= 0:
                msg = _("Volume size '%(size)s' must be an integer and" " greater than 0") % {"size": size}
                raise exception.InvalidInput(reason=msg)

        # Figure out which validation functions we should be applying
        # on the size value that we extract.
        validator_functors = [validate_int]
        if source_volume:
            validator_functors.append(validate_source_size)
        elif snapshot:
            validator_functors.append(validate_snap_size)

        # If the size is not provided then try to provide it.
        if not size and source_volume:
            size = source_volume["size"]
        elif not size and snapshot:
            size = snapshot.volume_size

        size = utils.as_int(size)
        LOG.debug(
            "Validating volume '%(size)s' using %(functors)s"
            % {"size": size, "functors": ", ".join([common.make_pretty_name(func) for func in validator_functors])}
        )
        for func in validator_functors:
            func(size)
        return size
示例#6
0
 def _populate_request_spec(self, volume, snapshot_id, image_id):
     # Create the full request spec using the volume object.
     #
     # NOTE(dulek): At this point, a volume can be deleted before it gets
     # scheduled.  If a delete API call is made, the volume gets instantly
     # delete and scheduling will fail when it tries to update the DB entry
     # (with the host) in ScheduleCreateVolumeTask below.
     volume_type_id = volume.volume_type_id
     vol_type = volume.volume_type
     return {
         'volume_id': volume.id,
         'snapshot_id': snapshot_id,
         'image_id': image_id,
         'volume_properties': {
             'size': utils.as_int(volume.size, quiet=False),
             'availability_zone': volume.availability_zone,
             'volume_type_id': volume_type_id,
         },
         'volume_type': list(dict(vol_type).items()),
     }
 def _populate_request_spec(self, context, volume_id, snapshot_id, image_id):
     # Create the full request spec using the volume_id.
     #
     # NOTE(harlowja): this will fetch the volume from the database, if
     # the volume has been deleted before we got here then this should fail.
     #
     # In the future we might want to have a lock on the volume_id so that
     # the volume can not be deleted while its still being created?
     if not volume_id:
         raise exception.InvalidInput(reason=_("No volume_id provided to populate a " "request_spec from"))
     volume_ref = objects.Volume.get_by_id(context, volume_id)
     volume_type_id = volume_ref.volume_type_id
     vol_type = volume_ref.volume_type
     return {
         "volume_id": volume_id,
         "snapshot_id": snapshot_id,
         "image_id": image_id,
         "volume_properties": {
             "size": utils.as_int(volume_ref.size, quiet=False),
             "availability_zone": volume_ref.availability_zone,
             "volume_type_id": volume_type_id,
         },
         "volume_type": list(dict(vol_type).items()),
     }
示例#8
0
文件: utils.py 项目: mahak/cinder
def check_image_metadata(image_meta, vol_size):
    """Validates the image metadata."""
    # Check whether image is active
    if image_meta['status'] != 'active':
        msg = _('Image %(image_id)s is not active.'
                ) % {'image_id': image_meta['id']}
        raise exception.InvalidInput(reason=msg)

    # Check image size is not larger than volume size.
    image_size = utils.as_int(image_meta['size'], quiet=False)
    image_size_in_gb = (image_size + GB - 1) // GB
    if image_size_in_gb > vol_size:
        msg = _('Size of specified image %(image_size)sGB'
                ' is larger than volume size %(volume_size)sGB.')
        msg = msg % {'image_size': image_size_in_gb, 'volume_size': vol_size}
        raise exception.InvalidInput(reason=msg)

    # Check image min_disk requirement is met for the particular volume
    min_disk = image_meta.get('min_disk', 0)
    if vol_size < min_disk:
        msg = _('Volume size %(volume_size)sGB cannot be smaller'
                ' than the image minDisk size %(min_disk)sGB.')
        msg = msg % {'volume_size': vol_size, 'min_disk': min_disk}
        raise exception.InvalidInput(reason=msg)
示例#9
0
    def execute(self, context, volume_ref, request_spec):
        get_remote_image_service = glance.get_remote_image_service

        volume_name = volume_ref["name"]
        volume_size = utils.as_int(volume_ref["size"], quiet=False)

        # Create a dictionary that will represent the volume to be so that
        # later tasks can easily switch between the different types and create
        # the volume according to the volume types specifications (which are
        # represented in this dictionary).
        specs = {
            "status": volume_ref["status"],
            "type": "raw",  # This will have the type of the volume to be
            # created, which should be one of [raw, snap,
            # source_vol, image]
            "volume_id": volume_ref["id"],
            "volume_name": volume_name,
            "volume_size": volume_size,
        }

        if volume_ref.get("snapshot_id"):
            # We are making a snapshot based volume instead of a raw volume.
            specs.update({"type": "snap", "snapshot_id": volume_ref["snapshot_id"]})
        elif volume_ref.get("source_volid"):
            # We are making a source based volume instead of a raw volume.
            #
            # NOTE(harlowja): This will likely fail if the source volume
            # disappeared by the time this call occurred.
            source_volid = volume_ref.get("source_volid")
            source_volume_ref = objects.Volume.get_by_id(context, source_volid)
            specs.update(
                {
                    "source_volid": source_volid,
                    # This is captured incase we have to revert and we want to set
                    # back the source volume status to its original status. This
                    # may or may not be sketchy to do??
                    "source_volstatus": source_volume_ref["status"],
                    "type": "source_vol",
                }
            )
        elif request_spec.get("source_replicaid"):
            # We are making a clone based on the replica.
            #
            # NOTE(harlowja): This will likely fail if the replica
            # disappeared by the time this call occurred.
            source_volid = request_spec["source_replicaid"]
            source_volume_ref = objects.Volume.get_by_id(context, source_volid)
            specs.update(
                {
                    "source_replicaid": source_volid,
                    "source_replicastatus": source_volume_ref["status"],
                    "type": "source_replica",
                }
            )
        elif request_spec.get("image_id"):
            # We are making an image based volume instead of a raw volume.
            image_href = request_spec["image_id"]
            image_service, image_id = get_remote_image_service(context, image_href)
            specs.update(
                {
                    "type": "image",
                    "image_id": image_id,
                    "image_location": image_service.get_location(context, image_id),
                    "image_meta": image_service.show(context, image_id),
                    # Instead of refetching the image service later just save it.
                    #
                    # NOTE(harlowja): if we have to later recover this tasks output
                    # on another 'node' that this object won't be able to be
                    # serialized, so we will have to recreate this object on
                    # demand in the future.
                    "image_service": image_service,
                }
            )

        return specs
示例#10
0
    def execute(self, context, volume_ref, **kwargs):
        get_remote_image_service = glance.get_remote_image_service

        volume_name = volume_ref['name']
        volume_size = utils.as_int(volume_ref['size'], quiet=False)

        # Create a dictionary that will represent the volume to be so that
        # later tasks can easily switch between the different types and create
        # the volume according to the volume types specifications (which are
        # represented in this dictionary).
        specs = {
            'status': volume_ref['status'],
            'type': 'raw',  # This will have the type of the volume to be
                            # created, which should be one of [raw, snap,
                            # source_vol, image]
            'volume_id': volume_ref['id'],
            'volume_name': volume_name,
            'volume_size': volume_size,
        }

        if kwargs.get('snapshot_id'):
            # We are making a snapshot based volume instead of a raw volume.
            specs.update({
                'type': 'snap',
                'snapshot_id': kwargs['snapshot_id'],
            })
        elif kwargs.get('source_volid'):
            # We are making a source based volume instead of a raw volume.
            #
            # NOTE(harlowja): This will likely fail if the source volume
            # disappeared by the time this call occurred.
            source_volid = kwargs['source_volid']
            source_volume_ref = self.db.volume_get(context, source_volid)
            specs.update({
                'source_volid': source_volid,
                # This is captured incase we have to revert and we want to set
                # back the source volume status to its original status. This
                # may or may not be sketchy to do??
                'source_volstatus': source_volume_ref['status'],
                'type': 'source_vol',
            })
        elif kwargs.get('source_replicaid'):
            # We are making a clone based on the replica.
            #
            # NOTE(harlowja): This will likely fail if the replica
            # disappeared by the time this call occurred.
            source_volid = kwargs['source_replicaid']
            source_volume_ref = self.db.volume_get(context, source_volid)
            specs.update({
                'source_replicaid': source_volid,
                'source_replicastatus': source_volume_ref['status'],
                'type': 'source_replica',
            })
        elif kwargs.get('image_id'):
            # We are making an image based volume instead of a raw volume.
            image_href = kwargs['image_id']
            image_service, image_id = get_remote_image_service(context,
                                                               image_href)
            specs.update({
                'type': 'image',
                'image_id': image_id,
                'image_location': image_service.get_location(context,
                                                             image_id),
                'image_meta': image_service.show(context, image_id),
                # Instead of refetching the image service later just save it.
                #
                # NOTE(harlowja): if we have to later recover this tasks output
                # on another 'node' that this object won't be able to be
                # serialized, so we will have to recreate this object on
                # demand in the future.
                'image_service': image_service,
            })

        return specs
示例#11
0
    def execute(self, context, volume, request_spec):
        get_remote_image_service = glance.get_remote_image_service

        volume_name = volume.name
        volume_size = utils.as_int(volume.size, quiet=False)

        # Create a dictionary that will represent the volume to be so that
        # later tasks can easily switch between the different types and create
        # the volume according to the volume types specifications (which are
        # represented in this dictionary).
        specs = {
            'status': volume.status,
            'type': 'raw',  # This will have the type of the volume to be
                            # created, which should be one of [raw, snap,
                            # source_vol, image, backup]
            'volume_id': volume.id,
            'volume_name': volume_name,
            'volume_size': volume_size,
        }

        if volume.snapshot_id:
            # We are making a snapshot based volume instead of a raw volume.
            specs.update({
                'type': 'snap',
                'snapshot_id': volume.snapshot_id,
            })
        elif volume.source_volid:
            # We are making a source based volume instead of a raw volume.
            #
            # NOTE(harlowja): This will likely fail if the source volume
            # disappeared by the time this call occurred.
            source_volid = volume.source_volid
            source_volume_ref = objects.Volume.get_by_id(context,
                                                         source_volid)
            specs.update({
                'source_volid': source_volid,
                # This is captured incase we have to revert and we want to set
                # back the source volume status to its original status. This
                # may or may not be sketchy to do??
                'source_volstatus': source_volume_ref.status,
                'type': 'source_vol',
            })
        elif request_spec.get('image_id'):
            # We are making an image based volume instead of a raw volume.
            image_href = request_spec['image_id']
            image_service, image_id = get_remote_image_service(context,
                                                               image_href)
            specs.update({
                'type': 'image',
                'image_id': image_id,
                'image_location': image_service.get_location(context,
                                                             image_id),
                'image_meta': image_service.show(context, image_id),
                # Instead of refetching the image service later just save it.
                #
                # NOTE(harlowja): if we have to later recover this tasks output
                # on another 'node' that this object won't be able to be
                # serialized, so we will have to recreate this object on
                # demand in the future.
                'image_service': image_service,
            })
        elif request_spec.get('backup_id'):
            # We are making a backup based volume instead of a raw volume.
            specs.update({
                'type': 'backup',
                'backup_id': request_spec['backup_id'],
                # NOTE(luqitao): if the driver does not implement the method
                # `create_volume_from_backup`, cinder-backup will update the
                # volume's status, otherwise we need update it in the method
                # `CreateVolumeOnFinishTask`.
                'need_update_volume': True,
            })
        return specs
    def _extract_size(size, source_volume, snapshot):
        """Extracts and validates the volume size.

        This function will validate or when not provided fill in the provided
        size variable from the source_volume or snapshot and then does
        validation on the size that is found and returns said validated size.
        """
        def validate_snap_size(size):
            if snapshot and size < snapshot.volume_size:
                msg = _("Volume size '%(size)s'GB cannot be smaller than"
                        " the snapshot size %(snap_size)sGB. "
                        "They must be >= original snapshot size.")
                msg = msg % {'size': size, 'snap_size': snapshot.volume_size}
                raise exception.InvalidInput(reason=msg)

        def validate_source_size(size):
            if source_volume and size < source_volume['size']:
                msg = _("Volume size '%(size)s'GB cannot be smaller than "
                        "original volume size  %(source_size)sGB. "
                        "They must be >= original volume size.")
                msg = msg % {
                    'size': size,
                    'source_size': source_volume['size']
                }
                raise exception.InvalidInput(reason=msg)

        def validate_int(size):
            if not isinstance(size, int) or size <= 0:
                msg = _("Volume size '%(size)s' must be an integer and"
                        " greater than 0") % {
                            'size': size
                        }
                raise exception.InvalidInput(reason=msg)

        # Figure out which validation functions we should be applying
        # on the size value that we extract.
        validator_functors = [validate_int]
        if source_volume:
            validator_functors.append(validate_source_size)
        elif snapshot:
            validator_functors.append(validate_snap_size)

        # If the size is not provided then try to provide it.
        if not size and source_volume:
            size = source_volume['size']
        elif not size and snapshot:
            size = snapshot.volume_size

        size = utils.as_int(size)
        LOG.debug(
            "Validating volume '%(size)s' using %(functors)s" % {
                'size':
                size,
                'functors':
                ", ".join([
                    common.make_pretty_name(func)
                    for func in validator_functors
                ])
            })
        for func in validator_functors:
            func(size)
        return size