Don't do snapshot when other action in progress

According to the referenced bug report, snapshot and restore operations
are not checking the stack status. The result is that some duplicate or
orphan VMs left. This patch adds a check in snapshot operation that will
reject a snapshot request when it seems unsafe.

partial-bug: 1412952
Change-Id: I5b5da312ac08fd5f15418dd6cf9670463180d7ad
This commit is contained in:
tengqm 2015-01-28 11:17:39 +08:00
parent 12a717f926
commit 1c88c182f9
2 changed files with 20 additions and 0 deletions

View File

@ -1159,6 +1159,13 @@ class EngineService(service.Service):
s = self._get_stack(cnxt, stack_identity)
stack = parser.Stack.load(cnxt, stack=s)
if stack.status == stack.IN_PROGRESS:
LOG.info(_LI('%(stack)s is in state %(action)s_IN_PROGRESS, '
'snapshot is not permitted.'), {
'stack': six.text_type(stack),
'action': stack.action})
raise exception.ActionInProgress(stack_name=stack.name,
action=stack.action)
lock = stack_lock.StackLock(cnxt, stack, self.engine_id)

View File

@ -3555,6 +3555,7 @@ class SnapshotServiceTest(common.HeatTestCase):
s = db_api.stack_get(self.ctx, sid)
if stub:
self.m.StubOutWithMock(parser.Stack, 'load')
stack.state_set(stack.CREATE, stack.COMPLETE, 'mock completion')
parser.Stack.load(self.ctx, stack=s).MultipleTimes().AndReturn(stack)
return stack
@ -3584,6 +3585,18 @@ class SnapshotServiceTest(common.HeatTestCase):
self.assertIsNotNone(stack.updated_time)
self.assertIsNotNone(snapshot['creation_time'])
def test_create_snapshot_action_in_progress(self):
stack = self._create_stack()
self.m.ReplayAll()
stack.state_set(stack.UPDATE, stack.IN_PROGRESS, 'test_override')
ex = self.assertRaises(dispatcher.ExpectedException,
self.engine.stack_snapshot,
self.ctx, stack.identifier(), 'snap_none')
self.assertEqual(exception.ActionInProgress, ex.exc_info[0])
msg = ("Stack stack already has an action (%(action)s) "
"in progress.") % {'action': stack.action}
self.assertEqual(msg, six.text_type(ex.exc_info[1]))
def test_delete_snapshot_not_found(self):
stack = self._create_stack()
self.m.ReplayAll()