From f32afc30dbf420965e3d0f16dcd2f6118e64571d Mon Sep 17 00:00:00 2001 From: Jose Luis Franco Arza Date: Wed, 2 Feb 2022 14:25:33 +0100 Subject: [PATCH] Add --reproduce-command option into Undercloud commands. The tripleo deploy command contains a very useful option named --reproduce-command. This option will drop a script with the needed command to reproduce an ansible playbook execution. This patch adds the very same option into the openstack undercloud install and openstack undercloud upgrade commands, so that the underlying tripleo deploy command used to deploy or upgrade creates this reproducer script. Change-Id: I33c9b5bea949d148f21175c15e9d8522fa4297bf Resolves: rhbz#2049444 (cherry picked from commit 348437dfa200dff0e45c665f0bf1a2dd65121052) --- .../v1/undercloud/test_install_upgrade.py | 80 +++++++++++++++++-- tripleoclient/v1/undercloud.py | 9 +++ tripleoclient/v1/undercloud_config.py | 4 + 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/tripleoclient/tests/v1/undercloud/test_install_upgrade.py b/tripleoclient/tests/v1/undercloud/test_install_upgrade.py index 41922100c..d0b60d787 100644 --- a/tripleoclient/tests/v1/undercloud/test_install_upgrade.py +++ b/tripleoclient/tests/v1/undercloud/test_install_upgrade.py @@ -111,6 +111,65 @@ class TestUndercloudInstall(TestPluginV1): '/usr/share/openstack-tripleo-heat-templates/' 'undercloud-stack-vstate-dropin.yaml']) + # TODO(cjeanner) drop once we have proper oslo.privsep + @mock.patch('os.geteuid', return_value=1001) + @mock.patch('getpass.getuser', return_value='stack') + @mock.patch('builtins.open') + @mock.patch('shutil.copy') + @mock.patch('os.mkdir') + @mock.patch('tripleoclient.utils.write_env_file', autospec=True) + @mock.patch('subprocess.check_call', autospec=True) + def test_undercloud_install_with_reproduce_command(self, mock_subprocess, + mock_wr, + mock_os, mock_copy, + mock_open, mock_user, + mock_getuid): + arglist = ['--no-validations', '--reproduce-command'] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + self.cmd.take_action(parsed_args) + + mock_subprocess.assert_called_with( + ['sudo', '--preserve-env', 'openstack', 'tripleo', 'deploy', + '--standalone', '--standalone-role', 'Undercloud', '--stack', + 'undercloud', '--local-domain=localdomain', + '--local-ip=192.168.24.1/24', + '--templates=/usr/share/openstack-tripleo-heat-templates/', + '--networks-file=/usr/share/openstack-tripleo-heat-templates/' + 'network_data_undercloud.yaml', + '--heat-native', '-e', + '/usr/share/openstack-tripleo-heat-templates/environments/' + 'undercloud.yaml', '-e', + '/usr/share/openstack-tripleo-heat-templates/environments/' + 'use-dns-for-vips.yaml', '-e', + '/home/stack/foo.yaml', '-e', + '/usr/share/openstack-tripleo-heat-templates/environments/' + 'services/ironic.yaml', '-e', + '/usr/share/openstack-tripleo-heat-templates/environments/' + 'services/ironic-inspector.yaml', '-e', + '/usr/share/openstack-tripleo-heat-templates/environments/' + 'services/undercloud-remove-novajoin.yaml', '-e', + '/usr/share/openstack-tripleo-heat-templates/environments/' + 'disable-telemetry.yaml', '-e', + '/usr/share/openstack-tripleo-heat-templates/environments/' + 'public-tls-undercloud.yaml', + '--public-virtual-ip', '192.168.24.2', + '--control-virtual-ip', '192.168.24.3', '-e', + '/usr/share/openstack-tripleo-heat-templates/environments/' + 'ssl/tls-endpoints-public-ip.yaml', '-e', + '/usr/share/openstack-tripleo-heat-templates/environments/' + 'services/undercloud-haproxy.yaml', + # TODO(cjeanner) drop once we have proper oslo.privsep + '--deployment-user', 'stack', + '--output-dir=/home/stack', '--cleanup', + '-e', '/home/stack/tripleo-config-generated-env-files/' + 'undercloud_parameters.yaml', '--reproduce-command', + '--log-file=install-undercloud.log', '-e', + '/usr/share/openstack-tripleo-heat-templates/' + 'undercloud-stack-vstate-dropin.yaml']) + # TODO(cjeanner) drop once we have proper oslo.privsep @mock.patch('os.geteuid', return_value=1001) @mock.patch('getpass.getuser', return_value='stack') @@ -621,7 +680,9 @@ class TestUndercloudUpgrade(TestPluginV1): mock_os, mock_copy, mock_user, mock_getuid): arglist = ['--force-stack-update', '--no-validations', - '--inflight-validations', '--dry-run', '--yes'] + '--inflight-validations', '--dry-run', '--yes', + '--disable-container-prepare', '--reproduce-command', + '--skip-package-updates'] verifylist = [] self.cmd.app_args.verbose_level = 2 parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -828,12 +889,15 @@ class TestUndercloudUpgrade(TestPluginV1): @mock.patch('tripleoclient.utils.write_env_file', autospec=True) @mock.patch('subprocess.check_call', autospec=True) @mock.patch('tripleoclient.utils.run_command', autospec=True) - def test_undercloud_upgrade_with_heat_and_yes(self, mock_run_command, - mock_subprocess, - mock_wr, mock_os, - mock_copy, mock_user, - mock_getuid): - arglist = ['--no-validations', '-y', '--skip-package-updates'] + def test_undercloud_upgrade_with_heat_reproduce_and_yes(self, + mock_run_command, + mock_subprocess, + mock_wr, mock_os, + mock_copy, + mock_user, + mock_getuid): + arglist = ['--no-validations', '-y', '--skip-package-updates', + '--reproduce-command'] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -877,7 +941,7 @@ class TestUndercloudUpgrade(TestPluginV1): '--deployment-user', 'stack', '--output-dir=/home/stack', '--cleanup', '-e', '/home/stack/tripleo-config-generated-env-files/' - 'undercloud_parameters.yaml', + 'undercloud_parameters.yaml', '--reproduce-command', '--log-file=install-undercloud.log', '-e', '/usr/share/openstack-tripleo-heat-templates/' 'undercloud-stack-vstate-dropin.yaml']) diff --git a/tripleoclient/v1/undercloud.py b/tripleoclient/v1/undercloud.py index 63ee5d030..c111dd1b1 100644 --- a/tripleoclient/v1/undercloud.py +++ b/tripleoclient/v1/undercloud.py @@ -131,6 +131,13 @@ class InstallUndercloud(command.Command): 'the container parameters configured, the deployment ' 'action may fail.') ) + parser.add_argument( + '--reproduce-command', + action='store_true', + default=False, + help=_('Create a reproducer command with ansible command' + 'line and all environments variables.') + ) return parser def take_action(self, parsed_args): @@ -150,6 +157,7 @@ class InstallUndercloud(command.Command): force_stack_update=parsed_args.force_stack_update, dry_run=parsed_args.dry_run, inflight=inflight, + reproducer=parsed_args.reproduce_command, disable_container_prepare=parsed_args.disable_container_prepare) self.log.warning("Running: %s" % ' '.join(cmd)) @@ -212,6 +220,7 @@ class UpgradeUndercloud(InstallUndercloud): no_validations=parsed_args. no_validations, verbose_level=self.app_args.verbose_level, + reproducer=parsed_args.reproduce_command, force_stack_update=parsed_args.force_stack_update) self.log.warning("Running: %s" % ' '.join(cmd)) try: diff --git a/tripleoclient/v1/undercloud_config.py b/tripleoclient/v1/undercloud_config.py index 2ba3a65b7..e704c1e18 100644 --- a/tripleoclient/v1/undercloud_config.py +++ b/tripleoclient/v1/undercloud_config.py @@ -439,6 +439,7 @@ def prepare_undercloud_deploy(upgrade=False, no_validations=True, verbose_level=1, yes=False, force_stack_update=False, dry_run=False, inflight=False, + reproducer=False, disable_container_prepare=False): """Prepare Undercloud deploy command based on undercloud.conf""" @@ -822,6 +823,9 @@ def prepare_undercloud_deploy(upgrade=False, no_validations=True, if inflight: deploy_args.append('--inflight-validations') + if reproducer: + deploy_args.append('--reproduce-command') + if disable_container_prepare: deploy_args.append('--disable-container-prepare')