971bc3298d
This patch adds a new parameter to configure the plan name when executing the "openstack overcloud config download" command. The default plan is as usual 'overcloud'. Change-Id: Icf5eb530b44553e3a79f6e0b7859b46ef08cc926 Closes-Bug: 1750338 Resolves: rhbz#1545415
218 lines
9.0 KiB
Bash
Executable File
218 lines
9.0 KiB
Bash
Executable File
#!/bin/bash
|
|
#set -x
|
|
# Copyright 2016 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.
|
|
#
|
|
# Utility script that will be invoked by the operator as part of the documented
|
|
# upgrades workflow. Those roles that have disable_upgrade_deployment set to
|
|
# true will have had a /root/tripleo_upgrade_node.sh script delivered during
|
|
# the composable ansible upgrade steps. This tripleo_upgrade_node.sh is then
|
|
# invoked over ssh by the operator using the simple utility delivered in this
|
|
# file. See -h for options.
|
|
#
|
|
set -eu
|
|
set -o pipefail
|
|
SCRIPT_NAME=$(basename $0)
|
|
|
|
#can make the upgrade script overridable (if a different target will be used)
|
|
UPGRADE_SCRIPT=${UPGRADE_SCRIPT:-/root/tripleo_upgrade_node.sh}
|
|
#allow override incase the ssh user is not 'heat-admin' - must be able to sudo
|
|
STACK_NAME_DEFAULT="overcloud"
|
|
STACK_NAME=${STACK_NAME:-$STACK_NAME_DEFAULT}
|
|
UPGRADE_NODE_USER_DEFAULT="heat-admin"
|
|
UPGRADE_NODE_USER=${UPGRADE_NODE_USER:-$UPGRADE_NODE_USER_DEFAULT}
|
|
UPGRADE_NODE=""
|
|
QUERY_NODE=""
|
|
HOSTNAME=""
|
|
IP_ADDR=""
|
|
INVENTORY=""
|
|
ANSIBLE_OPTS="" # e.g. "--skip-tags validation"
|
|
function show_options {
|
|
echo "Usage: $SCRIPT_NAME"
|
|
echo
|
|
echo "Options:"
|
|
echo " -h|--help -- print this help."
|
|
echo " -u|--upgrade <nova node> -- nova node name or id or ctlplane IP"
|
|
echo " to upgrade."
|
|
echo " -q|--query <nova node> -- check if the node is ACTIVE and tail"
|
|
echo " yum.log for any package update info."
|
|
echo " -s|--stack-name <stack name> -- the stack name, defaults to $STACK_NAME_DEFAULT"
|
|
echo " -I|--inventory <path> -- use the specified tripleo ansible "
|
|
echo " inventory (yaml format)."
|
|
echo " -O|--ansible-opts \"opts\" -- specify extra options to be passed "
|
|
echo " to ansible-playbook e.g. \"-vvv\" or "
|
|
echo " \"-vvv --skip-tags validation\"."
|
|
echo " -U|--overcloud-user <name> -- the user with which to ssh to the"
|
|
echo " target upgrade node - defaults to"
|
|
echo " $UPGRADE_NODE_USER_DEFAULT."
|
|
echo
|
|
echo "Invoke the /root/tripleo_upgrade_node.sh script on roles that have"
|
|
echo "the 'disable_upgrade_deployment' flag set true and then download and"
|
|
echo "execute the upgrade and deployment steps ansible playbooks."
|
|
echo
|
|
echo "The tripleo_upgrade_node.sh is delivered to the 'disable_upgrade_deployment'"
|
|
echo "nodes, when you execute the composable upgrade steps on the "
|
|
echo "controlplane nodes (i.e. the first step of the upgrade process). "
|
|
echo
|
|
echo "This utility is then used by the operator to invoke the upgrade workflow"
|
|
echo "by named node (nova name or uuid) on the 'disable_upgrade_deployment'"
|
|
echo "nodes. You can use the nova UUID, name or an IP address on the provisioning"
|
|
echo "network (e.g. for split stack deployments)."
|
|
echo
|
|
echo "Logfiles are generated in the"
|
|
echo "current working directory by node name/UUID/IP as appropriate."
|
|
echo
|
|
echo "Example invocations:"
|
|
echo
|
|
echo " upgrade-non-controller.sh --upgrade overcloud-compute-0 "
|
|
echo " upgrade-non-controller.sh -u 734eea90-087b-4f12-9cd9-4807da83ea78 "
|
|
echo " upgrade-non-controller.sh -u 192.168.24.15 "
|
|
echo " upgrade-non-controller.sh -U stack -u 192.168.24.15 -s overcloud"
|
|
echo " upgrade-non-controller.sh -U stack -u 192.168.24.16 \ "
|
|
echo " -I /home/stack/tripleo-ansible-inventory.yaml"
|
|
echo " upgrade-non-controller.sh -U stack -u 192.168.24.16 \ "
|
|
echo " -I /home/stack/tripleo-ansible-inventory.yaml \ "
|
|
echo " -O \"-vvv --skip-tags validation\" "
|
|
echo
|
|
echo "You can run on multiple nodes in parallel: "
|
|
|
|
echo " for i in \$(seq 0 2); do "
|
|
echo " upgrade-non-controller.sh --upgrade overcloud-compute-\$i &"
|
|
echo " # Remove the '&' above to have these upgrade in sequence"
|
|
echo " done"
|
|
echo
|
|
exit $1
|
|
}
|
|
|
|
TEMP=`getopt -o h,u:,q:,s:,U:,I:,O: -l help,upgrade:,query:,stack-name:,overcloud-user:,inventory:,ansible-opts: -n $SCRIPT_NAME -- "$@"`
|
|
|
|
if [ $? != 0 ]; then
|
|
echo "Terminating..." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Note the quotes around `$TEMP': they are essential!
|
|
eval set -- "$TEMP"
|
|
|
|
while true ; do
|
|
case "$1" in
|
|
-h | --help ) show_options 0 >&2;;
|
|
-u | --upgrade ) UPGRADE_NODE="$2" ; shift 2 ;;
|
|
-q | --query ) QUERY_NODE="$2" ; shift 2 ;;
|
|
-s | --stack-name ) STACK_NAME="$2" ; shift 2 ;;
|
|
-U | --overcloud-user ) UPGRADE_NODE_USER="$2"; shift 2;;
|
|
-I | --inventory ) INVENTORY="$2"; shift 2;;
|
|
-O | --ansible-opts ) ANSIBLE_OPTS="$2"; shift 2;;
|
|
-- ) shift ; break ;;
|
|
* ) echo "Error: unsupported option $1." ; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
LOGFILE="$SCRIPT_NAME"-$UPGRADE_NODE$QUERY_NODE
|
|
function log {
|
|
echo "`date` $SCRIPT_NAME $1" 2>&1 | tee -a $LOGFILE
|
|
}
|
|
|
|
if [[ -n $UPGRADE_NODE$QUERY_NODE ]]; then
|
|
log "Logging to $LOGFILE"
|
|
fi
|
|
|
|
function reset_hostname_ip {
|
|
HOSTNAME=""
|
|
IP_ADDR=""
|
|
}
|
|
|
|
# find_node_by_name_id_or_ip expects one parameter that is the nova name,
|
|
# uuid or cltplane IP address of the node we want to upgrade.
|
|
# The function will try and determine the hostname and (ctlplane) IP address
|
|
# for that node and assign these values to the global HOSTNAME and IP_ADDR.
|
|
# These variables are thus reset at the outset.
|
|
function find_node_by_name_id_or_ip {
|
|
reset_hostname_ip
|
|
name_id_or_ip=$1
|
|
# First try as a nova node name or UUID. Could also be an IP (split stack)
|
|
set +e # dont want to fail if nova or ping does below
|
|
nova_name=$(openstack server show $name_id_or_ip -f value -c name)
|
|
if [[ -n $nova_name ]]; then
|
|
set -e
|
|
HOSTNAME=$nova_name
|
|
addr_string=$(openstack server show $name_id_or_ip -f value -c addresses)
|
|
IP_ADDR=${addr_string#*=} # remove the ctlpane from ctlplane=192.168.24.11
|
|
log "nova node $HOSTNAME found with IP $IP_ADDR "
|
|
else
|
|
log "$name_id_or_ip not known to nova. Trying it as an IP address"
|
|
if ping -c1 $name_id_or_ip ; then
|
|
set -e
|
|
HOSTNAME=$(ssh $UPGRADE_NODE_USER@$name_id_or_ip hostname)
|
|
IP_ADDR=$name_id_or_ip
|
|
log "node $HOSTNAME found with address $IP_ADDR "
|
|
else
|
|
set -e
|
|
log "ERROR $name_id_or_ip not known to nova or not responding to ping if it is an IP address. Exiting"
|
|
exit 1
|
|
fi
|
|
fi
|
|
set -e
|
|
}
|
|
|
|
# Generate static tripleo ansible inventory. This is mainly to deal with different
|
|
# ssh user for the ansible playbooks, e.g. in a split stack environment.
|
|
# $1 is the path for to write the tripleo-ansible-inventory to
|
|
function get_static_inventory {
|
|
local config_dir=$1
|
|
if [ -d "$config_dir" ] ;then
|
|
local inventory_args=" --static-yaml-inventory $config_dir/tripleo-ansible-inventory.yaml"
|
|
if [[ $UPGRADE_NODE_USER != $UPGRADE_NODE_USER_DEFAULT ]]; then
|
|
inventory_args+=" --ansible_ssh_user $UPGRADE_NODE_USER"
|
|
fi
|
|
log "Generating static tripleo-ansible-inventory with these args: $inventory_args"
|
|
/usr/bin/tripleo-ansible-inventory $inventory_args
|
|
else
|
|
log "ERROR can't generate tripleo-ansible-inventory - cannot find $config_dir"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
function run_ansible_playbook {
|
|
local playbook=$UPGRADE_NODE/$1
|
|
full_args=" -b --limit $HOSTNAME --inventory $INVENTORY $ANSIBLE_OPTS $playbook"
|
|
log "Running ansible-playbook with $full_args"
|
|
ansible-playbook $full_args 2>&1 | tee -a $LOGFILE
|
|
}
|
|
|
|
if [ -n "$UPGRADE_NODE" ]; then
|
|
find_node_by_name_id_or_ip $UPGRADE_NODE
|
|
log "Executing $UPGRADE_SCRIPT on $IP_ADDR"
|
|
ssh $UPGRADE_NODE_USER@$IP_ADDR sudo $UPGRADE_SCRIPT 2>&1 | tee -a $LOGFILE
|
|
log "Clearing any existing dir $UPGRADE_NODE and downloading config"
|
|
rm -rf $UPGRADE_NODE
|
|
openstack overcloud config download --name "$STACK_NAME" --config-dir "$UPGRADE_NODE"
|
|
config_dir=$(ls -1 $UPGRADE_NODE)
|
|
if [ -z "$INVENTORY" ]; then
|
|
get_static_inventory $UPGRADE_NODE/$config_dir
|
|
INVENTORY="$UPGRADE_NODE/$config_dir/tripleo-ansible-inventory.yaml"
|
|
fi
|
|
for book in upgrade_steps_playbook.yaml deploy_steps_playbook.yaml ; do
|
|
run_ansible_playbook $config_dir/$book
|
|
done
|
|
fi
|
|
|
|
if [ -n "$QUERY_NODE" ]; then
|
|
# check node exists, check for upgrade script
|
|
find_node_by_name_id_or_ip $QUERY_NODE
|
|
log "We can't remotely tell if the upgrade has run on $QUERY_NODE."
|
|
log "We can check for package updates... trying to tail yum.log on $QUERY_NODE:"
|
|
ssh $UPGRADE_NODE_USER@$IP_ADDR "sudo tail /var/log/yum.log" 2>&1 | tee -a $LOGFILE
|
|
fi
|