Implement handle_<action>_cancel for SoftwareDeployment

This implements handle_<action>_cancel for SoftwareDeployment
to update the deployment to failed, when the resource fails due
to scheduler timeout or some other external reason.

Change-Id: Ibaa551d35e96f34cf950811a5b5a05e1cda6c364
Closes-Bug: #1585815
This commit is contained in:
rabi 2017-07-10 16:40:12 +05:30
parent 1591acaf1f
commit 199e4ac322
4 changed files with 87 additions and 4 deletions

View File

@ -507,6 +507,38 @@ class SoftwareDeployment(signal_responder.SignalResponder):
self.context, self.resource_id, details,
timeutils.utcnow().isoformat())
def _handle_cancel(self):
if self.resource_id is None:
return
sd = self.rpc_client().show_software_deployment(
self.context, self.resource_id)
if sd is None:
return
status = sd[rpc_api.SOFTWARE_DEPLOYMENT_STATUS]
if status == SoftwareDeployment.IN_PROGRESS:
self.rpc_client().update_software_deployment(
self.context, self.resource_id,
status=SoftwareDeployment.FAILED,
status_reason=_('Deployment cancelled.'))
def handle_create_cancel(self, cookie):
self._handle_cancel()
def handle_update_cancel(self, cookie):
self._handle_cancel()
def handle_delete_cancel(self, cookie):
self._handle_cancel()
def handle_suspend_cancel(self, cookie):
self._handle_cancel()
def handle_resume_cancel(self, cookie):
self._handle_cancel()
def get_attribute(self, key, *path):
"""Resource attributes map to deployment outputs values."""
sd = self.rpc_client().show_software_deployment(

View File

@ -685,6 +685,29 @@ class SoftwareDeploymentTest(common.HeatTestCase):
self.assertEqual(
'Deployment to server failed: something wrong', six.text_type(err))
def test_handle_create_cancel(self):
self._create_stack(self.template)
mock_sd = self.mock_deployment()
self.rpc_client.show_software_deployment.return_value = mock_sd
self.deployment.resource_id = 'c8a19429-7fde-47ea-a42f-40045488226c'
# status in_progress
mock_sd['status'] = self.deployment.IN_PROGRESS
self.deployment.handle_create_cancel(None)
self.assertEqual(
'FAILED',
self.rpc_client.update_software_deployment.call_args[1]['status'])
# status failed
mock_sd['status'] = self.deployment.FAILED
self.deployment.handle_create_cancel(None)
# deployment not created
mock_sd = None
self.deployment.handle_create_cancel(None)
self.assertEqual(1,
self.rpc_client.update_software_deployment.call_count)
def test_handle_delete(self):
self._create_stack(self.template)
mock_sd = self.mock_deployment()

View File

@ -551,12 +551,13 @@ class HeatIntegrationTest(testscenarios.WithScenarios,
parameters=None, environment=None, tags=None,
expected_status='CREATE_COMPLETE',
disable_rollback=True, enable_cleanup=True,
environment_files=None):
environment_files=None, timeout=None):
name = stack_name or self._stack_rand_name()
templ = template or self.template
templ_files = files or {}
params = parameters or {}
env = environment or {}
timeout_mins = timeout or self.conf.build_timeout
self.client.stacks.create(
stack_name=name,
template=templ,
@ -565,7 +566,8 @@ class HeatIntegrationTest(testscenarios.WithScenarios,
parameters=params,
environment=env,
tags=tags,
environment_files=environment_files
environment_files=environment_files,
timeout_mins=timeout_mins
)
if expected_status not in ['ROLLBACK_COMPLETE'] and enable_cleanup:
self.addCleanup(self._stack_delete, name)

View File

@ -22,6 +22,7 @@ import yaml
from oslo_utils import timeutils
from heat_integrationtests.common import exceptions
from heat_integrationtests.common import test
from heat_integrationtests.functional import functional_base
@ -101,6 +102,30 @@ properties:
for config_stack in config_stacks:
self._wait_for_stack_status(config_stack, 'CREATE_COMPLETE')
def test_deployments_timeout_failed(self):
parms = {'flavor': self.conf.minimal_instance_type,
'network': self.conf.fixed_network_name,
'image': self.conf.minimal_image_ref}
stack_identifier = self.stack_create(
parameters=parms,
template=self.server_template,
enable_cleanup=self.enable_cleanup)
server_stack = self.client.stacks.get(stack_identifier)
server = server_stack.outputs[0]['output_value']
config_stack = self.deploy_config(server, 3, 1)
self._wait_for_stack_status(config_stack, 'CREATE_FAILED')
kwargs = {'server_id': server}
def check_deployment_status():
sd_list = self.client.software_deployments.list(**kwargs)
for sd in sd_list:
if sd.status != 'FAILED':
return False
return True
self.assertTrue(test.call_until_true(
20, 0, check_deployment_status))
def deploy_many_configs(self, stack, server, config_stacks,
stack_count, deploys_per_stack,
deploy_count_start):
@ -112,7 +137,7 @@ properties:
self.wait_for_deploy_metadata_set(stack, new_count)
return new_count
def deploy_config(self, server, deploy_count):
def deploy_config(self, server, deploy_count, timeout=None):
parms = {'server': server}
template = yaml.safe_load(self.config_template)
resources = template['resources']
@ -123,7 +148,8 @@ properties:
parameters=parms,
template=template,
enable_cleanup=self.enable_cleanup,
expected_status=None)
expected_status=None,
timeout=timeout)
def wait_for_deploy_metadata_set(self, stack, deploy_count):
build_timeout = self.conf.build_timeout