Propagate creation errors with exceptions
Change-Id: I567f1901e1203930d282620112368ac32440b9ed
This commit is contained in:
parent
f3be3d90b3
commit
9e90af14cf
|
@ -246,5 +246,17 @@ class WatchRuleNotFound(OpenstackException):
|
||||||
message = _("The Watch Rule (%(watch_name)s) could not be found.")
|
message = _("The Watch Rule (%(watch_name)s) could not be found.")
|
||||||
|
|
||||||
|
|
||||||
|
class ResourceFailure(OpenstackException):
|
||||||
|
message = _("%(exc_type)s: %(message)s")
|
||||||
|
|
||||||
|
def __init__(self, exception):
|
||||||
|
if isinstance(exception, ResourceFailure):
|
||||||
|
exception = getattr(exception, 'exc', exception)
|
||||||
|
self.exc = exception
|
||||||
|
exc_type = type(exception).__name__
|
||||||
|
super(ResourceFailure, self).__init__(exc_type=exc_type,
|
||||||
|
message=str(exception))
|
||||||
|
|
||||||
|
|
||||||
class NestedResourceFailure(OpenstackException):
|
class NestedResourceFailure(OpenstackException):
|
||||||
message = _("%(message)s")
|
message = _("%(message)s")
|
||||||
|
|
|
@ -275,12 +275,12 @@ class Stack(object):
|
||||||
try:
|
try:
|
||||||
for res in self:
|
for res in self:
|
||||||
if stack_status != self.CREATE_FAILED:
|
if stack_status != self.CREATE_FAILED:
|
||||||
result = res.create()
|
try:
|
||||||
if result:
|
res.create()
|
||||||
|
except exception.ResourceFailure as ex:
|
||||||
stack_status = self.CREATE_FAILED
|
stack_status = self.CREATE_FAILED
|
||||||
reason = 'Resource %s failed with: %s' % (str(res),
|
reason = 'Resource %s failed with: %s' % (str(res),
|
||||||
result)
|
str(ex))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
res.state_set(res.CREATE_FAILED,
|
res.state_set(res.CREATE_FAILED,
|
||||||
'Stack creation aborted')
|
'Stack creation aborted')
|
||||||
|
@ -366,10 +366,11 @@ class Stack(object):
|
||||||
self[res.name] = res
|
self[res.name] = res
|
||||||
self.dependencies = self._get_dependencies(
|
self.dependencies = self._get_dependencies(
|
||||||
self.resources.itervalues())
|
self.resources.itervalues())
|
||||||
result = self[res.name].create()
|
try:
|
||||||
if result:
|
self[res.name].create()
|
||||||
|
except exception.ResourceFailure as ex:
|
||||||
logger.error("Failed to add %s : %s" %
|
logger.error("Failed to add %s : %s" %
|
||||||
(res.name, result))
|
(res.name, str(ex)))
|
||||||
raise exception.ResourceUpdateFailed(
|
raise exception.ResourceUpdateFailed(
|
||||||
resource_name=res.name)
|
resource_name=res.name)
|
||||||
|
|
||||||
|
@ -418,10 +419,11 @@ class Stack(object):
|
||||||
self[res.name] = res
|
self[res.name] = res
|
||||||
self.dependencies = self._get_dependencies(
|
self.dependencies = self._get_dependencies(
|
||||||
self.resources.itervalues())
|
self.resources.itervalues())
|
||||||
result = self[res.name].create()
|
try:
|
||||||
if result:
|
self[res.name].create()
|
||||||
|
except exception.ResourceFailure as ex:
|
||||||
logger.error("Failed to create %s : %s" %
|
logger.error("Failed to create %s : %s" %
|
||||||
(res.name, result))
|
(res.name, str(ex)))
|
||||||
raise exception.ResourceUpdateFailed(
|
raise exception.ResourceUpdateFailed(
|
||||||
resource_name=res.name)
|
resource_name=res.name)
|
||||||
else:
|
else:
|
||||||
|
@ -541,7 +543,7 @@ class Stack(object):
|
||||||
if not failed:
|
if not failed:
|
||||||
try:
|
try:
|
||||||
res.create()
|
res.create()
|
||||||
except Exception as ex:
|
except exception.ResourceFailure as ex:
|
||||||
logger.exception('create')
|
logger.exception('create')
|
||||||
failed = True
|
failed = True
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -324,8 +324,9 @@ class Resource(object):
|
||||||
raise
|
raise
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.exception('create %s', str(self))
|
logger.exception('create %s', str(self))
|
||||||
self.state_set(self.CREATE_FAILED, str(ex))
|
failure = exception.ResourceFailure(ex)
|
||||||
return str(ex) or "Error : %s" % type(ex)
|
self.state_set(self.CREATE_FAILED, str(failure))
|
||||||
|
raise failure
|
||||||
else:
|
else:
|
||||||
self.state_set(self.CREATE_COMPLETE)
|
self.state_set(self.CREATE_COMPLETE)
|
||||||
|
|
||||||
|
|
|
@ -192,9 +192,11 @@ class InstanceGroup(resource.Resource):
|
||||||
self.resource_id_set(','.join(inst_list))
|
self.resource_id_set(','.join(inst_list))
|
||||||
logger.info('Creating Autoscaling instance %s' % name)
|
logger.info('Creating Autoscaling instance %s' % name)
|
||||||
|
|
||||||
error_str = inst.create()
|
try:
|
||||||
if raise_on_error and error_str is not None:
|
inst.create()
|
||||||
raise exception.NestedResourceFailure(message=error_str)
|
except exception.ResourceFailure as ex:
|
||||||
|
if raise_on_error:
|
||||||
|
raise
|
||||||
|
|
||||||
return inst
|
return inst
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ class InstanceGroupTest(unittest.TestCase):
|
||||||
|
|
||||||
self.m.ReplayAll()
|
self.m.ReplayAll()
|
||||||
|
|
||||||
self.assertNotEqual(resource.create(), None)
|
self.assertRaises(exception.ResourceFailure, resource.create)
|
||||||
self.assertEqual(asc.InstanceGroup.CREATE_FAILED, resource.state)
|
self.assertEqual(asc.InstanceGroup.CREATE_FAILED, resource.state)
|
||||||
|
|
||||||
self.m.VerifyAll()
|
self.m.VerifyAll()
|
||||||
|
|
|
@ -242,7 +242,7 @@ class ResourceTest(unittest.TestCase):
|
||||||
res = generic_rsrc.GenericResource(rname, tmpl, self.stack)
|
res = generic_rsrc.GenericResource(rname, tmpl, self.stack)
|
||||||
|
|
||||||
estr = 'Property error : test_resource: Property Foo not assigned'
|
estr = 'Property error : test_resource: Property Foo not assigned'
|
||||||
self.assertEqual(estr, res.create())
|
self.assertRaises(exception.ResourceFailure, res.create)
|
||||||
self.assertEqual(res.CREATE_FAILED, res.state)
|
self.assertEqual(res.CREATE_FAILED, res.state)
|
||||||
|
|
||||||
def test_create_fail_prop_typo(self):
|
def test_create_fail_prop_typo(self):
|
||||||
|
@ -255,7 +255,7 @@ class ResourceTest(unittest.TestCase):
|
||||||
res = generic_rsrc.GenericResource(rname, tmpl, self.stack)
|
res = generic_rsrc.GenericResource(rname, tmpl, self.stack)
|
||||||
|
|
||||||
estr = 'Property error : test_resource: Property Foo not assigned'
|
estr = 'Property error : test_resource: Property Foo not assigned'
|
||||||
self.assertEqual(estr, res.create())
|
self.assertRaises(exception.ResourceFailure, res.create)
|
||||||
self.assertEqual(res.CREATE_FAILED, res.state)
|
self.assertEqual(res.CREATE_FAILED, res.state)
|
||||||
|
|
||||||
def test_update_ok(self):
|
def test_update_ok(self):
|
||||||
|
|
|
@ -329,8 +329,7 @@ class AccessKeyTest(unittest.TestCase):
|
||||||
resource = user.AccessKey('HostKeys',
|
resource = user.AccessKey('HostKeys',
|
||||||
t['Resources']['HostKeys'],
|
t['Resources']['HostKeys'],
|
||||||
stack)
|
stack)
|
||||||
self.assertEqual('could not find user test_stack.NoExist',
|
self.assertRaises(exception.ResourceFailure, resource.create)
|
||||||
resource.create())
|
|
||||||
self.assertEqual(user.AccessKey.CREATE_FAILED,
|
self.assertEqual(user.AccessKey.CREATE_FAILED,
|
||||||
resource.state)
|
resource.state)
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import unittest
|
||||||
from nose.plugins.attrib import attr
|
from nose.plugins.attrib import attr
|
||||||
|
|
||||||
from heat.common import context
|
from heat.common import context
|
||||||
|
from heat.common import exception
|
||||||
from heat.common import template_format
|
from heat.common import template_format
|
||||||
from heat.engine import parser
|
from heat.engine import parser
|
||||||
from heat.engine.resources import volume as vol
|
from heat.engine.resources import volume as vol
|
||||||
|
@ -147,7 +148,7 @@ class VolumeTest(unittest.TestCase):
|
||||||
resource = vol.Volume('DataVolume',
|
resource = vol.Volume('DataVolume',
|
||||||
t['Resources']['DataVolume'],
|
t['Resources']['DataVolume'],
|
||||||
stack)
|
stack)
|
||||||
self.assertEqual(resource.create(), 'error')
|
self.assertRaises(exception.ResourceFailure, resource.create)
|
||||||
|
|
||||||
self.m.VerifyAll()
|
self.m.VerifyAll()
|
||||||
|
|
||||||
|
@ -184,7 +185,7 @@ class VolumeTest(unittest.TestCase):
|
||||||
resource = vol.VolumeAttachment('MountPoint',
|
resource = vol.VolumeAttachment('MountPoint',
|
||||||
t['Resources']['MountPoint'],
|
t['Resources']['MountPoint'],
|
||||||
stack)
|
stack)
|
||||||
self.assertEqual(resource.create(), 'error')
|
self.assertRaises(exception.ResourceFailure, resource.create)
|
||||||
|
|
||||||
self.m.VerifyAll()
|
self.m.VerifyAll()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue