Exemplo n.º 1
0
    def _reschedule(self, context, cause, request_spec, filter_properties, volume):
        """Actions that happen during the rescheduling attempt occur here."""

        create_volume = self.scheduler_rpcapi.create_volume
        if not filter_properties:
            filter_properties = {}
        if "retry" not in filter_properties:
            filter_properties["retry"] = {}

        retry_info = filter_properties["retry"]
        num_attempts = retry_info.get("num_attempts", 0)
        request_spec["volume_id"] = volume.id

        LOG.debug(
            "Volume %(volume_id)s: re-scheduling %(method)s " "attempt %(num)d due to %(reason)s",
            {
                "volume_id": volume.id,
                "method": common.make_pretty_name(create_volume),
                "num": num_attempts,
                "reason": cause.exception_str,
            },
        )

        if all(cause.exc_info):
            # Stringify to avoid circular ref problem in json serialization
            retry_info["exc"] = traceback.format_exception(*cause.exc_info)

        return create_volume(
            context,
            CONF.volume_topic,
            volume.id,
            request_spec=request_spec,
            filter_properties=filter_properties,
            volume=volume,
        )
Exemplo n.º 2
0
    def _reschedule(self, context, cause, request_spec, filter_properties,
                    volume):
        """Actions that happen during the rescheduling attempt occur here."""

        create_volume = self.scheduler_rpcapi.create_volume
        if not filter_properties:
            filter_properties = {}
        if 'retry' not in filter_properties:
            filter_properties['retry'] = {}

        retry_info = filter_properties['retry']
        num_attempts = retry_info.get('num_attempts', 0)
        request_spec['volume_id'] = volume.id

        LOG.debug("Volume %(volume_id)s: re-scheduling %(method)s "
                  "attempt %(num)d due to %(reason)s",
                  {'volume_id': volume.id,
                   'method': common.make_pretty_name(create_volume),
                   'num': num_attempts,
                   'reason': cause.exception_str})

        if all(cause.exc_info):
            # Stringify to avoid circular ref problem in json serialization
            retry_info['exc'] = traceback.format_exception(*cause.exc_info)

        return create_volume(context, volume, request_spec=request_spec,
                             filter_properties=filter_properties)
Exemplo n.º 3
0
    def _reschedule(self, context, cause, request_spec, filter_properties,
                    snapshot_id, image_id, volume_id, **kwargs):
        """Actions that happen during the rescheduling attempt occur here."""

        create_volume = self.scheduler_rpcapi.create_volume
        if not filter_properties:
            filter_properties = {}
        if 'retry' not in filter_properties:
            filter_properties['retry'] = {}

        retry_info = filter_properties['retry']
        num_attempts = retry_info.get('num_attempts', 0)
        request_spec['volume_id'] = volume_id

        LOG.debug("Volume %(volume_id)s: re-scheduling %(method)s "
                  "attempt %(num)d due to %(reason)s" %
                  {'volume_id': volume_id,
                   'method': common.make_pretty_name(create_volume),
                   'num': num_attempts,
                   'reason': cause.exception_str})

        if all(cause.exc_info):
            # Stringify to avoid circular ref problem in json serialization
            retry_info['exc'] = traceback.format_exception(*cause.exc_info)

        return create_volume(context, CONF.volume_topic, volume_id,
                             snapshot_id=snapshot_id, image_id=image_id,
                             request_spec=request_spec,
                             filter_properties=filter_properties)
Exemplo n.º 4
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
Exemplo n.º 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
Exemplo n.º 6
0
    def execute(self, context, volume_ref, volume_spec):
        volume_spec = dict(volume_spec)
        volume_id = volume_spec.pop('volume_id', None)

        # we can't do anything if the driver didn't init
        if not self.driver.initialized:
            driver_name = self.driver.__class__.__name__
            LOG.error(
                _("Unable to create volume. "
                  "Volume driver %s not initialized") % driver_name)
            # NOTE(flaper87): Set the error status before
            # raising any exception.
            self.db.volume_update(context, volume_id, dict(status='error'))
            raise exception.DriverNotInitialized()

        create_type = volume_spec.pop('type', None)
        create_functor = self._create_func_mapping.get(create_type)
        if not create_functor:
            raise exception.VolumeTypeNotFound(volume_type_id=create_type)

        if not volume_id:
            volume_id = volume_ref['id']
        LOG.info(
            _("Volume %(volume_id)s: being created using %(functor)s "
              "with specification: %(volume_spec)s") % {
                  'volume_spec': volume_spec,
                  'volume_id': volume_id,
                  'functor': common.make_pretty_name(create_functor)
              })

        # Call the given functor to make the volume.
        model_update = create_functor(context,
                                      volume_ref=volume_ref,
                                      **volume_spec)

        # Persist any model information provided on creation.
        try:
            if model_update:
                volume_ref = self.db.volume_update(context, volume_ref['id'],
                                                   model_update)
        except exception.CinderException as ex:
            # If somehow the update failed we want to ensure that the
            # failure is logged (but not try rescheduling since the volume at
            # this point has been created).
            if model_update:
                LOG.exception(
                    _("Failed updating model of volume %(volume_id)s"
                      " with creation provided model %(model)s") % {
                          'volume_id': volume_id,
                          'model': model_update
                      })
                raise exception.ExportFailure(reason=ex)

        return volume_ref
Exemplo n.º 7
0
    def execute(self, context, volume_ref, volume_spec):
        volume_spec = dict(volume_spec)
        volume_id = volume_spec.pop('volume_id', None)

        # we can't do anything if the driver didn't init
        if not self.driver.initialized:
            driver_name = self.driver.__class__.__name__
            LOG.error(_("Unable to create volume. "
                        "Volume driver %s not initialized") % driver_name)
            # NOTE(flaper87): Set the error status before
            # raising any exception.
            self.db.volume_update(context, volume_id, dict(status='error'))
            raise exception.DriverNotInitialized()

        create_type = volume_spec.pop('type', None)
        create_functor = self._create_func_mapping.get(create_type)
        if not create_functor:
            raise exception.VolumeTypeNotFound(volume_type_id=create_type)

        if not volume_id:
            volume_id = volume_ref['id']
        LOG.info(_("Volume %(volume_id)s: being created using %(functor)s "
                   "with specification: %(volume_spec)s") %
                 {'volume_spec': volume_spec, 'volume_id': volume_id,
                  'functor': common.make_pretty_name(create_functor)})

        # NOTE(vish): so we don't have to get volume from db again before
        # passing it to the driver.
        volume_ref['host'] = self.host

        # Call the given functor to make the volume.
        model_update = create_functor(context, volume_ref=volume_ref,
                                      **volume_spec)

        # Persist any model information provided on creation.
        try:
            if model_update:
                volume_ref = self.db.volume_update(context, volume_ref['id'],
                                                   model_update)
        except exception.CinderException as ex:
            # If somehow the update failed we want to ensure that the
            # failure is logged (but not try rescheduling since the volume at
            # this point has been created).
            if model_update:
                LOG.exception(_("Failed updating model of volume %(volume_id)s"
                                " with creation provided model %(model)s") %
                              {'volume_id': volume_id, 'model': model_update})
                raise exception.ExportFailure(reason=ex)

        return volume_ref