diff --git a/tripleoclient/tests/fixture_data/deployment.py b/tripleoclient/tests/fixture_data/deployment.py index ee9d864bc..77729f1bd 100644 --- a/tripleoclient/tests/fixture_data/deployment.py +++ b/tripleoclient/tests/fixture_data/deployment.py @@ -32,6 +32,9 @@ class DeploymentWorkflowFixture(fixtures.Fixture): self.mock_get_horizon_url = self.useFixture(fixtures.MockPatch( 'tripleoclient.workflows.deployment.get_horizon_url') ).mock + self.mock_set_deployment_status = self.useFixture(fixtures.MockPatch( + 'tripleoclient.workflows.deployment.set_deployment_status') + ).mock class PlanManagementFixture(fixtures.Fixture): diff --git a/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py b/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py index aabad70bc..51fa5bc55 100644 --- a/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py +++ b/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py @@ -1533,6 +1533,10 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): self.assertTrue(fixture.mock_enable_ssh_admin.called) self.assertTrue(fixture.mock_get_overcloud_hosts.called) self.assertTrue(fixture.mock_config_download.called) + self.assertTrue(fixture.mock_set_deployment_status.called) + self.assertEqual( + 'deploying', + fixture.mock_set_deployment_status.call_args[0][1]) @mock.patch('tripleoclient.utils.create_tempest_deployer_input', autospec=True) @@ -1565,6 +1569,51 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): self.assertTrue(fixture.mock_enable_ssh_admin.called) self.assertTrue(fixture.mock_get_overcloud_hosts.called) self.assertTrue(fixture.mock_config_download.called) + self.assertTrue(fixture.mock_set_deployment_status.called) + self.assertEqual( + 'deploying', + fixture.mock_set_deployment_status.call_args[0][1]) + + @mock.patch('tripleoclient.utils.create_tempest_deployer_input', + autospec=True) + @mock.patch('tripleoclient.utils.get_overcloud_endpoint', autospec=True) + @mock.patch('tripleoclient.utils.write_overcloudrc', autospec=True) + @mock.patch('tripleoclient.workflows.deployment.create_overcloudrc', + autospec=True) + @mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.' + '_deploy_tripleo_heat_templates_tmpdir', autospec=True) + def test_config_download_fails( + self, mock_deploy_tmpdir, + mock_overcloudrc, mock_write_overcloudrc, + mock_overcloud_endpoint, + mock_create_tempest_deployer_input): + fixture = deployment.DeploymentWorkflowFixture() + self.useFixture(fixture) + clients = self.app.client_manager + orchestration_client = clients.orchestration + orchestration_client.stacks.get.return_value = mock.Mock() + + arglist = ['--templates', '--config-download-only'] + verifylist = [ + ('templates', '/usr/share/openstack-tripleo-heat-templates/'), + ('config_download_only', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + fixture.mock_config_download.side_effect = \ + exceptions.DeploymentError('fails') + self.assertRaises( + exceptions.DeploymentError, + self.cmd.take_action, + parsed_args) + self.assertFalse(mock_deploy_tmpdir.called) + self.assertTrue(fixture.mock_enable_ssh_admin.called) + self.assertTrue(fixture.mock_get_overcloud_hosts.called) + self.assertTrue(fixture.mock_config_download.called) + self.assertTrue(fixture.mock_set_deployment_status.called) + self.assertEqual( + 'failed', + fixture.mock_set_deployment_status.call_args[0][1]) @mock.patch('tripleoclient.workflows.deployment.get_overcloud_hosts') @mock.patch('tripleoclient.workflows.deployment.enable_ssh_admin') diff --git a/tripleoclient/v1/overcloud_deploy.py b/tripleoclient/v1/overcloud_deploy.py index 987547ddf..0a82f63c6 100644 --- a/tripleoclient/v1/overcloud_deploy.py +++ b/tripleoclient/v1/overcloud_deploy.py @@ -899,30 +899,40 @@ class DeployOvercloud(command.Command): if parsed_args.config_download: print("Deploying overcloud configuration") + deployment.set_deployment_status( + self.clients, 'deploying', + plan=stack.stack_name) - hosts = deployment.get_overcloud_hosts( - stack, parsed_args.overcloud_ssh_network) - deployment.enable_ssh_admin(self.log, self.clients, - stack.stack_name, - hosts, - parsed_args.overcloud_ssh_user, - parsed_args.overcloud_ssh_key) + try: + hosts = deployment.get_overcloud_hosts( + stack, parsed_args.overcloud_ssh_network) + deployment.enable_ssh_admin( + self.log, self.clients, + stack.stack_name, + hosts, + parsed_args.overcloud_ssh_user, + parsed_args.overcloud_ssh_key) - if parsed_args.config_download_timeout: - timeout = parsed_args.config_download_timeout * 60 - else: - used = int(time.time() - start) - timeout = (parsed_args.timeout * 60) - used + if parsed_args.config_download_timeout: + timeout = parsed_args.config_download_timeout * 60 + else: + used = int(time.time() - start) + timeout = (parsed_args.timeout * 60) - used - deployment.config_download(self.log, self.clients, stack, - parsed_args.templates, - parsed_args.overcloud_ssh_user, - parsed_args.overcloud_ssh_key, - parsed_args.overcloud_ssh_network, - parsed_args.output_dir, - parsed_args.override_ansible_cfg, - timeout, - verbosity=self.app_args.verbose_level) + deployment.config_download( + self.log, self.clients, stack, + parsed_args.templates, parsed_args.overcloud_ssh_user, + parsed_args.overcloud_ssh_key, + parsed_args.overcloud_ssh_network, + parsed_args.output_dir, + parsed_args.override_ansible_cfg, + timeout, + verbosity=self.app_args.verbose_level) + except Exception: + deployment.set_deployment_status( + self.clients, 'failed', + plan=stack.stack_name) + raise # Force fetching of attributes stack.get() diff --git a/tripleoclient/workflows/deployment.py b/tripleoclient/workflows/deployment.py index 810e994b7..1e9a72ace 100644 --- a/tripleoclient/workflows/deployment.py +++ b/tripleoclient/workflows/deployment.py @@ -100,6 +100,7 @@ def deploy_and_wait(log, clients, stack, plan_name, verbose_level, orchestration_client, plan_name, marker, action, verbose_events) if not create_result: shell.OpenStackShell().run(["stack", "failures", "list", plan_name]) + set_deployment_status(clients, 'failed', plan=plan_name) if stack is None: raise exceptions.DeploymentError("Heat Stack create failed.") else: @@ -345,6 +346,37 @@ def get_deployment_status(clients, **workflow_input): payload.get('message', ''))) +def set_deployment_status(clients, status='success', **workflow_input): + workflow_client = clients.workflow_engine + tripleoclients = clients.tripleoclient + + if status == 'success': + workflow = 'tripleo.deployment.v1.set_deployment_status_success' + elif status == 'failed': + workflow = 'tripleo.deployment.v1.set_deployment_status_failed' + elif status == 'deploying': + workflow = 'tripleo.deployment.v1.set_deployment_status_deploying' + else: + raise Exception("Can't set unknown deployment status: %s" % status) + + with tripleoclients.messaging_websocket() as ws: + execution = base.start_workflow( + workflow_client, + workflow, + workflow_input=workflow_input + ) + + for payload in base.wait_for_messages(workflow_client, ws, execution, + _WORKFLOW_TIMEOUT): + # Just continue until workflow is done + continue + + if payload['status'] != 'SUCCESS': + raise exceptions.WorkflowServiceError( + 'Exception setting deployment status: {}'.format( + payload.get('message', ''))) + + def get_deployment_failures(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient