
Consume the update zaqar queue to get the ansible output in real time. The queue used is not the 'tripleo' queue because we need to not be disrupt by other messages. We need to claim all the zaqar messages in the queue to get a consistent ansible output Change-Id: I3682051eb719f8da9c744f7ec8be3a58f3db3f86 Closes-Bug: 1732497
148 lines
6.6 KiB
Python
148 lines
6.6 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 logging
|
|
import os
|
|
import yaml
|
|
|
|
|
|
from osc_lib.command import command
|
|
from osc_lib.i18n import _
|
|
from oslo_concurrency import processutils
|
|
|
|
from tripleoclient import constants
|
|
from tripleoclient import exceptions
|
|
from tripleoclient import utils as oooutils
|
|
from tripleoclient.workflows import package_update
|
|
|
|
|
|
class UpdateOvercloud(command.Command):
|
|
"""Updates packages on overcloud nodes"""
|
|
|
|
log = logging.getLogger(__name__ + ".UpdateOvercloud")
|
|
|
|
def get_parser(self, prog_name):
|
|
parser = super(UpdateOvercloud, self).get_parser(prog_name)
|
|
parser.add_argument('--stack',
|
|
nargs='?',
|
|
dest='stack',
|
|
help=_('Name or ID of heat stack to scale '
|
|
'(default=Env: OVERCLOUD_STACK_NAME)'),
|
|
default='overcloud'
|
|
)
|
|
parser.add_argument('--templates',
|
|
nargs='?',
|
|
default=constants.TRIPLEO_HEAT_TEMPLATES,
|
|
help=_("The directory containing the Heat"
|
|
"templates to deploy. "),
|
|
)
|
|
parser.add_argument('--init-minor-update',
|
|
dest='init_minor_update',
|
|
action='store_true',
|
|
help=_("Init the minor update heat config output."
|
|
"Needs to be run only once"),
|
|
)
|
|
parser.add_argument('--container-registry-file',
|
|
dest='container_registry_file',
|
|
default=None,
|
|
help=_("File which contains the container "
|
|
"registry data for the update"),
|
|
)
|
|
parser.add_argument('--ceph-ansible-playbook',
|
|
action="store",
|
|
default="/usr/share/ceph-ansible/infrastructure-"
|
|
"playbooks/rolling_update.yml",
|
|
help=_('Path to switch the ceph-ansible playbook '
|
|
'used for update. This value should be set '
|
|
'during the init-minor-update step.')
|
|
)
|
|
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.')
|
|
)
|
|
parser.add_argument('--playbook',
|
|
action="store",
|
|
default="update_steps_playbook.yaml",
|
|
help=_('Playbook to use for update')
|
|
)
|
|
parser.add_argument('--static-inventory',
|
|
dest='static_inventory',
|
|
action="store",
|
|
default=None,
|
|
help=_('Path to an existing ansible inventory to '
|
|
'use. If not specified, one will be '
|
|
'generated in ~/tripleo-ansible-inventory')
|
|
)
|
|
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
|
|
container_registry = parsed_args.container_registry_file
|
|
|
|
if parsed_args.init_minor_update:
|
|
# Update the container registry:
|
|
if container_registry:
|
|
with open(os.path.abspath(container_registry)) as content:
|
|
registry = yaml.load(content.read())
|
|
else:
|
|
self.log.warning(
|
|
"You have not provided a container registry file. Note "
|
|
"that none of the containers on your environement will be "
|
|
"updated. If you want to update your container you have "
|
|
"to re-run this command and provide the registry file "
|
|
"with: --container-registry-file option.")
|
|
registry = None
|
|
# Execute minor 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("Minor update init on stack {0} complete.".format(
|
|
parsed_args.stack))
|
|
else:
|
|
# Run ansible:
|
|
nodes = parsed_args.nodes
|
|
playbook = parsed_args.playbook
|
|
inventory_file = parsed_args.static_inventory
|
|
if inventory_file is None:
|
|
inventory_file = '%s/%s' % (os.path.expanduser('~'),
|
|
'tripleo-ansible-inventory')
|
|
try:
|
|
processutils.execute('/bin/tripleo-ansible-inventory',
|
|
'--static-inventory', inventory_file)
|
|
except processutils.ProcessExecutionError as e:
|
|
message = "Failed to generate inventory: %s" % str(e)
|
|
raise exceptions.InvalidConfiguration(message)
|
|
if os.path.exists(inventory_file):
|
|
inventory = open(inventory_file, 'r').read()
|
|
else:
|
|
raise exceptions.InvalidConfiguration(
|
|
"Inventory file %s can not be found." % inventory_file)
|
|
package_update.update_ansible(
|
|
clients, nodes=nodes,
|
|
inventory_file=inventory,
|
|
playbook=playbook,
|
|
ansible_queue_name=constants.UPDATE_QUEUE)
|