# 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 uuid 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('--nodes', action="store", default=None, help=_('Nodes to update.') ) parser.add_argument('--playbook', action="store", default="update_steps_playbook.yaml", help=_('Playbook to use for update') ) parser.add_argument('--generate-inventory', dest='generate_inventory', action='store_true', default=True, help=_("Generate inventory for the ansible " "playbook"), ) parser.add_argument('--static-inventory', dest='static_inventory', action="store", default='tripleo-hosts-inventory', help=_('Path to the static inventory to use') ) 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: raise exceptions.InvalidConfiguration( "You need to provide a container registry file in order " "to update your current containers deployed.") # Execute minor update package_update.update(clients, container=stack_name, container_registry=registry, queue_name=str(uuid.uuid4())) print("Minor update init on stack {0} complete.".format( parsed_args.stack)) # Run ansible: nodes = parsed_args.nodes playbook = parsed_args.playbook if nodes is not None: inventory_path = '%s/%s' % (os.path.expanduser('~'), parsed_args.static_inventory) if parsed_args.generate_inventory: try: processutils.execute('/bin/tripleo-ansible-inventory', '--static-inventory', inventory_path) except processutils.ProcessExecutionError as e: message = "Failed to generate inventory file: %s" % str(e) raise exceptions.InvalidConfiguration(message) if os.path.exists(inventory_path): inventory = open(inventory_path, 'r').read() else: raise exceptions.InvalidConfiguration( "Inventory file missing, provide an inventory file or " "generate an inventory by using the --generate-inventory " "option") output = package_update.update_ansible( clients, nodes=nodes, inventory_file=inventory, playbook=playbook, queue_name=str(uuid.uuid4())) print(output)