Replace ApiError with new exceptions
* Convert ApiError to EC2APIError * Add new exceptions to replace ApiError where it didn't belong * Fixes bug 926250 Change-Id: Ia711440ee0313faf8ea8c87e2c0a2f5b39cc55a2
This commit is contained in:
@@ -1607,7 +1607,7 @@ class VsaDriveTypeCommands(object):
|
||||
"""Marks volume types as deleted"""
|
||||
try:
|
||||
volume_types.destroy(self.context, name)
|
||||
except exception.ApiError:
|
||||
except exception.InvalidVolumeType:
|
||||
print "Valid volume type name is required"
|
||||
sys.exit(1)
|
||||
except exception.DBError, e:
|
||||
@@ -1786,7 +1786,7 @@ class InstanceTypeCommands(object):
|
||||
"""Marks instance types / flavors as deleted"""
|
||||
try:
|
||||
instance_types.destroy(name)
|
||||
except exception.ApiError:
|
||||
except exception.InstanceTypeNotFound:
|
||||
print "Valid instance type name is required"
|
||||
sys.exit(1)
|
||||
except exception.DBError, e:
|
||||
|
@@ -80,7 +80,7 @@ class Error(Exception):
|
||||
super(Error, self).__init__(message)
|
||||
|
||||
|
||||
class ApiError(Error):
|
||||
class EC2APIError(Error):
|
||||
def __init__(self, message='Unknown', code=None):
|
||||
self.msg = message
|
||||
self.code = code
|
||||
@@ -88,7 +88,7 @@ class ApiError(Error):
|
||||
outstr = '%s: %s' % (code, message)
|
||||
else:
|
||||
outstr = '%s' % message
|
||||
super(ApiError, self).__init__(outstr)
|
||||
super(EC2APIError, self).__init__(outstr)
|
||||
|
||||
|
||||
class DBError(Error):
|
||||
@@ -223,6 +223,14 @@ class Invalid(NovaException):
|
||||
message = _("Unacceptable parameters.")
|
||||
|
||||
|
||||
class InvalidSnapshot(Invalid):
|
||||
message = _("Invalid snapshot") + ": %(reason)s"
|
||||
|
||||
|
||||
class VolumeUnattached(Invalid):
|
||||
message = _("Volume %(volume_id)s is not attached to anything")
|
||||
|
||||
|
||||
class InvalidKeypair(Invalid):
|
||||
message = _("Keypair data is invalid")
|
||||
|
||||
@@ -248,7 +256,11 @@ class InvalidInstanceType(Invalid):
|
||||
|
||||
|
||||
class InvalidVolumeType(Invalid):
|
||||
message = _("Invalid volume type %(volume_type)s.")
|
||||
message = _("Invalid volume type") + ": %(reason)s"
|
||||
|
||||
|
||||
class InvalidVolume(Invalid):
|
||||
message = _("Invalid volume") + ": %(reason)s"
|
||||
|
||||
|
||||
class InvalidPortRange(Invalid):
|
||||
@@ -930,9 +942,8 @@ class WillNotSchedule(NovaException):
|
||||
message = _("Host %(host)s is not up or doesn't exist.")
|
||||
|
||||
|
||||
class QuotaError(ApiError):
|
||||
"""Quota Exceeded."""
|
||||
pass
|
||||
class QuotaError(NovaException):
|
||||
message = _("Quota exceeded") + ": code=%(code)s"
|
||||
|
||||
|
||||
class AggregateNotFound(NotFound):
|
||||
@@ -962,3 +973,24 @@ class AggregateHostExists(Duplicate):
|
||||
|
||||
class DuplicateSfVolumeNames(Duplicate):
|
||||
message = _("Detected more than one volume with name %(vol_name)")
|
||||
|
||||
|
||||
class VolumeTypeCreateFailed(NovaException):
|
||||
message = _("Cannot create volume_type with "
|
||||
"name %(name)s and specs %(extra_specs)s")
|
||||
|
||||
|
||||
class InstanceTypeCreateFailed(NovaException):
|
||||
message = _("Unable to create instance type")
|
||||
|
||||
|
||||
class SolidFireAPIException(NovaException):
|
||||
message = _("Bad response from SolidFire API")
|
||||
|
||||
|
||||
class SolidFireAPIStatusException(SolidFireAPIException):
|
||||
message = _("Error in SolidFire API response: status=%(status)s")
|
||||
|
||||
|
||||
class SolidFireAPIDataException(SolidFireAPIException):
|
||||
message = _("Error in SolidFire API response: data=%(data)s")
|
||||
|
@@ -13,14 +13,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova import context
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova import flags
|
||||
from nova import log as logging
|
||||
from nova import rpc
|
||||
from nova.scheduler import vsa as vsa_sched
|
||||
from nova import test
|
||||
from nova.tests.scheduler import test_scheduler
|
||||
from nova import utils
|
||||
from nova.volume import volume_types
|
||||
|
@@ -176,5 +176,5 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
def test_get_cluster_info_fail(self):
|
||||
SFID._issue_api_request = self.fake_issue_api_request_fails
|
||||
sfv = SFID()
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.SolidFireAPIException,
|
||||
sfv._get_cluster_info)
|
||||
|
@@ -2357,7 +2357,7 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
address = '0.1.2.3'
|
||||
|
||||
self.compute.run_instance(self.context, instance_uuid)
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.FixedIpNotFoundForInstance,
|
||||
self.compute_api.associate_floating_ip,
|
||||
self.context,
|
||||
instance,
|
||||
@@ -2967,7 +2967,7 @@ class ComputeAPITestCase(BaseTestCase):
|
||||
self.compute_api.delete(self.context, instance)
|
||||
|
||||
def test_attach_volume_invalid(self):
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.InvalidDevicePath,
|
||||
self.compute_api.attach_volume,
|
||||
self.context,
|
||||
None,
|
||||
|
@@ -85,7 +85,7 @@ class InstanceTypeTestCase(test.TestCase):
|
||||
'instance type was not created')
|
||||
|
||||
instance_types.destroy(name)
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.InstanceTypeNotFound,
|
||||
instance_types.get_instance_type, inst_type_id)
|
||||
|
||||
# deleted instance should not be in list anymoer
|
||||
@@ -133,7 +133,7 @@ class InstanceTypeTestCase(test.TestCase):
|
||||
'unknown_flavor')
|
||||
|
||||
def test_duplicate_names_fail(self):
|
||||
"""Ensures that name duplicates raise ApiError"""
|
||||
"""Ensures that name duplicates raise InstanceTypeCreateFailed"""
|
||||
name = 'some_name'
|
||||
instance_types.create(name, 256, 1, 120, 200, 'flavor1')
|
||||
self.assertRaises(exception.InstanceTypeExists,
|
||||
@@ -141,7 +141,7 @@ class InstanceTypeTestCase(test.TestCase):
|
||||
name, 256, 1, 120, 200, 'flavor2')
|
||||
|
||||
def test_duplicate_flavorids_fail(self):
|
||||
"""Ensures that flavorid duplicates raise ApiError"""
|
||||
"""Ensures that flavorid duplicates raise InstanceTypeCreateFailed"""
|
||||
flavorid = 'flavor1'
|
||||
instance_types.create('name one', 256, 1, 120, 200, flavorid)
|
||||
self.assertRaises(exception.InstanceTypeExists,
|
||||
@@ -156,7 +156,7 @@ class InstanceTypeTestCase(test.TestCase):
|
||||
def test_will_not_get_bad_default_instance_type(self):
|
||||
"""ensures error raised on bad default instance type"""
|
||||
self.flags(default_instance_type='unknown_flavor')
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.InstanceTypeNotFound,
|
||||
instance_types.get_default_instance_type)
|
||||
|
||||
def test_will_get_instance_type_by_id(self):
|
||||
@@ -167,12 +167,12 @@ class InstanceTypeTestCase(test.TestCase):
|
||||
|
||||
def test_will_not_get_instance_type_by_unknown_id(self):
|
||||
"""Ensure get by name returns default flavor with no name"""
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.InstanceTypeNotFound,
|
||||
instance_types.get_instance_type, 10000)
|
||||
|
||||
def test_will_not_get_instance_type_with_bad_id(self):
|
||||
"""Ensure get by name returns default flavor with bad name"""
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.InstanceTypeNotFound,
|
||||
instance_types.get_instance_type, 'asdf')
|
||||
|
||||
def test_instance_type_get_by_None_name_returns_default(self):
|
||||
@@ -183,7 +183,7 @@ class InstanceTypeTestCase(test.TestCase):
|
||||
|
||||
def test_will_not_get_instance_type_with_bad_name(self):
|
||||
"""Ensure get by name returns default flavor with bad name"""
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.InstanceTypeNotFound,
|
||||
instance_types.get_instance_type_by_name, 10000)
|
||||
|
||||
def test_will_not_get_instance_by_unknown_flavor_id(self):
|
||||
|
@@ -249,7 +249,7 @@ class VolumeTestCase(test.TestCase):
|
||||
|
||||
volume_api = nova.volume.api.API()
|
||||
volume = volume_api.get(self.context, volume['id'])
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.InvalidVolume,
|
||||
volume_api.create_snapshot,
|
||||
self.context, volume,
|
||||
'fake_name', 'fake_description')
|
||||
|
@@ -85,7 +85,7 @@ class VolumeTypeTestCase(test.TestCase):
|
||||
|
||||
def test_non_existant_vol_type_shouldnt_delete(self):
|
||||
"""Ensures that volume type creation fails with invalid args"""
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.VolumeTypeNotFoundByName,
|
||||
volume_types.destroy, self.ctxt, "sfsfsdfdfs")
|
||||
|
||||
def test_repeated_vol_types_shouldnt_raise(self):
|
||||
|
@@ -90,7 +90,7 @@ class VsaTestCase(test.TestCase):
|
||||
|
||||
def test_vsa_create_wrong_image_name(self):
|
||||
param = {'image_name': 'wrong_image_name'}
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.ImageNotFound,
|
||||
self.vsa_api.create, self.context, **param)
|
||||
|
||||
def test_vsa_create_db_error(self):
|
||||
@@ -100,19 +100,19 @@ class VsaTestCase(test.TestCase):
|
||||
raise exception.Error
|
||||
|
||||
self.stubs.Set(nova.db, 'vsa_create', fake_vsa_create)
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.Error,
|
||||
self.vsa_api.create, self.context)
|
||||
|
||||
def test_vsa_create_wrong_storage_params(self):
|
||||
vsa_list1 = self.vsa_api.get_all(self.context)
|
||||
param = {'storage': [{'stub': 1}]}
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.InvalidVolumeType,
|
||||
self.vsa_api.create, self.context, **param)
|
||||
vsa_list2 = self.vsa_api.get_all(self.context)
|
||||
self.assertEqual(len(vsa_list2), len(vsa_list1))
|
||||
|
||||
param = {'storage': [{'drive_name': 'wrong name'}]}
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.InvalidVolumeType,
|
||||
self.vsa_api.create, self.context, **param)
|
||||
|
||||
def test_vsa_create_with_storage(self, multi_vol_creation=True):
|
||||
|
@@ -107,14 +107,14 @@ class VsaVolumesTestCase(test.TestCase):
|
||||
'deleting')
|
||||
|
||||
def test_vsa_volume_delete_nonavail_volume(self):
|
||||
""" Check volume deleton in different states. """
|
||||
""" Check volume deletion in different states. """
|
||||
volume_param = self._default_volume_param()
|
||||
volume_ref = self.volume_api.create(self.context, **volume_param)
|
||||
|
||||
self.volume_api.update(self.context,
|
||||
volume_ref,
|
||||
{'status': 'in-use'})
|
||||
self.assertRaises(exception.ApiError,
|
||||
self.assertRaises(exception.InvalidVolume,
|
||||
self.volume_api.delete,
|
||||
self.context, volume_ref)
|
||||
|
||||
|
@@ -23,8 +23,6 @@ For assistance and guidelines pls contact
|
||||
Zadara Storage Inc & Openstack community
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
from nova import compute
|
||||
from nova import exception
|
||||
from nova import flags
|
||||
@@ -81,8 +79,8 @@ class API(base.Base):
|
||||
vol_type['extra_specs'].get('drive_type') is None or
|
||||
vol_type['extra_specs'].get('drive_size') is None):
|
||||
|
||||
raise exception.ApiError(_("Invalid drive type %s")
|
||||
% vol_type['name'])
|
||||
msg = _("invalid drive data")
|
||||
raise exception.InvalidVolumeType(reason=msg)
|
||||
|
||||
def _get_default_vsa_instance_type(self):
|
||||
return instance_types.get_instance_type_by_name(
|
||||
@@ -104,13 +102,14 @@ class API(base.Base):
|
||||
num_disks = node.get('num_drives', 1)
|
||||
|
||||
if name is None:
|
||||
raise exception.ApiError(_("No drive_name param found in %s")
|
||||
% node)
|
||||
msg = _("drive_name not defined")
|
||||
raise exception.InvalidVolumeType(reason=msg)
|
||||
|
||||
try:
|
||||
vol_type = volume_types.get_volume_type_by_name(context, name)
|
||||
except exception.NotFound:
|
||||
raise exception.ApiError(_("Invalid drive type name %s")
|
||||
% name)
|
||||
msg = _("invalid drive type name %s")
|
||||
raise exception.InvalidVolumeType(reason=msg % name)
|
||||
|
||||
self._check_volume_type_correctness(vol_type)
|
||||
|
||||
@@ -177,13 +176,10 @@ class API(base.Base):
|
||||
# check if image is ready before starting any work
|
||||
if image_name is None:
|
||||
image_name = FLAGS.vc_image_name
|
||||
try:
|
||||
|
||||
image_service = self.compute_api.image_service
|
||||
vc_image = image_service.show_by_name(context, image_name)
|
||||
vc_image_href = vc_image['id']
|
||||
except exception.ImageNotFound:
|
||||
raise exception.ApiError(_("Failed to find configured image %s")
|
||||
% image_name)
|
||||
|
||||
options = {
|
||||
'display_name': display_name,
|
||||
@@ -198,10 +194,8 @@ class API(base.Base):
|
||||
LOG.info(_("Creating VSA: %s") % options)
|
||||
|
||||
# create DB entry for VSA instance
|
||||
try:
|
||||
vsa_ref = self.db.vsa_create(context, options)
|
||||
except exception.Error:
|
||||
raise exception.ApiError(_(sys.exc_info()[1]))
|
||||
|
||||
vsa_id = vsa_ref['id']
|
||||
vsa_name = vsa_ref['name']
|
||||
|
||||
@@ -209,10 +203,9 @@ class API(base.Base):
|
||||
try:
|
||||
volume_params = self._check_storage_parameters(context, vsa_name,
|
||||
storage, shared)
|
||||
except exception.ApiError:
|
||||
except exception.InvalidVolumeType:
|
||||
self.db.vsa_destroy(context, vsa_id)
|
||||
raise exception.ApiError(_("Error in storage parameters: %s")
|
||||
% storage)
|
||||
raise
|
||||
|
||||
# after creating DB entry, re-check and set some defaults
|
||||
updates = {}
|
||||
@@ -358,7 +351,7 @@ class API(base.Base):
|
||||
LOG.info(_("VSA ID %(vsa_id)s: Deleting %(direction)s "
|
||||
"volume %(vol_name)s"), locals())
|
||||
self.volume_api.delete(context, volume)
|
||||
except exception.ApiError:
|
||||
except exception.InvalidVolume:
|
||||
LOG.info(_("Unable to delete volume %s"), volume['name'])
|
||||
if force_delete:
|
||||
LOG.info(_("VSA ID %(vsa_id)s: Forced delete. "
|
||||
|
Reference in New Issue
Block a user