#!/bin/bash -e

# Usage: upgradebest.sh [-e ssh_options] [-c command] [server ...]
#
# Executes "sudo aptitude -y upgrade" or some arbitrary other
# command on a list of servers. If the command starts with
# "sudo", a password is requested which will be used to get
# sudo permissions.
#
# The script is most useful when used with public key ssh authentication.
#
# You can customize the default values at the beginning of the script.
#
# Examples:
#   upgradebest.sh              -- Upgrade all servers
#   upgradebest.sh cluj-mx gent -- Upgrade only cluj-mx.example.com and gent.example.com
#   upgradebest.sh -c "sudo a b c" tallinn lisbon
#                               -- Execute "sudo a b c" on tallinn.example.com and lisbon.example.com
#   upgradebest.sh -e "-l username"
#                               -- Upgrade all servers, logging in as user "username"
#
# Author: Heinrich Moser, mail@heinzi.at
# Version: 1.2, 2007-09-03

# Default ssh_options, if no -e is given
SSH_OPTIONS=""

# Default command, if no -c is given -- just upgrade the server
COMMAND="sudo aptitude -y upgrade"

# Default list of servers
SERVERS="cluj-mx gent gent-mx lisbon"

# Default suffix to add to all server names (default list and command line)
DOMAIN=".example.com"

leave_usage() { # show usage message and exit with error
    echo "Usage: upgradebest.sh [-e ssh_options] [-c command] [server ...]"
    exit 1
}

# Parse command line arguments
while getopts ":e:c:" options; do
    case "$options" in
	'e' ) SSH_OPTIONS=$OPTARG;;
	'c' ) COMMAND=$OPTARG;;
	'?' ) echo "Invalid option -$OPTARG"; leave_usage;;
	':' ) echo "Option -$OPTARG requires an argument."; leave_usage;;
        * ) echo "This line should never be reached."; exit 1;;
    esac
done
shift $(($OPTIND - 1)) # let $1 be first non-option argument

# The rest of the command line specifies the list of servers
if [ -n "$1" ]; then
	SERVERS=$@
fi

# Test whether sudo is required
[[ "$COMMAND" =~ "^sudo" ]] && SUDO=yes || SUDO=no

# If sudo is performed, read password required for sudo
[ "$SUDO" = "yes" ] && read -rsp 'sudo password: ' PWD

for s in $SERVERS; do
	SERVER=$s$DOMAIN
	echo "--- Executing \"$COMMAND\" on $SERVER ---"

	# Get sudo rights (if required),
	# then connect again (with pseudo-terminal) and upgrade
	if [ "$SUDO" = "yes" ]; then
		if ! echo $PWD | \
		    ssh -o "ConnectTimeout 10" $SSH_OPTIONS $SERVER "sudo -k; sudo -v"; then
			echo "Error connecting to $SERVER!"
			continue
		fi
	fi
	ssh -to "ConnectTimeout 10" $SSH_OPTIONS $SERVER "$COMMAND" \
	    || echo "Return value: $?"
done

