Merge "Use undercloud upgrade to update all required pkgs" into stable/train

This commit is contained in:
Zuul 2020-05-21 23:26:11 +00:00 committed by Gerrit Code Review
commit ac7ddb7dcc
3 changed files with 127 additions and 65 deletions

View File

@ -170,6 +170,7 @@ EXPORT_PASSWORD_EXCLUDE_PATTERNS = [
# Package that need to be to the latest before undercloud
# update/update/ffwd.
UNDERCLOUD_EXTRA_PACKAGES = [
"openstack-tripleo-common",
"openstack-tripleo-heat-templates",
"openstack-tripleo-validations",
"tripleo-ansible"

View File

@ -17,6 +17,7 @@ import fixtures
import json
import mock
import os
import sys
from jinja2 import Template
@ -563,6 +564,7 @@ class TestUndercloudUpgrade(TestPluginV1):
app_args.verbose_level = 1
self.cmd = undercloud.UpgradeUndercloud(self.app, app_args)
@mock.patch.object(sys, 'executable', 'python2')
# TODO(cjeanner) drop once we have proper oslo.privsep
@mock.patch('getpass.getuser', return_value='stack')
@mock.patch('shutil.copy')
@ -582,12 +584,64 @@ class TestUndercloudUpgrade(TestPluginV1):
self.cmd.take_action(parsed_args)
mock_run_command.assert_called_with(
['sudo', 'yum', 'upgrade', '-y',
'python2-tripleoclient',
'openstack-tripleo-common',
'openstack-tripleo-heat-templates',
'openstack-tripleo-validations',
'tripleo-ansible'],
name='Update extra packages'
)
mock_subprocess.assert_called_with([
'openstack', 'undercloud', 'upgrade', '--skip-package-updates',
'--no-validations'])
@mock.patch.object(sys, 'executable', 'python3')
# 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('shutil.copy')
@mock.patch('os.mkdir')
@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_all_opts(self, mock_run_command,
mock_subprocess,
mock_wr,
mock_os, mock_copy, mock_user,
mock_getuid):
arglist = ['--force-stack-update', '--no-validations',
'--inflight-validations', '--dry-run', '--yes']
verifylist = []
self.cmd.app_args.verbose_level = 2
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# DisplayCommandBase.take_action() returns two tuples
self.cmd.take_action(parsed_args)
mock_run_command.assert_not_called()
mock_subprocess.assert_called_with([
'openstack', 'undercloud', 'upgrade', '--skip-package-updates',
'--force-stack-update', '--no-validations',
'--inflight-validations', '--dry-run', '--yes', '--debug'])
# 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('shutil.copy')
@mock.patch('os.mkdir')
@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_no_pkgs(self, mock_run_command,
mock_subprocess,
mock_wr,
mock_os, mock_copy, mock_user,
mock_getuid):
arglist = ['--no-validations', '--skip-package-updates']
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',
@ -648,21 +702,13 @@ class TestUndercloudUpgrade(TestPluginV1):
mock_subprocess,
mock_wr, mock_os,
mock_copy, mock_user):
arglist = ['--no-validations']
arglist = ['--no-validations', '--skip-package-updates']
verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# DisplayCommandBase.take_action() returns two tuples
self.cmd.take_action(parsed_args)
mock_run_command.assert_called_with(
['sudo', 'yum', 'upgrade', '-y',
'openstack-tripleo-heat-templates',
'openstack-tripleo-validations',
'tripleo-ansible'],
name='Update extra packages'
)
mock_subprocess.assert_called_with(
['sudo', '--preserve-env', 'openstack', 'tripleo', 'deploy',
'--standalone', '--standalone-role', 'Undercloud', '--stack',
@ -722,21 +768,13 @@ class TestUndercloudUpgrade(TestPluginV1):
mock_subprocess,
mock_wr, mock_os,
mock_copy, mock_user):
arglist = ['--no-validations']
arglist = ['--no-validations', '--skip-package-updates']
verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# DisplayCommandBase.take_action() returns two tuples
self.cmd.take_action(parsed_args)
mock_run_command.assert_called_with(
['sudo', 'yum', 'upgrade', '-y',
'openstack-tripleo-heat-templates',
'openstack-tripleo-validations',
'tripleo-ansible'],
name='Update extra packages'
)
mock_subprocess.assert_called_with(
['sudo', '--preserve-env', 'openstack', 'tripleo', 'deploy',
'--standalone', '--standalone-role', 'Undercloud', '--stack',
@ -795,22 +833,14 @@ class TestUndercloudUpgrade(TestPluginV1):
def test_undercloud_upgrade_with_heat_and_yes(self, mock_run_command,
mock_subprocess,
mock_wr, mock_os,
mock_user, mock_copy):
arglist = ['--no-validations', '-y']
mock_copy, mock_user):
arglist = ['--no-validations', '-y', '--skip-package-updates']
verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# DisplayCommandBase.take_action() returns two tuples
self.cmd.take_action(parsed_args)
mock_run_command.assert_called_with(
['sudo', 'yum', 'upgrade', '-y',
'openstack-tripleo-heat-templates',
'openstack-tripleo-validations',
'tripleo-ansible'],
name='Update extra packages'
)
mock_subprocess.assert_called_with(
['sudo', '--preserve-env', 'openstack', 'tripleo', 'deploy',
'--standalone', '--standalone-role', 'Undercloud', '--stack',
@ -871,7 +901,7 @@ class TestUndercloudUpgrade(TestPluginV1):
mock_subprocess,
mock_wr, mock_os,
mock_copy, mock_user):
arglist = ['--no-validations']
arglist = ['--no-validations', '--skip-package-updates']
verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -881,14 +911,6 @@ class TestUndercloudUpgrade(TestPluginV1):
self.cmd.take_action(parsed_args)
self.cmd.app_args.verbose_level = old_verbose
mock_run_command.assert_called_with(
['sudo', 'yum', 'upgrade', '-y',
'openstack-tripleo-heat-templates',
'openstack-tripleo-validations',
'tripleo-ansible'],
name='Update extra packages'
)
mock_subprocess.assert_called_with(
['sudo', '--preserve-env', 'openstack', 'tripleo', 'deploy',
'--standalone', '--standalone-role', 'Undercloud', '--stack',

View File

@ -19,6 +19,7 @@ import argparse
import logging
import os
import subprocess
import sys
from openstackclient.i18n import _
@ -165,41 +166,55 @@ class UpgradeUndercloud(InstallUndercloud):
log = logging.getLogger(__name__ + ".UpgradeUndercloud")
osloconfig = cfg.CONF
def get_parser(self, prog_name):
parser = super(UpgradeUndercloud, self).get_parser(prog_name)
parser.add_argument('--skip-package-updates',
dest='skip_package_updates',
action='store_true',
default=False,
help=_("Flag to skip the package update when "
"performing upgrades and updates"),
)
return parser
def _update_extra_packages(self, packages=[], dry_run=False):
"""Necessary packages to be updated before undercloud upgrade."""
cmd = []
if packages:
cmd = ['sudo', 'yum', 'upgrade', '-y'] + packages
if not packages:
return
if cmd:
if not dry_run:
self.log.warning(
"Updating necessary packages: {}\n{}".format(
" ".join(packages),
("Note that tripleoclient and tripleo-common "
"still need to be updated manually.")
),
)
output = utils.run_command(cmd, name="Update extra packages")
self.log.warning("{}".format(output))
else:
self.log.warning(
"Would update necessary packages: {}".format(" ".join(cmd))
)
cmd = ['sudo', 'yum', 'upgrade', '-y'] + packages
def take_action(self, parsed_args):
# Fetch configuration used to add logging to a file
utils.load_config(self.osloconfig, constants.UNDERCLOUD_CONF_PATH)
utils.configure_logging(self.log, self.app_args.verbose_level,
self.osloconfig['undercloud_log_file'])
self.log.debug("take action(%s)" % parsed_args)
if not dry_run:
self.log.warning("Updating necessary packages: {}".format(
" ".join(packages)))
output = utils.run_command(cmd, name="Update extra packages")
self.log.warning("{}".format(output))
else:
self.log.warning("Would update necessary packages: {}".format(
" ".join(cmd)))
utils.ensure_run_as_normal_user()
self._update_extra_packages(constants.UNDERCLOUD_EXTRA_PACKAGES,
parsed_args.dry_run)
def _invoke_self(self, parsed_args):
cmd = ['openstack', 'undercloud', 'upgrade', '--skip-package-updates']
opts = {'force_stack_update': '--force-stack-update',
'no_validations': '--no-validations',
'inflight': '--inflight-validations',
'dry_run': '--dry-run',
'yes': '--yes'}
args = vars(parsed_args)
for k, v in opts.items():
if args[k]:
cmd.append(v)
# handle --debug
if self.app_args.verbose_level > 1:
cmd.append('--debug')
try:
subprocess.check_call(cmd)
except Exception as e:
self.log.error(e)
raise exceptions.DeploymentError(e)
def _run_upgrade(self, parsed_args):
cmd = undercloud_config.\
prepare_undercloud_deploy(
upgrade=True,
@ -224,3 +239,27 @@ class UpgradeUndercloud(InstallUndercloud):
self.log.error(UNDERCLOUD_FAILURE_MESSAGE)
self.log.error(e)
raise exceptions.DeploymentError(e)
def take_action(self, parsed_args):
# Fetch configuration used to add logging to a file
utils.load_config(self.osloconfig, constants.UNDERCLOUD_CONF_PATH)
utils.configure_logging(self.log, self.app_args.verbose_level,
self.osloconfig['undercloud_log_file'])
self.log.debug("take action(%s)" % parsed_args)
utils.ensure_run_as_normal_user()
if not parsed_args.skip_package_updates:
print("executable is {}".format(sys.executable))
if ('python3' in sys.executable):
pyver = '3'
else:
pyver = '2'
client_pkgs = [
"python{}-tripleoclient".format(pyver),
]
pkgs = client_pkgs + constants.UNDERCLOUD_EXTRA_PACKAGES
self._update_extra_packages(pkgs, parsed_args.dry_run)
self._invoke_self(parsed_args)
else:
self._run_upgrade(parsed_args)