Subclass vendor specific exceptions.
Up until now drivers have been able to define their own custom exception classes. In most cases these are inherited from either a native python exception class or at best the base cinder exception class. The problem with this is that it makes it very difficult for higher layers (such as volume manager) to do any intelligent exception handling and the base Cinder.exception class is too broad. This change takes the first step in cleaning this up. We create new exception classes for all drivers to inherit from: VolumeDriverException VolumeBackendAPIException BackupDriverException This still allows the freedom to create custom exceptions for a particular driver, however it also gives us a common exception class to catch and check in higher levels. Further refinement and standardization will be helpful going forward but this should give us a good start. Change-Id: I8c2ca4eecf7a64a82846d6d24fc0239db086237e
This commit is contained in:
parent
9f138a1efd
commit
8b6f41715c
|
@ -106,6 +106,19 @@ class CinderException(Exception):
|
|||
return unicode(self.msg)
|
||||
|
||||
|
||||
class VolumeBackendAPIException(CinderException):
|
||||
message = _("Bad or unexpected response from the storage volume "
|
||||
"backend API: %(data)s")
|
||||
|
||||
|
||||
class VolumeDriverException(CinderException):
|
||||
message = _("Volume driver reported an error: %(message)s")
|
||||
|
||||
|
||||
class BackupDriverException(CinderException):
|
||||
message = _("Backup driver reported an error: %(message)s")
|
||||
|
||||
|
||||
class GlanceConnectionFailed(CinderException):
|
||||
message = _("Connection to glance failed: %(reason)s")
|
||||
|
||||
|
@ -218,11 +231,6 @@ class VolumeNotFound(NotFound):
|
|||
message = _("Volume %(volume_id)s could not be found.")
|
||||
|
||||
|
||||
class SfAccountNotFound(NotFound):
|
||||
message = _("Unable to locate account %(account_name)s on "
|
||||
"Solidfire device")
|
||||
|
||||
|
||||
class VolumeMetadataNotFound(NotFound):
|
||||
message = _("Volume %(volume_id)s has no metadata with "
|
||||
"key %(metadata_key)s.")
|
||||
|
@ -417,92 +425,31 @@ class DuplicateSfVolumeNames(Duplicate):
|
|||
message = _("Detected more than one volume with name %(vol_name)s")
|
||||
|
||||
|
||||
class Invalid3PARDomain(CinderException):
|
||||
message = _("Invalid 3PAR Domain: %(err)s")
|
||||
|
||||
|
||||
class VolumeTypeCreateFailed(CinderException):
|
||||
message = _("Cannot create volume_type with "
|
||||
"name %(name)s and specs %(extra_specs)s")
|
||||
|
||||
|
||||
class SolidFireAPIException(CinderException):
|
||||
message = _("Bad response from SolidFire API")
|
||||
|
||||
|
||||
class SolidFireAPIDataException(SolidFireAPIException):
|
||||
message = _("Error in SolidFire API response: data=%(data)s")
|
||||
|
||||
|
||||
class UnknownCmd(Invalid):
|
||||
class UnknownCmd(VolumeDriverException):
|
||||
message = _("Unknown or unsupported command %(cmd)s")
|
||||
|
||||
|
||||
class MalformedResponse(Invalid):
|
||||
class MalformedResponse(VolumeDriverException):
|
||||
message = _("Malformed response to command %(cmd)s: %(reason)s")
|
||||
|
||||
|
||||
class BadHTTPResponseStatus(CinderException):
|
||||
message = _("Bad HTTP response status %(status)s")
|
||||
class BadDriverResponseStatus(VolumeDriverException):
|
||||
message = _("Bad driver response status: %(status)s")
|
||||
|
||||
|
||||
class FailedCmdWithDump(CinderException):
|
||||
class FailedCmdWithDump(VolumeDriverException):
|
||||
message = _("Operation failed with status=%(status)s. Full dump: %(data)s")
|
||||
|
||||
|
||||
class ZadaraServerCreateFailure(CinderException):
|
||||
message = _("Unable to create server object for initiator %(name)s")
|
||||
|
||||
|
||||
class ZadaraServerNotFound(NotFound):
|
||||
message = _("Unable to find server object for initiator %(name)s")
|
||||
|
||||
|
||||
class ZadaraVPSANoActiveController(CinderException):
|
||||
message = _("Unable to find any active VPSA controller")
|
||||
|
||||
|
||||
class ZadaraAttachmentsNotFound(NotFound):
|
||||
message = _("Failed to retrieve attachments for volume %(name)s")
|
||||
|
||||
|
||||
class ZadaraInvalidAttachmentInfo(Invalid):
|
||||
message = _("Invalid attachment info for volume %(name)s: %(reason)s")
|
||||
|
||||
|
||||
class InstanceNotFound(NotFound):
|
||||
message = _("Instance %(instance_id)s could not be found.")
|
||||
|
||||
|
||||
class VolumeBackendAPIException(CinderException):
|
||||
message = _("Bad or unexpected response from the storage volume "
|
||||
"backend API: %(data)s")
|
||||
|
||||
|
||||
class NfsException(CinderException):
|
||||
message = _("Unknown NFS exception")
|
||||
|
||||
|
||||
class NfsNoSharesMounted(NotFound):
|
||||
message = _("No mounted NFS shares found")
|
||||
|
||||
|
||||
class NfsNoSuitableShareFound(NotFound):
|
||||
message = _("There is no share which can host %(volume_size)sG")
|
||||
|
||||
|
||||
class GlusterfsException(CinderException):
|
||||
message = _("Unknown Gluster exception")
|
||||
|
||||
|
||||
class GlusterfsNoSharesMounted(NotFound):
|
||||
message = _("No mounted Gluster shares found")
|
||||
|
||||
|
||||
class GlusterfsNoSuitableShareFound(NotFound):
|
||||
message = _("There is no share which can host %(volume_size)sG")
|
||||
|
||||
|
||||
class GlanceMetadataExists(Invalid):
|
||||
message = _("Glance metadata cannot be updated, key %(key)s"
|
||||
" exists for volume id %(volume_id)s")
|
||||
|
@ -532,7 +479,7 @@ class ImageCopyFailure(Invalid):
|
|||
message = _("Failed to copy image to volume: %(reason)s")
|
||||
|
||||
|
||||
class BackupInvalidCephArgs(Invalid):
|
||||
class BackupInvalidCephArgs(BackupDriverException):
|
||||
message = _("Invalid Ceph args provided for backup rbd operation")
|
||||
|
||||
|
||||
|
@ -540,7 +487,7 @@ class BackupOperationError(Invalid):
|
|||
message = _("An error has occurred during backup operation")
|
||||
|
||||
|
||||
class BackupRBDOperationFailed(Invalid):
|
||||
class BackupRBDOperationFailed(BackupDriverException):
|
||||
message = _("Backup RBD operation failed")
|
||||
|
||||
|
||||
|
@ -556,7 +503,7 @@ class InvalidBackup(Invalid):
|
|||
message = _("Invalid backup: %(reason)s")
|
||||
|
||||
|
||||
class SwiftConnectionFailed(CinderException):
|
||||
class SwiftConnectionFailed(BackupDriverException):
|
||||
message = _("Connection to swift failed: %(reason)s")
|
||||
|
||||
|
||||
|
@ -572,34 +519,6 @@ class SSHInjectionThreat(CinderException):
|
|||
message = _("SSH command injection detected: %(command)s")
|
||||
|
||||
|
||||
class CoraidException(CinderException):
|
||||
message = _('Coraid Cinder Driver exception.')
|
||||
|
||||
|
||||
class CoraidJsonEncodeFailure(CoraidException):
|
||||
message = _('Failed to encode json data.')
|
||||
|
||||
|
||||
class CoraidESMBadCredentials(CoraidException):
|
||||
message = _('Login on ESM failed.')
|
||||
|
||||
|
||||
class CoraidESMReloginFailed(CoraidException):
|
||||
message = _('Relogin on ESM failed.')
|
||||
|
||||
|
||||
class CoraidESMBadGroup(CoraidException):
|
||||
message = _('Group with name "%(group_name)s" not found.')
|
||||
|
||||
|
||||
class CoraidESMConfigureError(CoraidException):
|
||||
message = _('ESM configure request failed: %(message)s.')
|
||||
|
||||
|
||||
class CoraidESMNotAvailable(CoraidException):
|
||||
message = _('Coraid ESM not available with reason: %(reason)s.')
|
||||
|
||||
|
||||
class QoSSpecsExists(Duplicate):
|
||||
message = _("QoS Specs %(specs_id)s already exists.")
|
||||
|
||||
|
@ -643,3 +562,115 @@ class QoSSpecsInUse(CinderException):
|
|||
|
||||
class KeyManagerError(CinderException):
|
||||
msg_fmt = _("key manager error: %(reason)s")
|
||||
|
||||
|
||||
# Driver specific exceptions
|
||||
# Coraid
|
||||
class CoraidException(VolumeDriverException):
|
||||
message = _('Coraid Cinder Driver exception.')
|
||||
|
||||
|
||||
class CoraidJsonEncodeFailure(CoraidException):
|
||||
message = _('Failed to encode json data.')
|
||||
|
||||
|
||||
class CoraidESMBadCredentials(CoraidException):
|
||||
message = _('Login on ESM failed.')
|
||||
|
||||
|
||||
class CoraidESMReloginFailed(CoraidException):
|
||||
message = _('Relogin on ESM failed.')
|
||||
|
||||
|
||||
class CoraidESMBadGroup(CoraidException):
|
||||
message = _('Group with name "%(group_name)s" not found.')
|
||||
|
||||
|
||||
class CoraidESMConfigureError(CoraidException):
|
||||
message = _('ESM configure request failed: %(message)s.')
|
||||
|
||||
|
||||
class CoraidESMNotAvailable(CoraidException):
|
||||
message = _('Coraid ESM not available with reason: %(reason)s.')
|
||||
|
||||
|
||||
# Zadara
|
||||
class ZadaraException(VolumeDriverException):
|
||||
message = _('Zadara Cinder Driver exception.')
|
||||
|
||||
|
||||
class ZadaraServerCreateFailure(ZadaraException):
|
||||
message = _("Unable to create server object for initiator %(name)s")
|
||||
|
||||
|
||||
class ZadaraServerNotFound(ZadaraException):
|
||||
message = _("Unable to find server object for initiator %(name)s")
|
||||
|
||||
|
||||
class ZadaraVPSANoActiveController(ZadaraException):
|
||||
message = _("Unable to find any active VPSA controller")
|
||||
|
||||
|
||||
class ZadaraAttachmentsNotFound(ZadaraException):
|
||||
message = _("Failed to retrieve attachments for volume %(name)s")
|
||||
|
||||
|
||||
class ZadaraInvalidAttachmentInfo(ZadaraException):
|
||||
message = _("Invalid attachment info for volume %(name)s: %(reason)s")
|
||||
|
||||
|
||||
class BadHTTPResponseStatus(ZadaraException):
|
||||
message = _("Bad HTTP response status %(status)s")
|
||||
|
||||
|
||||
#SolidFire
|
||||
class SolidFireAPIException(VolumeBackendAPIException):
|
||||
message = _("Bad response from SolidFire API")
|
||||
|
||||
|
||||
class SolidFireDriverException(VolumeDriverException):
|
||||
message = _("SolidFire Cinder Driver exception")
|
||||
|
||||
|
||||
class SolidFireAPIDataException(SolidFireAPIException):
|
||||
message = _("Error in SolidFire API response: data=%(data)s")
|
||||
|
||||
|
||||
class SolidFireAccountNotFound(SolidFireDriverException):
|
||||
message = _("Unable to locate account %(account_name)s on "
|
||||
"Solidfire device")
|
||||
|
||||
|
||||
class DuplicateSolidFireVolumeNames(SolidFireDriverException):
|
||||
message = _("Detected more than one volume with name %(vol_name)s")
|
||||
|
||||
|
||||
# HP 3Par
|
||||
class Invalid3PARDomain(VolumeDriverException):
|
||||
message = _("Invalid 3PAR Domain: %(err)s")
|
||||
|
||||
|
||||
# NFS driver
|
||||
class NfsException(VolumeDriverException):
|
||||
message = _("Unknown NFS exception")
|
||||
|
||||
|
||||
class NfsNoSharesMounted(VolumeDriverException):
|
||||
message = _("No mounted NFS shares found")
|
||||
|
||||
|
||||
class NfsNoSuitableShareFound(VolumeDriverException):
|
||||
message = _("There is no share which can host %(volume_size)sG")
|
||||
|
||||
|
||||
# Gluster driver
|
||||
class GlusterfsException(VolumeDriverException):
|
||||
message = _("Unknown Gluster exception")
|
||||
|
||||
|
||||
class GlusterfsNoSharesMounted(VolumeDriverException):
|
||||
message = _("No mounted Gluster shares found")
|
||||
|
||||
|
||||
class GlusterfsNoSuitableShareFound(VolumeDriverException):
|
||||
message = _("There is no share which can host %(volume_size)sG")
|
||||
|
|
|
@ -405,7 +405,8 @@ class GlusterFsDriverTestCase(test.TestCase):
|
|||
|
||||
drv._mounted_shares = []
|
||||
|
||||
self.assertRaises(exception.NotFound, drv._find_share,
|
||||
self.assertRaises(exception.GlusterfsNoSharesMounted,
|
||||
drv._find_share,
|
||||
self.TEST_SIZE_IN_GB)
|
||||
|
||||
def test_find_share(self):
|
||||
|
|
|
@ -399,7 +399,7 @@ class NfsDriverTestCase(test.TestCase):
|
|||
|
||||
drv._mounted_shares = []
|
||||
|
||||
self.assertRaises(exception.NotFound, drv._find_share,
|
||||
self.assertRaises(exception.NfsNoSharesMounted, drv._find_share,
|
||||
self.TEST_SIZE_IN_GB)
|
||||
|
||||
def test_find_share(self):
|
||||
|
|
|
@ -367,7 +367,7 @@ class SolidFireVolumeTestCase(test.TestCase):
|
|||
'created_at': timeutils.utcnow()}
|
||||
|
||||
sfv = SolidFireDriver(configuration=self.configuration)
|
||||
self.assertRaises(exception.SfAccountNotFound,
|
||||
self.assertRaises(exception.SolidFireAccountNotFound,
|
||||
sfv.delete_volume,
|
||||
testvol)
|
||||
|
||||
|
@ -426,6 +426,6 @@ class SolidFireVolumeTestCase(test.TestCase):
|
|||
'created_at': timeutils.utcnow()}
|
||||
|
||||
sfv = SolidFireDriver(configuration=self.configuration)
|
||||
self.assertRaises(exception.SfAccountNotFound,
|
||||
self.assertRaises(exception.SolidFireAccountNotFound,
|
||||
sfv.extend_volume,
|
||||
testvol, 2)
|
||||
|
|
|
@ -231,7 +231,8 @@ class SolidFireDriver(SanISCSIDriver):
|
|||
sf_account_name = self._get_sf_account_name(project_id)
|
||||
sfaccount = self._get_sfaccount_by_name(sf_account_name)
|
||||
if sfaccount is None:
|
||||
raise exception.SfAccountNotFound(account_name=sf_account_name)
|
||||
raise exception.SolidFireAccountNotFound(
|
||||
account_name=sf_account_name)
|
||||
|
||||
return sfaccount
|
||||
|
||||
|
|
Loading…
Reference in New Issue