Fix update run for Ephemeral Heat

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
(cherry picked from commit 5020a8a69a1f2d13e01157ffca9903951cba1356)
This commit is contained in:
Brendan Shephard 2021-08-22 22:43:35 +00:00
parent 7b9bf2fe63
commit e97d9e7b50
4 changed files with 105 additions and 53 deletions

@ -0,0 +1,10 @@
---
prelude: >
During a minor update of the overcloud. It was previously necessary to
execute 3 steps.
- Update Prepare
- Update Run
- Update Converge
Starting in W, it is no longer necessary to perform a Stack update
during the converge. This change removes the stack update from the
converge step. Now, we will just run the deploy_steps_playbook instead.

@ -100,7 +100,6 @@ EXTERNAL_UPGRADE_PLAYBOOKS = ['external_upgrade_steps_playbook.yaml']
# upgrade environment files expected by the client in the --templates
# tripleo-heat-templates default above $TRIPLEO_HEAT_TEMPLATES
UPDATE_PREPARE_ENV = "environments/lifecycle/update-prepare.yaml"
UPDATE_CONVERGE_ENV = "environments/lifecycle/update-converge.yaml"
UPGRADE_PREPARE_ENV = "environments/lifecycle/upgrade-prepare.yaml"
UPGRADE_CONVERGE_ENV = "environments/lifecycle/upgrade-converge.yaml"
UPGRADE_CONVERGE_FORBIDDEN_PARAMS = ["ceph3_namespace",

@ -140,35 +140,57 @@ class TestOvercloudUpdateRun(fakes.TestOvercloudUpdateRun):
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.v1.overcloud_deploy.DeployOvercloud.take_action')
'tripleoclient.utils.run_ansible_playbook')
def test_update_converge(self, deploy_action, mock_confirm,
mock_usercheck):
argslist = ['--templates', '--stack', 'cloud']
mock_usercheck, mock_dir, mock_key):
argslist = ['--stack', 'cloud']
verifylist = [
('stack', 'cloud')
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
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()
assert('/usr/share/openstack-tripleo-heat-templates/'
'environments/lifecycle/update-converge.yaml'
in parsed_args.environment_files)
deploy_action.assert_called_once_with(parsed_args)
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"
}
)

@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
#
import os
from oslo_config import cfg
from oslo_log import log as logging
@ -24,18 +26,17 @@ from tripleoclient import command
from tripleoclient import constants
from tripleoclient import utils as oooutils
from tripleoclient.v1.overcloud_deploy import DeployOvercloud
from tripleoclient.workflows import deployment
CONF = cfg.CONF
class UpdatePrepare(DeployOvercloud):
"""Run heat stack update for overcloud nodes to refresh heat stack outputs.
"""Use Heat to update and render the new Ansible playbooks based
on the updated templates.
The heat stack outputs are what we use later on to generate ansible
playbooks which deliver the minor update workflow. This is used as the
first step for a minor update of your overcloud.
These playbooks will be rendered and used during the update run step
to perform the minor update of the overcloud nodes.
"""
log = logging.getLogger(__name__ + ".MinorUpdatePrepare")
@ -188,44 +189,46 @@ class UpdateRun(command.Command):
else:
playbook = parsed_args.playbook
_, ansible_dir = self.get_ansible_key_and_dir(
no_workflow=True,
stack=parsed_args.stack,
orchestration=self.app.client_manager.orchestration
)
deployment.config_download(
log=self.log,
clients=self.app.client_manager,
stack=oooutils.get_stack(
self.app.client_manager.orchestration,
parsed_args.stack
),
output_dir=ansible_dir,
verbosity=oooutils.playbook_verbosity(self=self),
ansible_playbook_name=playbook,
inventory_path=oooutils.get_tripleo_ansible_inventory(
parsed_args.static_inventory,
parsed_args.ssh_user,
parsed_args.stack,
return_inventory_file_path=True
),
limit_hosts=oooutils.playbook_limit_parse(
limit_nodes=parsed_args.limit
),
ansible_dir = os.path.join(oooutils.get_default_working_dir(
parsed_args.stack
),
'config-download',
parsed_args.stack)
if not parsed_args.static_inventory:
inventory = os.path.join(ansible_dir,
'tripleo-ansible-inventory.yaml')
else:
inventory = parsed_args.static_inventory
ansible_cfg = os.path.join(ansible_dir, 'ansible.cfg')
key_file = oooutils.get_key(parsed_args.stack)
oooutils.run_ansible_playbook(
playbook=playbook,
inventory=inventory,
workdir=ansible_dir,
playbook_dir=ansible_dir,
skip_tags=parsed_args.skip_tags,
tags=parsed_args.tags,
forks=parsed_args.ansible_forks
ansible_cfg=ansible_cfg,
ssh_user='tripleo-admin',
limit_hosts=parsed_args.limit,
reproduce_command=True,
forks=parsed_args.ansible_forks,
extra_env_variables={
"ANSIBLE_BECOME": True,
"ANSIBLE_PRIVATE_KEY_FILE": key_file
}
)
self.log.info("Completed Overcloud Minor Update Run.")
self.log.info("Completed Minor Update Run.")
class UpdateConverge(DeployOvercloud):
"""Converge the update on Overcloud nodes.
This restores the plan and stack so that normal deployment
workflow is back in place.
"""
log = logging.getLogger(__name__ + ".UpdateConverge")
def get_parser(self, prog_name):
@ -236,6 +239,7 @@ class UpdateConverge(DeployOvercloud):
"required before any update operation. "
"Use this with caution! "),
)
return parser
def take_action(self, parsed_args):
@ -249,13 +253,30 @@ class UpdateConverge(DeployOvercloud):
constants.UPDATE_PROMPT, self.log)):
raise OvercloudUpdateNotConfirmed(constants.UPDATE_NO)
# Add the update-converge.yaml environment to unset noops
templates_dir = (parsed_args.templates or
constants.TRIPLEO_HEAT_TEMPLATES)
parsed_args.environment_files = oooutils.prepend_environment(
parsed_args.environment_files, templates_dir,
constants.UPDATE_CONVERGE_ENV)
ansible_dir = os.path.join(oooutils.get_default_working_dir(
parsed_args.stack
),
'config-download',
parsed_args.stack)
super(UpdateConverge, self).take_action(parsed_args)
self.log.info("Update converge on stack {0} complete.".format(
parsed_args.stack))
inventory = os.path.join(ansible_dir,
'tripleo-ansible-inventory.yaml')
ansible_cfg = os.path.join(ansible_dir, 'ansible.cfg')
key_file = oooutils.get_key(parsed_args.stack)
oooutils.run_ansible_playbook(
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": key_file
}
)
self.log.info("Completed Minor Update Converge.")