Allow plugins to specify signal event reason

Currently, we have logic in the Resource.signal base-class implementation
which works out the reason string based on knowledge of some of the
signal-handling resources.  This is invariably going to be fragile, and it
won't work at all with any out of tree or contrib plugins.

So instead, move towards a model where we accept an optional return value from
handle_signal, and use that as the reason string instead.  Since no resources
yet return a reason, maintain the old logic as a fallback path, until this
gets migrated into the appropriate resources.

Change-Id: I45fdf112e6cd050bb1f4111977f653ba6440df02
Partial-Bug: #1340894
This commit is contained in:
Steven Hardy 2014-07-11 20:48:45 +01:00
parent 720f88cd8b
commit fc676986b7
2 changed files with 30 additions and 2 deletions

View File

@ -897,8 +897,12 @@ class Resource(object):
str(self)) str(self))
raise Exception(msg) raise Exception(msg)
self._add_event('signal', self.status, get_string_details()) signal_result = self.handle_signal(details)
self.handle_signal(details) if signal_result:
reason_string = "Signal: %s" % signal_result
else:
reason_string = get_string_details()
self._add_event('signal', self.status, reason_string)
except Exception as ex: except Exception as ex:
LOG.exception(_('signal %(name)s : %(msg)s') % {'name': str(self), LOG.exception(_('signal %(name)s : %(msg)s') % {'name': str(self),
'msg': ex}) 'msg': ex})

View File

@ -297,6 +297,30 @@ class SignalTest(HeatTestCase):
self.m.VerifyAll() self.m.VerifyAll()
def test_signal_plugin_reason(self):
# Ensure if handle_signal returns data, we use it as the reason
self.stack = self.create_stack()
self.stack.create()
rsrc = self.stack['signal_handler']
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.m.StubOutWithMock(generic_resource.SignalResource,
'handle_signal')
signal_details = {'status': 'COMPLETE'}
ret_expected = "Received COMPLETE signal"
generic_resource.SignalResource.handle_signal(
signal_details).AndReturn(ret_expected)
self.m.StubOutWithMock(generic_resource.SignalResource,
'_add_event')
generic_resource.SignalResource._add_event(
'signal', 'COMPLETE', 'Signal: %s' % ret_expected).AndReturn(None)
self.m.ReplayAll()
rsrc.signal(details=signal_details)
self.m.VerifyAll()
def test_signal_wrong_resource(self): def test_signal_wrong_resource(self):
# assert that we get the correct exception when calling a # assert that we get the correct exception when calling a
# resource.signal() that does not have a handle_signal() # resource.signal() that does not have a handle_signal()