restore: update success only upon heat complete

Currently, immediatelly after heat stack has been created, status is
updated to success, without waiting for the stack result.
Instead, set the success status only after heat stack finished
successfully.

Change-Id: I60c795ec547070b7d53f31fbd7865c573efe4433
This commit is contained in:
Yuval Brik 2016-10-09 17:20:32 +03:00
parent 64bba9e99e
commit 5a523b2cb7
4 changed files with 32 additions and 25 deletions

View File

@ -269,21 +269,19 @@ class RestoresController(wsgi.Controller):
LOG.debug('call restore RPC : restoreobj:%s', restoreobj)
# call restore rpc API of protection service
result = self.protection_api.restore(context, restoreobj, restore_auth)
if result is True:
status_update = constants.OPERATION_EXE_STATE_SUCCESS
else:
try:
self.protection_api.restore(context, restoreobj, restore_auth)
except Exception:
status_update = constants.OPERATION_EXE_STATE_FAILED
# update the status of restore
update_dict = {
"status": status_update
}
# update the status of restore
update_dict = {
"status": status_update
}
check_policy(context, 'update', restoreobj)
restoreobj = self._restore_update(context,
restoreobj.get("id"),
update_dict)
check_policy(context, 'update', restoreobj)
self._restore_update(context,
restoreobj.get("id"), update_dict)
restoreobj.update(update_dict)
retval = self._view_builder.detail(req, restoreobj)
return retval
@ -313,6 +311,7 @@ class RestoresController(wsgi.Controller):
restore.update(fields)
restore.save()
LOG.info(_LI("restore updated successfully."))
return restore
else:
msg = _("The parameter restore must be a object of "
"KarborObject class.")

View File

@ -16,6 +16,7 @@ from oslo_config import cfg
from oslo_log import log as logging
from oslo_service import loopingcall
from karbor.common import constants
from karbor.i18n import _LE, _LI
from karbor.services.protection.client_factory import ClientFactory
from karbor.services.protection.restore_heat import HeatTemplate
@ -42,7 +43,7 @@ class CreateStackTask(task.Task):
def execute(self):
stack_name = "restore_%s" % str(uuid4())
LOG.info(_LI("creating stack, stack_name: %s"), stack_name)
LOG.info(_LI("creating stack, stack_name:%s"), stack_name)
try:
body = self._heat_client.stacks.create(
stack_name=stack_name,
@ -54,11 +55,12 @@ class CreateStackTask(task.Task):
class SyncStackStatusTask(task.Task):
def __init__(self, checkpoint, heat_client):
def __init__(self, checkpoint, heat_client, restore):
requires = ['stack_id']
super(SyncStackStatusTask, self).__init__(requires=requires)
self._heat_client = heat_client
self._checkpoint = checkpoint
self._restore = restore
def execute(self, stack_id):
LOG.info(_LI("syncing stack status, stack_id: %s"), stack_id)
@ -73,6 +75,16 @@ class SyncStackStatusTask(task.Task):
if stack_status == 'CREATE_IN_PROGRESS':
return
if stack_status == 'CREATE_FAILED':
status = constants.OPERATION_EXE_STATE_FAILED
elif stack_status == 'CREATE_COMPLETE':
status = constants.OPERATION_EXE_STATE_SUCCESS
status_dict = {
"status": status
}
self._restore.update(status_dict)
self._restore.save()
raise loopingcall.LoopingCallDone()
except Exception:
LOG.info(_LI("stop sync stack status, stack_id: %s"), stack_id)
@ -109,9 +121,11 @@ def get_flow(context, workflow_engine, operation_type, checkpoint, provider,
restoration_flow = workflow_engine.build_flow(flow_name, 'linear')
result = provider.build_task_flow(ctx)
resource_flow = result.get('task_flow')
workflow_engine.add_tasks(restoration_flow,
resource_flow,
CreateStackTask(heat_client, heat_template),
SyncStackStatusTask(checkpoint, heat_client))
workflow_engine.add_tasks(
restoration_flow,
resource_flow,
CreateStackTask(heat_client, heat_template),
SyncStackStatusTask(checkpoint, heat_client, restore)
)
flow_engine = workflow_engine.get_engine(restoration_flow)
return flow_engine

View File

@ -150,7 +150,6 @@ class ProtectionManager(manager.Manager):
error=_("Failed to create flow"))
try:
self.worker.run_flow(restoration_flow)
return True
except Exception:
LOG.exception(
_LE("Failed to run restoration flow checkpoint: %s"),

View File

@ -45,20 +45,15 @@ class RestoreApiTest(base.TestCase):
@mock.patch(
'karbor.services.protection.api.API.restore')
@mock.patch(
'karbor.api.v1.restores.'
'RestoresController._restore_update')
@mock.patch(
'karbor.objects.restore.Restore.create')
def test_restore_create(self, mock_restore_create,
mock_restore_update,
mock_rpc_restore):
restore = self._restore_in_request_body()
body = {"restore": restore}
req = fakes.HTTPRequest.blank('/v1/restores')
self.controller.create(req, body)
self.assertTrue(mock_restore_create.called)
self.assertTrue(mock_restore_update.called)
self.assertTrue(mock_rpc_restore.called)
def test_restore_create_InvalidBody(self):