5020a8a69a
When using ephemeral Heat, the update run can no longer rely on the Heat stack being present. Since we create the stack and update the playbooks during update prepare. We can simply execute the update_steps_playbook.yaml now. With this change, we also change the converge to just execute the deploy_steps_playbook.yaml without doing the entire stack update. The stack update is no longer necessary with Ephemeral Heat. Related: https://review.opendev.org/c/openstack/tripleo-upgrade/+/806565 Change-Id: I57d788639b651945ad765f810b504529e41f0fbd
196 lines
7.9 KiB
Python
196 lines
7.9 KiB
Python
# Copyright 2015 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.utils import ParserException
|
|
from tripleoclient import constants
|
|
from tripleoclient import exceptions
|
|
from tripleoclient.tests.v1.overcloud_update import fakes
|
|
from tripleoclient.v1 import overcloud_update
|
|
|
|
|
|
class TestOvercloudUpdatePrepare(fakes.TestOvercloudUpdatePrepare):
|
|
|
|
def setUp(self):
|
|
super(TestOvercloudUpdatePrepare, self).setUp()
|
|
|
|
# Get the command object to test
|
|
app_args = mock.Mock()
|
|
app_args.verbose_level = 1
|
|
self.cmd = overcloud_update.UpdatePrepare(self.app, app_args)
|
|
|
|
uuid4_patcher = mock.patch('uuid.uuid4', return_value="UUID4")
|
|
self.mock_uuid4 = uuid4_patcher.start()
|
|
self.addCleanup(self.mock_uuid4.stop)
|
|
|
|
@mock.patch('tripleoclient.utils.ensure_run_as_normal_user')
|
|
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
|
|
return_value=True)
|
|
@mock.patch('six.moves.builtins.open')
|
|
@mock.patch('os.path.abspath')
|
|
@mock.patch('yaml.safe_load')
|
|
@mock.patch('shutil.copytree', autospec=True)
|
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
|
'take_action', autospec=True)
|
|
def test_update_failed(self, mock_deploy, mock_copy, mock_yaml,
|
|
mock_abspath, mock_open,
|
|
mock_confirm, mock_usercheck):
|
|
mock_deploy.side_effect = exceptions.DeploymentError()
|
|
mock_yaml.return_value = {'fake_container': 'fake_value'}
|
|
argslist = ['--stack', 'overcloud', '--templates', ]
|
|
verifylist = [
|
|
('stack', 'overcloud'),
|
|
('templates', constants.TRIPLEO_HEAT_TEMPLATES),
|
|
]
|
|
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
|
|
|
|
with mock.patch('os.path.exists') as mock_exists, \
|
|
mock.patch('os.path.isfile') as mock_isfile:
|
|
mock_exists.return_value = True
|
|
mock_isfile.return_value = True
|
|
self.assertRaises(exceptions.DeploymentError,
|
|
self.cmd.take_action, parsed_args)
|
|
mock_usercheck.assert_called_once()
|
|
|
|
@mock.patch('tripleoclient.utils.get_ctlplane_attrs', autospec=True,
|
|
return_value={})
|
|
@mock.patch('tripleoclient.utils.ensure_run_as_normal_user')
|
|
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
|
|
return_value=True)
|
|
@mock.patch('tripleoclient.utils.get_undercloud_host_entry', autospec=True,
|
|
return_value='192.168.0.1 uc.ctlplane.localhost uc.ctlplane')
|
|
@mock.patch('tripleoclient.v1.overcloud_update.UpdatePrepare.log',
|
|
autospec=True)
|
|
@mock.patch('os.path.abspath')
|
|
@mock.patch('yaml.safe_load')
|
|
@mock.patch('shutil.copytree', autospec=True)
|
|
@mock.patch('six.moves.builtins.open')
|
|
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
|
'take_action', autospec=True)
|
|
def test_update_out(self, mock_deploy, mock_open, mock_copy, mock_yaml,
|
|
mock_abspath, mock_logger,
|
|
mock_get_undercloud_host_entry,
|
|
mock_confirm, mock_usercheck,
|
|
mock_get_ctlplane_attrs):
|
|
mock_yaml.return_value = {'fake_container': 'fake_value'}
|
|
|
|
argslist = ['--stack', 'overcloud', '--templates']
|
|
|
|
verifylist = [
|
|
('stack', 'overcloud'),
|
|
('templates', constants.TRIPLEO_HEAT_TEMPLATES),
|
|
]
|
|
|
|
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
|
|
with mock.patch('os.path.exists') as mock_exists, \
|
|
mock.patch('os.path.isfile') as mock_isfile:
|
|
mock_exists.return_value = True
|
|
mock_isfile.return_value = True
|
|
self.cmd.take_action(parsed_args)
|
|
mock_usercheck.assert_called_once()
|
|
mock_deploy.assert_called_once()
|
|
|
|
|
|
class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun):
|
|
|
|
def setUp(self):
|
|
super(TestOvercloudUpdateRun, self).setUp()
|
|
|
|
# Get the command object to test
|
|
app_args = mock.Mock()
|
|
app_args.verbose_level = 1
|
|
self.cmd = overcloud_update.UpdateRun(self.app, app_args)
|
|
|
|
uuid4_patcher = mock.patch('uuid.uuid4', return_value="UUID4")
|
|
self.mock_uuid4 = uuid4_patcher.start()
|
|
self.addCleanup(self.mock_uuid4.stop)
|
|
|
|
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
|
|
return_value=True)
|
|
@mock.patch('tripleoclient.utils.run_ansible_playbook',
|
|
autospec=True)
|
|
@mock.patch('os.path.expanduser')
|
|
@mock.patch('oslo_concurrency.processutils.execute')
|
|
@mock.patch('six.moves.builtins.open')
|
|
def test_update_with_no_limit(
|
|
self, mock_open, mock_execute, mock_expanduser, update_ansible,
|
|
mock_confirm):
|
|
mock_expanduser.return_value = '/home/fake/'
|
|
argslist = []
|
|
verifylist = [
|
|
('static_inventory', None),
|
|
('playbook', 'all')
|
|
]
|
|
self.assertRaises(ParserException, lambda: self.check_parser(
|
|
self.cmd, argslist, verifylist))
|
|
|
|
|
|
class TestOvercloudUpdateConverge(fakes.TestOvercloudUpdateConverge):
|
|
def setUp(self):
|
|
super(TestOvercloudUpdateConverge, self).setUp()
|
|
# Get the command object to test
|
|
app_args = mock.Mock()
|
|
app_args.verbose_level = 1
|
|
self.cmd = overcloud_update.UpdateConverge(self.app, app_args)
|
|
|
|
@mock.patch('tripleoclient.utils.get_key')
|
|
@mock.patch('tripleoclient.utils.get_default_working_dir')
|
|
@mock.patch('tripleoclient.utils.ensure_run_as_normal_user')
|
|
@mock.patch('tripleoclient.utils.prompt_user_for_confirmation',
|
|
return_value=True)
|
|
@mock.patch(
|
|
'tripleoclient.utils.run_ansible_playbook')
|
|
def test_update_converge(self, deploy_action, mock_confirm,
|
|
mock_usercheck, mock_dir, mock_key):
|
|
argslist = ['--stack', 'cloud']
|
|
verifylist = [
|
|
('stack', 'cloud')
|
|
]
|
|
mock_dir.return_value = "/home/stack/overcloud-deploy"
|
|
ansible_dir = "{}/config-download/cloud".format(
|
|
mock_dir.return_value
|
|
)
|
|
inventory = "{}/tripleo-ansible-inventory.yaml".format(
|
|
ansible_dir
|
|
)
|
|
ansible_cfg = "{}/ansible.cfg".format(
|
|
ansible_dir
|
|
)
|
|
mock_key.return_value = '/home/stack/.ssh/id_rsa_tripleo'
|
|
|
|
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
|
|
with mock.patch('os.path.exists') as mock_exists, \
|
|
mock.patch('os.path.isfile') as mock_isfile:
|
|
mock_exists.return_value = True
|
|
mock_isfile.return_value = True
|
|
self.cmd.take_action(parsed_args)
|
|
mock_usercheck.assert_called_once()
|
|
deploy_action.assert_called_once_with(
|
|
playbook='deploy_steps_playbook.yaml',
|
|
inventory=inventory,
|
|
workdir=ansible_dir,
|
|
playbook_dir=ansible_dir,
|
|
ansible_cfg=ansible_cfg,
|
|
ssh_user='tripleo-admin',
|
|
reproduce_command=True,
|
|
forks=parsed_args.ansible_forks,
|
|
extra_env_variables={
|
|
"ANSIBLE_BECOME": True,
|
|
"ANSIBLE_PRIVATE_KEY_FILE":
|
|
"/home/stack/.ssh/id_rsa_tripleo"
|
|
}
|
|
)
|