Add major update implementation
Add the openstack overcloud upgrade command and workflow for major upgrade from P to Queens. It share the same code base as the minor upgrade but add options for the converge part and take as parameter a list of environment files, that could be needed in some cases for the upgrade init stage. (like repo_setupt) Change-Id: I54f8fc57b758e34c620d607be15d2291d545ff6f
This commit is contained in:
parent
1e033c98fa
commit
e62b638acf
|
@ -88,6 +88,7 @@ openstack.tripleoclient.v1 =
|
|||
overcloud_roles_generate = tripleoclient.v1.overcloud_roles:RolesGenerate
|
||||
overcloud_support_report_collect = tripleoclient.v1.overcloud_support:ReportExecute
|
||||
overcloud_update_stack = tripleoclient.v1.overcloud_update:UpdateOvercloud
|
||||
overcloud_upgrade = tripleoclient.v1.overcloud_update:UpgradeOvercloud
|
||||
overcloud_execute = tripleoclient.v1.overcloud_execute:RemoteExecute
|
||||
overcloud_generate_fencing = tripleoclient.v1.overcloud_parameters:GenerateFencingParameters
|
||||
undercloud_deploy = tripleoclient.v1.undercloud_deploy:DeployUndercloud
|
||||
|
|
|
@ -28,6 +28,7 @@ PLAN_ENVIRONMENT = 'plan-environment.yaml'
|
|||
DEFAULT_ENV_DIRECTORY = "~/.tripleo/environments"
|
||||
|
||||
TRIPLEO_PUPPET_MODULES = "/usr/share/openstack-puppet/modules/"
|
||||
UPGRADE_CONVERGE_FILE = "major-upgrade-converge-docker.yaml"
|
||||
PUPPET_MODULES = "/etc/puppet/modules/"
|
||||
PUPPET_BASE = "/etc/puppet/"
|
||||
# Update Queue
|
||||
|
|
|
@ -51,11 +51,11 @@ class TestOvercloudUpdate(fakes.TestOvercloudUpdate):
|
|||
mock_get_stack.return_value = mock_stack
|
||||
mock_abspath.return_value = '/home/fake/my-fake-registry.yaml'
|
||||
mock_yaml.return_value = {'fake_container': 'fake_value'}
|
||||
argslist = ['--stack', 'overcloud', '--init-minor-update',
|
||||
argslist = ['--stack', 'overcloud', '--init-update',
|
||||
'--container-registry-file', 'my-fake-registry.yaml']
|
||||
verifylist = [
|
||||
('stack', 'overcloud'),
|
||||
('init_minor_update', True),
|
||||
('init_update', True),
|
||||
('container_registry_file', 'my-fake-registry.yaml')
|
||||
]
|
||||
|
||||
|
@ -67,6 +67,7 @@ class TestOvercloudUpdate(fakes.TestOvercloudUpdate):
|
|||
container_registry={'fake_container': 'fake_value'},
|
||||
ceph_ansible_playbook='/usr/share/ceph-ansible'
|
||||
'/site-docker.yml.sample',
|
||||
environments={}
|
||||
)
|
||||
|
||||
@mock.patch('tripleoclient.workflows.package_update.update',
|
||||
|
@ -79,11 +80,11 @@ class TestOvercloudUpdate(fakes.TestOvercloudUpdate):
|
|||
mock_update.side_effect = exceptions.DeploymentError()
|
||||
mock_abspath.return_value = '/home/fake/my-fake-registry.yaml'
|
||||
mock_yaml.return_value = {'fake_container': 'fake_value'}
|
||||
argslist = ['--stack', 'overcloud', '--init-minor-update',
|
||||
argslist = ['--stack', 'overcloud', '--init-update',
|
||||
'--container-registry-file', 'my-fake-registry.yaml']
|
||||
verifylist = [
|
||||
('stack', 'overcloud'),
|
||||
('init_minor_update', True),
|
||||
('init_update', True),
|
||||
('container_registry_file', 'my-fake-registry.yaml')
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, argslist, verifylist)
|
||||
|
|
|
@ -17,7 +17,7 @@ import logging
|
|||
import os
|
||||
import yaml
|
||||
|
||||
|
||||
from heatclient.common import template_utils
|
||||
from osc_lib.i18n import _
|
||||
from oslo_concurrency import processutils
|
||||
|
||||
|
@ -48,10 +48,11 @@ class UpdateOvercloud(command.Command):
|
|||
help=_("The directory containing the Heat"
|
||||
"templates to deploy. "),
|
||||
)
|
||||
parser.add_argument('--init-minor-update',
|
||||
dest='init_minor_update',
|
||||
parser.add_argument('--init-update',
|
||||
dest='init_update',
|
||||
action='store_true',
|
||||
help=_("Init the minor update heat config output."
|
||||
help=_("Run a heat stack update to generate the "
|
||||
"ansible playbooks."
|
||||
"Needs to be run only once"),
|
||||
)
|
||||
parser.add_argument('--container-registry-file',
|
||||
|
@ -68,17 +69,24 @@ class UpdateOvercloud(command.Command):
|
|||
'used for update. This value should be set '
|
||||
'during the init-minor-update step.')
|
||||
)
|
||||
parser.add_argument('--extra-environment', '-e',
|
||||
action='append',
|
||||
dest='environment_files',
|
||||
default=[],
|
||||
help=_("Extra environment required for the "
|
||||
"major update"),
|
||||
)
|
||||
parser.add_argument('--nodes',
|
||||
action="store",
|
||||
default=None,
|
||||
help=_('Nodes to update. If none and the '
|
||||
'--init-minor-update set to false, it '
|
||||
'will run the update on all nodes.')
|
||||
help=_("Nodes to update. If none and the "
|
||||
"--init-update set to false, it "
|
||||
"will run the update on all nodes.")
|
||||
)
|
||||
parser.add_argument('--playbook',
|
||||
action="store",
|
||||
default="update_steps_playbook.yaml",
|
||||
help=_('Playbook to use for update')
|
||||
help=_("Playbook to use for update/upgrade.")
|
||||
)
|
||||
parser.add_argument('--static-inventory',
|
||||
dest='static_inventory',
|
||||
|
@ -100,8 +108,9 @@ class UpdateOvercloud(command.Command):
|
|||
|
||||
stack_name = stack.stack_name
|
||||
container_registry = parsed_args.container_registry_file
|
||||
init_update = parsed_args.init_update
|
||||
|
||||
if parsed_args.init_minor_update:
|
||||
if init_update:
|
||||
# Update the container registry:
|
||||
if container_registry:
|
||||
with open(os.path.abspath(container_registry)) as content:
|
||||
|
@ -114,16 +123,21 @@ class UpdateOvercloud(command.Command):
|
|||
"to re-run this command and provide the registry file "
|
||||
"with: --container-registry-file option.")
|
||||
registry = None
|
||||
# Execute minor update
|
||||
# Extra env file
|
||||
environment_files = parsed_args.environment_files
|
||||
env = {}
|
||||
if environment_files:
|
||||
env_files, env = (
|
||||
template_utils.process_multiple_environments_and_files(
|
||||
env_paths=environment_files))
|
||||
# Run update
|
||||
ceph_ansible_playbook = parsed_args.ceph_ansible_playbook
|
||||
package_update.update(clients, container=stack_name,
|
||||
container_registry=registry,
|
||||
ceph_ansible_playbook=ceph_ansible_playbook)
|
||||
|
||||
print("Heat stack update init on {0} complete.".format(
|
||||
parsed_args.stack))
|
||||
ceph_ansible_playbook=ceph_ansible_playbook,
|
||||
environments=env)
|
||||
package_update.get_config(clients, container=stack_name)
|
||||
print("Init minor update on stack {0} complete.".format(
|
||||
print("Update init on stack {0} complete.".format(
|
||||
parsed_args.stack))
|
||||
else:
|
||||
# Run ansible:
|
||||
|
@ -150,3 +164,49 @@ class UpdateOvercloud(command.Command):
|
|||
inventory_file=inventory,
|
||||
playbook=playbook,
|
||||
ansible_queue_name=constants.UPDATE_QUEUE)
|
||||
|
||||
|
||||
class UpgradeOvercloud(UpdateOvercloud):
|
||||
"""Upgrade Overcloud Nodes"""
|
||||
|
||||
log = logging.getLogger(__name__ + ".UpgradeOvercloud")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UpgradeOvercloud, self).get_parser(prog_name)
|
||||
parser.add_argument('--converge',
|
||||
dest='converge',
|
||||
action='store_true',
|
||||
help=_("Upgrade converge step"),
|
||||
)
|
||||
parser.add_argument('--upgrade-converge-environment-file',
|
||||
dest='upgrade_converge_file',
|
||||
default="%senvironments/%s" % (
|
||||
constants.TRIPLEO_HEAT_TEMPLATES,
|
||||
constants.UPGRADE_CONVERGE_FILE),
|
||||
help=_("Upgrade environment file which perform "
|
||||
"the converge of the Overcloud"),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
clients = self.app.client_manager
|
||||
|
||||
stack = oooutils.get_stack(clients.orchestration,
|
||||
parsed_args.stack)
|
||||
|
||||
stack_name = stack.stack_name
|
||||
converge = parsed_args.converge
|
||||
|
||||
if converge:
|
||||
converge_file = parsed_args.upgrade_converge_file
|
||||
# Add the converge file to the user environment:
|
||||
if converge_file:
|
||||
with open(os.path.abspath(converge_file)) as conv_content:
|
||||
converge_env = yaml.load(conv_content.read())
|
||||
# Run converge steps
|
||||
package_update.converge_nodes(clients,
|
||||
converge_env=converge_env,
|
||||
container=stack_name)
|
||||
else:
|
||||
super(UpgradeOvercloud, self).take_action(parsed_args)
|
||||
|
|
|
@ -111,4 +111,35 @@ def update_ansible(clients, **workflow_input):
|
|||
if payload['status'] == 'SUCCESS':
|
||||
print('Success')
|
||||
else:
|
||||
raise RuntimeError('Minor update failed with: {}'.format(payload))
|
||||
raise RuntimeError('Update failed with: {}'.format(payload))
|
||||
|
||||
|
||||
def converge_nodes(clients, **workflow_input):
|
||||
workflow_client = clients.workflow_engine
|
||||
tripleoclients = clients.tripleoclient
|
||||
plan_name = workflow_input['container']
|
||||
|
||||
with tripleoclients.messaging_websocket() as ws:
|
||||
execution = base.start_workflow(
|
||||
workflow_client,
|
||||
'tripleo.package_update.v1.converge_upgrade_plan',
|
||||
workflow_input=workflow_input
|
||||
)
|
||||
|
||||
for payload in base.wait_for_messages(workflow_client, ws, execution):
|
||||
assert payload['status'] == "SUCCESS", pprint.pformat(payload)
|
||||
|
||||
orchestration_client = clients.orchestration
|
||||
|
||||
events = event_utils.get_events(orchestration_client,
|
||||
stack_id=plan_name,
|
||||
event_args={'sort_dir': 'desc',
|
||||
'limit': 1})
|
||||
marker = events[0].id if events else None
|
||||
|
||||
time.sleep(10)
|
||||
create_result = utils.wait_for_stack_ready(
|
||||
orchestration_client, plan_name, marker, 'UPDATE', 1)
|
||||
if not create_result:
|
||||
shell.OpenStackShell().run(["stack", "failures", "list", plan_name])
|
||||
raise exceptions.DeploymentError("Heat Stack update failed.")
|
||||
|
|
Loading…
Reference in New Issue