diff options
| author | Ronen Kat <ronenkat@il.ibm.com> | 2012-08-06 10:11:10 +0300 |
|---|---|---|
| committer | Mark McLoughlin <markmc@redhat.com> | 2012-09-07 14:07:01 +0100 |
| commit | 3379e821f715d6c63af3f0e96d276ca3f3ff24ca (patch) | |
| tree | 8795e48c3aba4c45040a302a660f506b68b565ce /nova/volume | |
| parent | 37cc45b8fdaa199b248a7ef5f683d514733b8387 (diff) | |
| download | nova-3379e821f715d6c63af3f0e96d276ca3f3ff24ca.tar.gz nova-3379e821f715d6c63af3f0e96d276ca3f3ff24ca.tar.xz nova-3379e821f715d6c63af3f0e96d276ca3f3ff24ca.zip | |
Use volume driver specific exceptions
Change generic use of exception.NovaException in the nova/volume directory
to specific exceptions. The exceptions used in this patch are:
exception.VolumeBackendAPIException
exception.InvalidInput
exception.InvalidVolume
exception.VolumeAtatched
Patch includes updates to the appropriate tests as well.
(cherry picked from cinder commit 3905a99)
Change-Id: I10407ff3f5babe64e88f445d3529269b7665ee16
Diffstat (limited to 'nova/volume')
| -rw-r--r-- | nova/volume/driver.py | 23 | ||||
| -rw-r--r-- | nova/volume/manager.py | 7 | ||||
| -rw-r--r-- | nova/volume/netapp.py | 47 | ||||
| -rw-r--r-- | nova/volume/san.py | 26 | ||||
| -rw-r--r-- | nova/volume/storwize_svc.py | 63 | ||||
| -rw-r--r-- | nova/volume/xensm.py | 32 |
6 files changed, 108 insertions, 90 deletions
diff --git a/nova/volume/driver.py b/nova/volume/driver.py index d03ad7cdc..8aa7fd595 100644 --- a/nova/volume/driver.py +++ b/nova/volume/driver.py @@ -104,8 +104,9 @@ class VolumeDriver(object): run_as_root=True) volume_groups = out.split() if not FLAGS.volume_group in volume_groups: - raise exception.NovaException(_("volume group %s doesn't exist") + exception_message = (_("volume group %s doesn't exist") % FLAGS.volume_group) + raise exception.VolumeBackendAPIException(data=exception_message) def _create_volume(self, volume_name, sizestr): self._try_execute('lvcreate', '-L', sizestr, '-n', @@ -429,9 +430,9 @@ class ISCSIDriver(VolumeDriver): location = self._do_iscsi_discovery(volume) if not location: - raise exception.NovaException(_("Could not find iSCSI export " - " for volume %s") % - (volume['name'])) + raise exception.InvalidVolume(_("Could not find iSCSI export " + " for volume %s") % + (volume['name'])) LOG.debug(_("ISCSI Discovery: Found %s") % (location)) properties['target_discovered'] = True @@ -563,8 +564,9 @@ class RBDDriver(VolumeDriver): (stdout, stderr) = self._execute('rados', 'lspools') pools = stdout.split("\n") if not FLAGS.rbd_pool in pools: - raise exception.NovaException(_("rbd has no pool %s") % - FLAGS.rbd_pool) + exception_message = (_("rbd has no pool %s") % + FLAGS.rbd_pool) + raise exception.VolumeBackendAPIException(data=exception_message) def create_volume(self, volume): """Creates a logical volume.""" @@ -641,10 +643,13 @@ class SheepdogDriver(VolumeDriver): # use it and just check if 'running' is in the output. (out, err) = self._execute('collie', 'cluster', 'info') if not 'running' in out.split(): - msg = _("Sheepdog is not working: %s") % out - raise exception.NovaException(msg) + exception_message = _("Sheepdog is not working: %s") % out + raise exception.VolumeBackendAPIException( + data=exception_message) + except exception.ProcessExecutionError: - raise exception.NovaException(_("Sheepdog is not working")) + exception_message = _("Sheepdog is not working") + raise exception.NovaException(data=exception_message) def create_volume(self, volume): """Creates a sheepdog volume""" diff --git a/nova/volume/manager.py b/nova/volume/manager.py index a45ae0d65..eed73e212 100644 --- a/nova/volume/manager.py +++ b/nova/volume/manager.py @@ -164,10 +164,11 @@ class VolumeManager(manager.SchedulerDependentManager): context = context.elevated() volume_ref = self.db.volume_get(context, volume_id) if volume_ref['attach_status'] == "attached": - raise exception.NovaException(_("Volume is still attached")) + # Volume is still attached, need to detach first + raise exception.VolumeAttached(volume_id=volume_id) if volume_ref['host'] != self.host: - msg = _("Volume is not local to this node") - raise exception.NovaException(msg) + raise exception.InvalidVolume( + reason=_("Volume is not local to this node")) self._notify_about_volume_usage(context, volume_ref, "delete.start") self._reset_stats() diff --git a/nova/volume/netapp.py b/nova/volume/netapp.py index 6dd5c0e31..1d0c574c7 100644 --- a/nova/volume/netapp.py +++ b/nova/volume/netapp.py @@ -106,7 +106,7 @@ class NetAppISCSIDriver(driver.ISCSIDriver): name = request.Name reason = response.Reason msg = _('API %(name)s failed: %(reason)s') - raise exception.NovaException(msg % locals()) + raise exception.VolumeBackendAPIException(data=msg % locals()) def _create_client(self, **kwargs): """Instantiate a web services client. @@ -151,11 +151,12 @@ class NetAppISCSIDriver(driver.ISCSIDriver): 'netapp_server_hostname', 'netapp_server_port'] for flag in required_flags: if not getattr(FLAGS, flag, None): - raise exception.NovaException(_('%s is not set') % flag) + raise exception.InvalidInput(reason=_('%s is not set') % flag) if not (FLAGS.netapp_storage_service or FLAGS.netapp_storage_service_prefix): - raise exception.NovaException(_('Either netapp_storage_service or ' - 'netapp_storage_service_prefix must be set')) + raise exception.InvalidInput(reason=_('Either ' + 'netapp_storage_service or netapp_storage_service_prefix must ' + 'be set')) def do_setup(self, context): """Setup the NetApp Volume driver. @@ -293,8 +294,8 @@ class NetAppISCSIDriver(driver.ISCSIDriver): events = self._get_job_progress(job_id) for event in events: if event.EventStatus == 'error': - raise exception.NovaException(_('Job failed: %s') % - (event.ErrorMessage)) + msg = _('Job failed: %s') % (event.ErrorMessage) + raise exception.VolumeBackendAPIException(data=msg) if event.EventType == 'job-end': return events time.sleep(5) @@ -324,11 +325,11 @@ class NetAppISCSIDriver(driver.ISCSIDriver): if ss_type and not self.storage_service_prefix: msg = _('Attempt to use volume_type without specifying ' 'netapp_storage_service_prefix flag.') - raise exception.NovaException(msg) + raise exception.VolumeBackendAPIException(data=msg) if not (ss_type or self.storage_service): msg = _('You must set the netapp_storage_service flag in order to ' 'create volumes with no volume_type.') - raise exception.NovaException(msg) + raise exception.VolumeBackendAPIException(data=msg) storage_service = self.storage_service if ss_type: storage_service = self.storage_service_prefix + ss_type @@ -396,7 +397,7 @@ class NetAppISCSIDriver(driver.ISCSIDriver): except (suds.WebFault, Exception): server.DatasetEditRollback(EditLockId=lock_id) msg = _('Failed to provision dataset member') - raise exception.NovaException(msg) + raise exception.VolumeBackendAPIException(data=msg) lun_id = None lunpath = None @@ -411,7 +412,7 @@ class NetAppISCSIDriver(driver.ISCSIDriver): if not lun_id: msg = _('No LUN was created by the provision job') - raise exception.NovaException(msg) + raise exception.VolumeBackendAPIException(data=msg) lun = DfmLun(dataset, lunpath, lun_id) self.discovered_luns.append(lun) @@ -449,7 +450,7 @@ class NetAppISCSIDriver(driver.ISCSIDriver): except (suds.WebFault, Exception): server.DatasetEditRollback(EditLockId=lock_id) msg = _('Failed to remove and delete dataset member') - raise exception.NovaException(msg) + raise exception.VolumeBackendAPIException(data=msg) def create_volume(self, volume): """Driver entry point for creating a new volume.""" @@ -489,8 +490,8 @@ class NetAppISCSIDriver(driver.ISCSIDriver): if lun.lunpath.endswith(lunpath_suffix): self.lun_table[name] = lun return lun - msg = _("No entry in LUN table for volume %s") - raise exception.NovaException(msg % (name)) + msg = _("No entry in LUN table for volume %s") % (name) + raise exception.VolumeBackendAPIException(data=msg) def delete_volume(self, volume): """Driver entry point for destroying existing volumes.""" @@ -510,7 +511,7 @@ class NetAppISCSIDriver(driver.ISCSIDriver): finally: server.LunListInfoIterEnd(Tag=tag) msg = _('Failed to get LUN details for LUN ID %s') - raise exception.NovaException(msg % lun_id) + raise exception.VolumeBackendAPIException(data=msg % lun_id) def _get_host_details(self, host_id): """Given the ID of a host, get the details about it. @@ -527,7 +528,7 @@ class NetAppISCSIDriver(driver.ISCSIDriver): finally: server.HostListInfoIterEnd(Tag=tag) msg = _('Failed to get host details for host ID %s') - raise exception.NovaException(msg % host_id) + raise exception.VolumeBackendAPIException(data=msg % host_id) def _get_iqn_for_host(self, host_id): """Get the iSCSI Target Name for a storage system.""" @@ -763,8 +764,8 @@ class NetAppISCSIDriver(driver.ISCSIDriver): initiator_name = connector['initiator'] lun_id = volume['provider_location'] if not lun_id: - msg = _("No LUN ID for volume %s") - raise exception.NovaException(msg % volume['name']) + msg = _("No LUN ID for volume %s") % volume['name'] + raise exception.VolumeBackendAPIException(data=msg) lun = self._get_lun_details(lun_id) lun_num = self._ensure_initiator_mapped(lun.HostId, lun.LunPath, initiator_name) @@ -773,12 +774,12 @@ class NetAppISCSIDriver(driver.ISCSIDriver): host.HostAddress) if not portal: msg = _('Failed to get target portal for filer: %s') - raise exception.NovaException(msg % host.HostName) + raise exception.VolumeBackendAPIException(data=msg % host.HostName) iqn = self._get_iqn_for_host(host.HostId) if not iqn: msg = _('Failed to get target IQN for filer: %s') - raise exception.NovaException(msg % host.HostName) + raise exception.VolumeBackendAPIException(data=msg % host.HostName) properties = {} properties['target_discovered'] = False @@ -810,8 +811,8 @@ class NetAppISCSIDriver(driver.ISCSIDriver): initiator_name = connector['initiator'] lun_id = volume['provider_location'] if not lun_id: - msg = _('No LUN ID for volume %s') - raise exception.NovaException(msg % (volume['name'])) + msg = _('No LUN ID for volume %s') % volume['name'] + raise exception.VolumeBackendAPIException(data=msg) lun = self._get_lun_details(lun_id) self._ensure_initiator_unmapped(lun.HostId, lun.LunPath, initiator_name) @@ -966,7 +967,7 @@ class NetAppISCSIDriver(driver.ISCSIDriver): if vol_size != snap_size: msg = _('Cannot create volume of size %(vol_size)s from ' 'snapshot of size %(snap_size)s') - raise exception.NovaException(msg % locals()) + raise exception.VolumeBackendAPIException(data=msg % locals()) vol_name = snapshot['volume_name'] snapshot_name = snapshot['name'] project = snapshot['project_id'] @@ -978,7 +979,7 @@ class NetAppISCSIDriver(driver.ISCSIDriver): if new_type != old_type: msg = _('Cannot create volume of type %(new_type)s from ' 'snapshot of type %(old_type)s') - raise exception.NovaException(msg % locals()) + raise exception.VolumeBackendAPIException(data=msg % locals()) lun = self._get_lun_details(lun_id) extra_gb = vol_size new_size = '+%dg' % extra_gb diff --git a/nova/volume/san.py b/nova/volume/san.py index 6fe46b1db..e6927a12d 100644 --- a/nova/volume/san.py +++ b/nova/volume/san.py @@ -112,7 +112,7 @@ class SanISCSIDriver(nova.volume.driver.ISCSIDriver): pkey=privatekey) else: msg = _("Specify san_password or san_private_key") - raise exception.NovaException(msg) + raise exception.InvalidInput(reason=msg) return ssh def _execute(self, *cmd, **kwargs): @@ -150,12 +150,12 @@ class SanISCSIDriver(nova.volume.driver.ISCSIDriver): """Returns an error if prerequisites aren't met.""" if not self.run_local: if not (FLAGS.san_password or FLAGS.san_private_key): - raise exception.NovaException(_('Specify san_password or ' - 'san_private_key')) + raise exception.InvalidInput( + reason=_('Specify san_password or san_private_key')) # The san_ip must always be set, because we use it for the target if not (FLAGS.san_ip): - raise exception.NovaException(_("san_ip must be set")) + raise exception.InvalidInput(reason=_("san_ip must be set")) def _collect_lines(data): @@ -226,8 +226,8 @@ class SolarisISCSIDriver(SanISCSIDriver): if "View Entry:" in out: return True - msg = _("Cannot parse list-view output: %s") % (out) - raise exception.NovaException() + msg = _("Cannot parse list-view output: %s") % out + raise exception.VolumeBackendAPIException(data=msg) def _get_target_groups(self): """Gets list of target groups from host.""" @@ -320,8 +320,9 @@ class SolarisISCSIDriver(SanISCSIDriver): luid = items[0].strip() return luid - raise Exception(_('LUID not found for %(zfs_poolname)s. ' - 'Output=%(out)s') % locals()) + msg = _('LUID not found for %(zfs_poolname)s. ' + 'Output=%(out)s') % locals() + raise exception.VolumeBackendAPIException(data=msg) def _is_lu_created(self, volume): luid = self._get_luid(volume) @@ -461,7 +462,7 @@ class HpSanISCSIDriver(SanISCSIDriver): msg = (_("Malformed response to CLIQ command " "%(verb)s %(cliq_args)s. Result=%(out)s") % locals()) - raise exception.NovaException(msg) + raise exception.VolumeBackendAPIException(data=msg) result_code = response_node.attrib.get("result") @@ -469,7 +470,7 @@ class HpSanISCSIDriver(SanISCSIDriver): msg = (_("Error running CLIQ command %(verb)s %(cliq_args)s. " " Result=%(out)s") % locals()) - raise exception.NovaException(msg) + raise exception.VolumeBackendAPIException(data=msg) return result_xml @@ -499,7 +500,7 @@ class HpSanISCSIDriver(SanISCSIDriver): msg = (_("Unexpected number of virtual ips for cluster " " %(cluster_name)s. Result=%(_xml)s") % locals()) - raise exception.NovaException(msg) + raise exception.VolumeBackendAPIException(data=msg) def _cliq_get_volume_info(self, volume_name): """Gets the volume info, including IQN""" @@ -602,7 +603,8 @@ class HpSanISCSIDriver(SanISCSIDriver): def local_path(self, volume): # TODO(justinsb): Is this needed here? - raise exception.NovaException(_("local_path not supported")) + msg = _("local_path not supported") + raise exception.VolumeBackendAPIException(data=msg) def initialize_connection(self, volume, connector): """Assigns the volume to a server. diff --git a/nova/volume/storwize_svc.py b/nova/volume/storwize_svc.py index dc3ed309d..d9b92126e 100644 --- a/nova/volume/storwize_svc.py +++ b/nova/volume/storwize_svc.py @@ -151,9 +151,9 @@ class StorwizeSVCDriver(san.SanISCSIDriver): 'err': str(err)}) search_text = '!%s!' % getattr(FLAGS, 'storwize_svc_volpool_name') if search_text not in out: - raise exception.InvalidParameterValue( - err=_('pool %s doesn\'t exist') - % getattr(FLAGS, 'storwize_svc_volpool_name')) + raise exception.InvalidInput( + reason=(_('pool %s doesn\'t exist') + % getattr(FLAGS, 'storwize_svc_volpool_name'))) storage_nodes = {} # Get the iSCSI names of the Storwize/SVC nodes @@ -322,63 +322,64 @@ class StorwizeSVCDriver(san.SanISCSIDriver): 'storwize_svc_volpool_name'] for flag in required_flags: if not getattr(FLAGS, flag, None): - raise exception.InvalidParameterValue( - err=_('%s is not set') % flag) + raise exception.InvalidInput( + reason=_('%s is not set') % flag) # Ensure that either password or keyfile were set if not (getattr(FLAGS, 'san_password', None) or getattr(FLAGS, 'san_private_key', None)): - raise exception.InvalidParameterValue( - err=_('Password or SSH private key is required for ' - 'authentication: set either san_password or ' - 'san_private_key option')) + raise exception.InvalidInput( + reason=_('Password or SSH private key is required for ' + 'authentication: set either san_password or ' + 'san_private_key option')) # vtype should either be 'striped' or 'seq' vtype = getattr(FLAGS, 'storwize_svc_vol_vtype') if vtype not in ['striped', 'seq']: - raise exception.InvalidParameterValue( - err=_('Illegal value specified for storwize_svc_vol_vtype: ' - 'set to either \'striped\' or \'seq\'')) + raise exception.InvalidInput( + reason=_('Illegal value specified for storwize_svc_vol_vtype: ' + 'set to either \'striped\' or \'seq\'')) # Check that rsize is a number or percentage rsize = getattr(FLAGS, 'storwize_svc_vol_rsize') if not self._check_num_perc(rsize) and (rsize not in ['auto', '-1']): - raise exception.InvalidParameterValue( - err=_('Illegal value specified for storwize_svc_vol_rsize: ' - 'set to either a number or a percentage')) + raise exception.InvalidInput( + reason=_('Illegal value specified for storwize_svc_vol_rsize: ' + 'set to either a number or a percentage')) # Check that warning is a number or percentage warning = getattr(FLAGS, 'storwize_svc_vol_warning') if not self._check_num_perc(warning): - raise exception.InvalidParameterValue( - err=_('Illegal value specified for storwize_svc_vol_warning: ' - 'set to either a number or a percentage')) + raise exception.InvalidInput( + reason=_('Illegal value specified for ' + 'storwize_svc_vol_warning: ' + 'set to either a number or a percentage')) # Check that autoexpand is a boolean autoexpand = getattr(FLAGS, 'storwize_svc_vol_autoexpand') if type(autoexpand) != type(True): - raise exception.InvalidParameterValue( - err=_('Illegal value specified for ' - 'storwize_svc_vol_autoexpand: set to either ' - 'True or False')) + raise exception.InvalidInput( + reason=_('Illegal value specified for ' + 'storwize_svc_vol_autoexpand: set to either ' + 'True or False')) # Check that grainsize is 32/64/128/256 grainsize = getattr(FLAGS, 'storwize_svc_vol_grainsize') if grainsize not in ['32', '64', '128', '256']: - raise exception.InvalidParameterValue( - err=_('Illegal value specified for ' - 'storwize_svc_vol_grainsize: set to either ' - '\'32\', \'64\', \'128\', or \'256\'')) + raise exception.InvalidInput( + reason=_('Illegal value specified for ' + 'storwize_svc_vol_grainsize: set to either ' + '\'32\', \'64\', \'128\', or \'256\'')) # Check that flashcopy_timeout is numeric and 32/64/128/256 flashcopy_timeout = getattr(FLAGS, 'storwize_svc_flashcopy_timeout') if not (flashcopy_timeout.isdigit() and int(flashcopy_timeout) > 0 and int(flashcopy_timeout) <= 600): - raise exception.InvalidParameterValue( - err=_('Illegal value %s specified for ' - 'storwize_svc_flashcopy_timeout: ' - 'valid values are between 0 and 600') - % flashcopy_timeout) + raise exception.InvalidInput( + reason=_('Illegal value %s specified for ' + 'storwize_svc_flashcopy_timeout: ' + 'valid values are between 0 and 600') + % flashcopy_timeout) # Check that compression is a boolean volume_compression = getattr(FLAGS, 'storwize_svc_vol_compression') diff --git a/nova/volume/xensm.py b/nova/volume/xensm.py index bde69e60d..3deec66f0 100644 --- a/nova/volume/xensm.py +++ b/nova/volume/xensm.py @@ -59,7 +59,8 @@ class XenSMDriver(nova.volume.driver.VolumeDriver): except Exception as ex: LOG.debug(_("Failed to create sr %s...continuing") % str(backend_ref['id'])) - raise exception.NovaException(_('Create failed')) + msg = _('Create failed') + raise exception.VolumeBackendAPIException(data=msg) LOG.debug(_('SR UUID of new SR is: %s') % sr_uuid) try: @@ -68,7 +69,8 @@ class XenSMDriver(nova.volume.driver.VolumeDriver): dict(sr_uuid=sr_uuid)) except Exception as ex: LOG.exception(ex) - raise exception.NovaException(_("Failed to update db")) + msg = _("Failed to update db") + raise exception.VolumeBackendAPIException(data=msg) else: # sr introduce, if not already done @@ -88,8 +90,8 @@ class XenSMDriver(nova.volume.driver.VolumeDriver): self._create_storage_repo(context, backend) except Exception as ex: LOG.exception(ex) - raise exception.NovaException(_('Failed to reach backend %d') - % backend['id']) + msg = _('Failed to reach backend %d') % backend['id'] + raise exception.VolumeBackendAPIException(data=msg) def __init__(self, *args, **kwargs): """Connect to the hypervisor.""" @@ -98,7 +100,7 @@ class XenSMDriver(nova.volume.driver.VolumeDriver): # hypervisor to be Xen if FLAGS.connection_type != 'xenapi': msg = _('XenSMDriver requires xenapi connection') - raise exception.NovaException(msg) + raise exception.VolumeBackendAPIException(data=msg) url = FLAGS.xenapi_connection_url username = FLAGS.xenapi_connection_username @@ -108,7 +110,8 @@ class XenSMDriver(nova.volume.driver.VolumeDriver): self._volumeops = volumeops.VolumeOps(session) except Exception as ex: LOG.exception(ex) - raise exception.NovaException(_("Failed to initiate session")) + msg = _("Failed to initiate session") + raise exception.VolumeBackendAPIException(data=msg) super(XenSMDriver, self).__init__(execute=utils.execute, sync_exec=utils.execute, @@ -153,10 +156,11 @@ class XenSMDriver(nova.volume.driver.VolumeDriver): except Exception as ex: LOG.exception(ex) msg = _("Failed to update volume in db") - raise exception.NovaException(msg) + raise exception.VolumeBackendAPIException(data=msg) else: - raise exception.NovaException(_('Unable to create volume')) + msg = _('Unable to create volume') + raise exception.VolumeBackendAPIException(data=msg) def delete_volume(self, volume): @@ -172,13 +176,15 @@ class XenSMDriver(nova.volume.driver.VolumeDriver): self._volumeops.delete_volume_for_sm(vol_rec['vdi_uuid']) except Exception as ex: LOG.exception(ex) - raise exception.NovaException(_("Failed to delete vdi")) + msg = _("Failed to delete vdi") + raise exception.VolumeBackendAPIException(data=msg) try: self.db.sm_volume_delete(self.ctxt, volume['id']) except Exception as ex: LOG.exception(ex) - raise exception.NovaException(_("Failed to delete volume in db")) + msg = _("Failed to delete volume in db") + raise exception.VolumeBackendAPIException(data=msg) def local_path(self, volume): return str(volume['id']) @@ -211,7 +217,8 @@ class XenSMDriver(nova.volume.driver.VolumeDriver): volume['id'])) except Exception as ex: LOG.exception(ex) - raise exception.NovaException(_("Failed to find volume in db")) + msg = _("Failed to find volume in db") + raise exception.VolumeBackendAPIException(data=msg) # Keep the volume id key consistent with what ISCSI driver calls it xensm_properties['volume_id'] = xensm_properties['id'] @@ -222,7 +229,8 @@ class XenSMDriver(nova.volume.driver.VolumeDriver): xensm_properties['backend_id']) except Exception as ex: LOG.exception(ex) - raise exception.NovaException(_("Failed to find backend in db")) + msg = _("Failed to find backend in db") + raise exception.VolumeBackendAPIException(data=msg) params = self._convert_config_params(backend_conf['config_params']) |
