Implement 'openstack tripleo upgrade'

Adding a new command:
$ openstack tripleo upgrade

This new command will run underneath:
$ openstack tripleo deploy --upgrade

The only difference when running this command is that we'll execute
upgrade tasks generated by config-download before the deployment tasks.

It'll be used by the containerized undercloud to upgrade by re-using the
upgrade tasks in THT, that were designed for the overcloud. We'll try to
re-use them so we avoid code duplication.

Change-Id: Ic932b3b308c83bc72fff4c0ef8ce94e878f33997
This commit is contained in:
Emilien Macchi 2018-05-03 11:36:17 -07:00 committed by Alex Schultz
parent fb222963b8
commit df9cbd400e
5 changed files with 119 additions and 8 deletions

View File

@ -48,6 +48,7 @@ openstack.cli.extension =
openstack.tripleoclient.v1 =
tripleo_deploy = tripleoclient.v1.tripleo_deploy:Deploy
tripleo_upgrade = tripleoclient.v1.tripleo_deploy:Upgrade
overcloud_netenv_validate = tripleoclient.v1.overcloud_netenv_validate:ValidateOvercloudNetenv
overcloud_config_download = tripleoclient.v1.overcloud_config:DownloadConfig
overcloud_container_image_upload = tripleoclient.v1.container_image:UploadImage

View File

@ -332,9 +332,9 @@ class TestDeployUndercloud(TestPluginV1):
'run_command_and_log', autospec=True)
@mock.patch('os.chdir')
@mock.patch('os.execvp')
def test_launch_ansible(self, mock_execvp, mock_chdir, mock_run):
def test_launch_ansible_deploy(self, mock_execvp, mock_chdir, mock_run):
self.cmd._launch_ansible('/tmp')
self.cmd._launch_ansible_deploy('/tmp')
mock_chdir.assert_called_once()
mock_run.assert_called_once_with(self.cmd.log, [
'ansible-playbook', '-i', '/tmp/inventory.yaml',
@ -368,7 +368,7 @@ class TestDeployUndercloud(TestPluginV1):
@mock.patch('tripleoclient.v1.tripleo_deploy.Deploy.'
'_create_install_artifact', return_value='/tmp/foo.tar.bzip2')
@mock.patch('tripleoclient.v1.tripleo_deploy.Deploy.'
'_launch_ansible')
'_launch_ansible_deploy')
@mock.patch('tripleoclient.v1.tripleo_deploy.Deploy.'
'_cleanup_working_dirs')
@mock.patch('tripleoclient.v1.tripleo_deploy.Deploy.'

View File

@ -0,0 +1,63 @@
# Copyright 2018 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
import mock
from osc_lib.tests import utils
# Load the plugin init module for the plugin list and show commands
from tripleoclient.v1 import tripleo_upgrade
class TestUpgrade(utils.TestCommand):
def setUp(self):
super(TestUpgrade, self).setUp()
# Get the command object to test
self.cmd = tripleo_upgrade.Upgrade(self.app, None)
@mock.patch('tripleoclient.utils.'
'run_command_and_log', autospec=True)
@mock.patch('os.chdir')
@mock.patch('os.execvp')
def test_launch_ansible_upgrade(self, mock_execvp, mock_chdir, mock_run):
self.cmd._launch_ansible_upgrade('/tmp')
mock_chdir.assert_called_once()
mock_run.assert_called_once_with(self.cmd.log, [
'ansible-playbook', '-i', '/tmp/inventory.yaml',
'upgrade_steps_playbook.yaml', '-e', 'role_name=Undercloud',
'-e', 'deploy_server_id=undercloud', '-e',
'bootstrap_server_id=undercloud', '--skip-tags', 'validation'])
@mock.patch('tripleoclient.v1.tripleo_deploy.Deploy.take_action',
autospec=True)
def test_take_action(self, mock_deploy):
parsed_args = self.check_parser(self.cmd,
['--local-ip', '127.0.0.1',
'--templates', '/tmp/thtroot',
'--stack', 'undercloud',
'--output-dir', '/my',
'-e', '/tmp/thtroot/puppet/foo.yaml',
'-e', '/tmp/thtroot//docker/bar.yaml',
'-e', '/tmp/thtroot42/notouch.yaml',
'-e', '~/custom.yaml',
'-e', 'something.yaml',
'-e', '../../../outside.yaml'], [])
self.cmd.take_action(parsed_args)
parsed_args.standlone = True
parsed_args.upgrade = True
mock_deploy.assert_called_with(self.cmd, parsed_args)

View File

@ -517,15 +517,26 @@ class Deploy(command.Command):
return self.tmp_ansible_dir
# Never returns, calls exec()
def _launch_ansible(self, ansible_dir):
self.log.warning('** Running ansible.. **')
def _launch_ansible_deploy(self, ansible_dir):
self.log.warning('** Running ansible deploy tasks **')
os.chdir(ansible_dir)
playbook_inventory = os.path.join(ansible_dir, 'inventory.yaml')
cmd = ['ansible-playbook', '-i', playbook_inventory,
'deploy_steps_playbook.yaml', '-e', 'role_name=Undercloud',
'-e', 'deploy_server_id=undercloud', '-e',
'bootstrap_server_id=undercloud']
self.log.debug('Running Ansible: %s' % (' '.join(cmd)))
self.log.debug('Running Ansible Deploy tasks: %s' % (' '.join(cmd)))
return utils.run_command_and_log(self.log, cmd)
def _launch_ansible_upgrade(self, ansible_dir):
self.log.warning('** Running ansible upgrade tasks **')
os.chdir(ansible_dir)
playbook_inventory = os.path.join(ansible_dir, 'inventory.yaml')
cmd = ['ansible-playbook', '-i', playbook_inventory,
'upgrade_steps_playbook.yaml', '-e', 'role_name=Undercloud',
'-e', 'deploy_server_id=undercloud', '-e',
'bootstrap_server_id=undercloud', '--skip-tags', 'validation']
self.log.debug('Running Ansible Upgrade tasks: %s' % (' '.join(cmd)))
return utils.run_command_and_log(self.log, cmd)
def get_parser(self, prog_name):
@ -541,6 +552,8 @@ class Deploy(command.Command):
parser.add_argument('--standalone', default=False, action='store_true',
help=_("Run deployment as a standalone deployment "
"with no undercloud."))
parser.add_argument('--upgrade', default=False, action='store_true',
help=_("Upgrade an existing deployment."))
parser.add_argument('--stack',
help=_("Stack name to create"),
default='undercloud')
@ -735,8 +748,10 @@ class Deploy(command.Command):
# Kill heat, we're done with it now.
self._kill_heat(parsed_args)
if not parsed_args.output_only:
# Never returns.. We exec() it directly.
rc = self._launch_ansible(ansible_dir)
# Run Upgrade tasks before the deployment
if parsed_args.upgrade:
rc = self._launch_ansible_upgrade(ansible_dir)
rc = self._launch_ansible_deploy(ansible_dir)
except Exception as e:
self.log.error("Exception: %s" % e)
self.log.error(traceback.format_exception(*sys.exc_info()))

View File

@ -0,0 +1,32 @@
# Copyright 2018 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
from __future__ import print_function
import logging
from tripleoclient.v1.tripleo_deploy import Deploy
class Upgrade(Deploy):
"""Upgrade TripleO"""
log = logging.getLogger(__name__ + ".Upgrade")
def take_action(self, parsed_args):
self.log.debug("take_action(%s)" % parsed_args)
parsed_args.standalone = True
parsed_args.upgrade = True
super(Upgrade, self).take_action(parsed_args)