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 create_export(self, context, volume, connector): model_update = {} try: if self.common.is_lun_mapped(volume['name']): return model_update iqn, trg_id, provider_auth = (self.common.create_iscsi_export( volume['name'], volume['id'])) except Exception as e: LOG.exception('Failed to remove_export.') raise exception.ExportFailure(reason=e) model_update['provider_location'] = (self.common.get_provider_location( iqn, trg_id)) model_update['provider_auth'] = provider_auth return model_update
def _attach_volume(self, context, volume, properties, remote=False): """Attach the volume.""" if remote: # Call remote manager's initialize_connection which includes # driver's create_export and initialize_connection rpcapi = volume_rpcapi.VolumeAPI() conn = rpcapi.initialize_connection(context, volume, properties) else: # Call local driver's create_export and initialize_connection. # NOTE(avishay) This is copied from the manager's code - need to # clean this up in the future. model_update = None try: LOG.debug(_("Volume %s: creating export"), volume['id']) model_update = self.create_export(context, volume) if model_update: volume = self.db.volume_update(context, volume['id'], model_update) except exception.CinderException as ex: if model_update: LOG.exception( _("Failed updating model of volume " "%(volume_id)s with driver provided model " "%(model)s") % { 'volume_id': volume['id'], 'model': model_update }) raise exception.ExportFailure(reason=ex) try: conn = self.initialize_connection(volume, properties) except Exception as err: try: err_msg = (_('Unable to fetch connection information from ' 'backend: %(err)s') % { 'err': err }) LOG.error(err_msg) LOG.debug("Cleaning up failed connect initialization.") self.remove_export(context, volume) except Exception as ex: ex_msg = (_('Error encountered during cleanup ' 'of a failed attach: %(ex)s') % { 'ex': ex }) LOG.error(err_msg) raise exception.VolumeBackendAPIException(data=ex_msg) raise exception.VolumeBackendAPIException(data=err_msg) # Use Brick's code to do attach/detach use_multipath = self.configuration.use_multipath_for_image_xfer device_scan_attempts = self.configuration.num_volume_device_scan_tries protocol = conn['driver_volume_type'] connector = utils.brick_get_connector( protocol, use_multipath=use_multipath, device_scan_attempts=device_scan_attempts, conn=conn) device = connector.connect_volume(conn['data']) host_device = device['path'] if not connector.check_valid_device(host_device): raise exception.DeviceUnavailable(path=host_device, reason=(_("Unable to access " "the backend storage " "via the path " "%(path)s.") % { 'path': host_device })) return {'conn': conn, 'device': device, 'connector': connector}