From 2843b447dc7f5860015e8b24b7dffa25758f9bfb Mon Sep 17 00:00:00 2001 From: James Slagle Date: Tue, 15 Mar 2022 10:32:29 -0400 Subject: [PATCH] Consolidate ephemeral Heat interaction to single try/finally Ephemeral Heat interaction was spread across several areas of the overcloud deploy, including the entire config-download execution. To reduce the amount of time that ephemeral Heat needs to stay running, consolidate all the Heat interaction to a single try/finally block. The overcloud export is moved earlier in the execution since it no longer requires Heat API access. This also makes the shutdown of ephemeral Heat and database backup in just a single location. Change-Id: Ia424b2eb251b2d31a97256b5e8882c70058d6a0b Signed-off-by: James Slagle --- tripleoclient/constants.py | 1 + tripleoclient/tests/test_utils.py | 13 ++-- .../overcloud_deploy/test_overcloud_deploy.py | 2 +- tripleoclient/utils.py | 11 +--- tripleoclient/v1/overcloud_deploy.py | 62 ++++++++++--------- tripleoclient/v1/tripleo_deploy.py | 2 +- 6 files changed, 44 insertions(+), 47 deletions(-) diff --git a/tripleoclient/constants.py b/tripleoclient/constants.py index 86b71f74f..ea1667239 100644 --- a/tripleoclient/constants.py +++ b/tripleoclient/constants.py @@ -89,6 +89,7 @@ STACK_OUTPUTS = ['BlacklistedHostnames', 'RoleNetIpMap', 'BlacklistedIpAddresses', 'RoleNetHostnameMap', + 'KeystoneAdminVip', 'KeystoneRegion', 'KeystoneURL', 'EndpointMap', diff --git a/tripleoclient/tests/test_utils.py b/tripleoclient/tests/test_utils.py index 9313385d0..4f6a521fb 100644 --- a/tripleoclient/tests/test_utils.py +++ b/tripleoclient/tests/test_utils.py @@ -1090,15 +1090,12 @@ class TestGetStackOutputItem(TestCase): class TestGetEndpointMap(TestCase): - def test_get_endpoint_map(self): - stack = mock.MagicMock() + @mock.patch('tripleoclient.utils.get_stack_saved_output_item') + def test_get_endpoint_map(self, mock_saved_output_item): + working_dir = mock.Mock() emap = {'KeystonePublic': {'uri': 'http://foo:8000/'}} - stack.to_dict.return_value = { - 'outputs': [{'output_key': 'EndpointMap', - 'output_value': emap}] - } - - endpoint_map = utils.get_endpoint_map(stack) + mock_saved_output_item.return_value = emap + endpoint_map = utils.get_endpoint_map(working_dir) self.assertEqual(endpoint_map, {'KeystonePublic': {'uri': 'http://foo:8000/'}}) diff --git a/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py b/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py index 5c98de1f7..942803aa0 100644 --- a/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py +++ b/tripleoclient/tests/v1/overcloud_deploy/test_overcloud_deploy.py @@ -1406,7 +1406,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud): 'region': 'region1'} # assuming heat deploy consumed a 3m out of total 451m timeout with mock.patch('time.time', side_effect=[1585820346, - 12345678, 0, + 0, 12345678, 0, 1585820526, 0, 0, 0, 0]): self.cmd.take_action(parsed_args) diff --git a/tripleoclient/utils.py b/tripleoclient/utils.py index 6cb6a0deb..f1c51e52a 100644 --- a/tripleoclient/utils.py +++ b/tripleoclient/utils.py @@ -992,8 +992,8 @@ def get_service_ips(stack): return service_ips -def get_endpoint_map(stack): - endpoint_map = get_stack_output_item(stack, 'EndpointMap') +def get_endpoint_map(working_dir): + endpoint_map = get_stack_saved_output_item('EndpointMap', working_dir) if not endpoint_map: endpoint_map = {} return endpoint_map @@ -1009,13 +1009,6 @@ def get_role_net_ip_map(working_dir): 'RoleNetIpMap', working_dir) -def get_endpoint(key, stack): - endpoint_map = get_endpoint_map(stack) - if endpoint_map: - return endpoint_map[key]['host'] - return get_service_ips(stack).get(key + 'Vip') - - def get_stack(orchestration_client, stack_name): """Get the ID for the current deployed overcloud stack if it exists. diff --git a/tripleoclient/v1/overcloud_deploy.py b/tripleoclient/v1/overcloud_deploy.py index f57ada645..d467b5aee 100644 --- a/tripleoclient/v1/overcloud_deploy.py +++ b/tripleoclient/v1/overcloud_deploy.py @@ -429,7 +429,7 @@ class DeployOvercloud(command.Command): messages = 'Failed to deploy: %s' % str(e) raise ValueError(messages) - def _deploy_postconfig(self, stack, parsed_args): + def _deploy_postconfig(self, parsed_args): self.log.debug("_deploy_postconfig(%s)" % parsed_args) overcloud_endpoint = utils.get_overcloud_endpoint(self.working_dir) @@ -1149,14 +1149,22 @@ class DeployOvercloud(command.Command): # a full deployment do_config_download = parsed_args.config_download_only or full_deploy - if ephemeral_heat and do_stack: - self.setup_ephemeral_heat(parsed_args) - config_download_dir = parsed_args.output_dir or \ os.path.join(self.working_dir, "config-download") + horizon_url = None + overcloud_endpoint = None + old_rcpath = None + rcpath = None + # All code within this "try" block requires Heat, and no other code + # outside the block should require Heat. With ephemeral Heat, the Heat + # pods will be cleaned up in the "finally" clause, such that it's not + # running during later parts of overcloud deploy. try: if do_stack: + if ephemeral_heat: + self.setup_ephemeral_heat(parsed_args) + self.deploy_tripleo_heat_templates( stack, parsed_args, new_tht_root, user_tht_root, created_env_files) @@ -1166,6 +1174,26 @@ class DeployOvercloud(command.Command): utils.save_stack_outputs( self.orchestration_client, stack, self.working_dir) + horizon_url = deployment.get_horizon_url( + stack=stack.stack_name, + heat_type=parsed_args.heat_type, + working_dir=self.working_dir) + + overcloud_endpoint = utils.get_overcloud_endpoint( + self.working_dir) + overcloud_admin_vip = utils.get_stack_saved_output_item( + 'KeystoneAdminVip', self.working_dir) + rc_params = utils.get_rc_params(self.working_dir) + + # For backwards compatibility, we will also write overcloudrc + # to $HOME and then self.working_dir. + old_rcpath = deployment.create_overcloudrc( + parsed_args.stack, overcloud_endpoint, overcloud_admin_vip, + rc_params, parsed_args.no_proxy) + rcpath = deployment.create_overcloudrc( + parsed_args.stack, overcloud_endpoint, overcloud_admin_vip, + rc_params, parsed_args.no_proxy, self.working_dir) + # Download config config_dir = parsed_args.config_dir or config_download_dir config_type = parsed_args.config_type @@ -1198,35 +1226,13 @@ class DeployOvercloud(command.Command): extra_vars=extra_vars ) - except (KeyboardInterrupt, Exception): + finally: if parsed_args.heat_type != 'installed' and self.heat_launcher: self.log.info("Stopping ephemeral heat.") utils.kill_heat(self.heat_launcher) utils.rm_heat(self.heat_launcher, backup_db=True) - raise - - overcloud_endpoint = None - old_rcpath = None - rcpath = None - horizon_url = None try: - if stack: - overcloud_endpoint = utils.get_overcloud_endpoint( - self.working_dir) - overcloud_admin_vip = utils.get_stack_saved_output_item( - 'KeystoneAdminVip', self.working_dir) - rc_params = utils.get_rc_params(self.working_dir) - - # For backwards compatibility, we will also write overcloudrc - # to $HOME and then self.working_dir. - old_rcpath = deployment.create_overcloudrc( - parsed_args.stack, overcloud_endpoint, overcloud_admin_vip, - rc_params, parsed_args.no_proxy) - rcpath = deployment.create_overcloudrc( - parsed_args.stack, overcloud_endpoint, overcloud_admin_vip, - rc_params, parsed_args.no_proxy, self.working_dir) - if do_setup: deployment.get_hosts_and_enable_ssh_admin( parsed_args.stack, @@ -1301,7 +1307,7 @@ class DeployOvercloud(command.Command): # Run postconfig on create or force if (stack or parsed_args.force_postconfig and not parsed_args.skip_postconfig): - self._deploy_postconfig(stack, parsed_args) + self._deploy_postconfig(parsed_args) except Exception as e: self.log.error('Exception during postconfig') self.log.error(e) diff --git a/tripleoclient/v1/tripleo_deploy.py b/tripleoclient/v1/tripleo_deploy.py index fb585141b..fa280956e 100644 --- a/tripleoclient/v1/tripleo_deploy.py +++ b/tripleoclient/v1/tripleo_deploy.py @@ -846,7 +846,7 @@ class Deploy(command.Command): endpointmap_file = os.path.join(self.output_dir, output_file) outputs = {} - endpointmap = utils.get_endpoint_map(stack) + endpointmap = utils.get_endpoint_map(self.output_dir) if endpointmap: outputs['EndpointMapOverride'] = endpointmap