Propagate creation errors with exceptions

Change-Id: I567f1901e1203930d282620112368ac32440b9ed
This commit is contained in:
Zane Bitter 2013-04-23 13:36:47 +02:00
parent f3be3d90b3
commit 9e90af14cf
8 changed files with 40 additions and 23 deletions

View File

@ -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")

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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):

View File

@ -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)

View File

@ -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()