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, )
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)
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)
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
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
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
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