#!/bin/bash hosts= group= user=root pdsh=`which pdsh 2>/dev/null` ssh=`which qarsh 2>/dev/null` scp=`which qacp 2>/dev/null` command=list format=oneline replace="{}" if [ x$ssh = "x" ]; then ssh=ssh scp=scp fi function helptext() { echo "cluster-helper - A tool for running commands on multiple hosts" echo "" echo "Attempt to use pdsh, qarsh, or ssh (in that order) to execute commands" echo "on mutiple hosts" echo "" echo "DSH groups can be configured and specified with -g instead of listing" echo "the individual hosts every time" echo "" echo "Usage: cluster-helper [options] [command]" echo "" echo "Options:" echo "--ssh Force the use of ssh instead of qarsh even if it available" echo "-g, --group Specify the group to operate on/with" echo "-w, --host Specify a host to operate on/with. May be specified multiple times" echo "-f, --format Specifiy the output format When listing hosts or group contents" echo " Allowed values: [oneline], long, short, pdsh, bullet" echo "" echo "" echo "Commands:" echo "--list format List the contents of a group in the specified format" echo "--add name Add supplied (-w) hosts to the named group" echo "--create name Create the named group with the supplied (-w) hosts" echo "--run, -- Treat all subsequent arguments as a command to perform on" echo " the specified command on the hosts or group" echo "--xargs Run the supplied command having replaced any occurances" echo " of {} with the node name" echo "" echo "--copy file(s) host:file Pass subsequent arguments to scp or qacp" echo " Any occurances of {} are replaced with the node name" echo "" exit $1 } while true ; do case "$1" in --help|-h|-\?) helptext 0;; -x) set -x; shift;; --ssh) ssh="ssh"; scp="scp"; shift;; -g|--group) group="$2"; shift; shift;; -w|--host) for h in $2; do hosts="$hosts -w $h"; done shift; shift;; -f|--format) format=$2; shift; shift;; -I) replace=$2; shift; shift;; --list|list) format=$2; command=list; shift; shift;; --add|add) command=group-add; shift;; --create|create) group="$2", command=group-create; shift; shift;; --run|run) command=run; shift;; --copy|copy) command=copy; shift; break ;; --xargs) command=xargs; shift; break ;; --) command=run; shift; break ;; "") break;; *) helptext 1;; esac done if [ x"$group" = x -a x"$hosts" = x ]; then group=$CTS_GROUP fi function expand() { fmt=$1 if [ x$group != x -a -f ~/.dsh/group/$group ]; then hosts=`cat ~/.dsh/group/$group` elif [ x$group != x ]; then echo "Unknown group: $group" >&2 exit 1 fi if [ "x$hosts" != x -a $fmt = oneline ]; then echo $hosts elif [ "x$hosts" != x -a $fmt = short ]; then ( for h in $hosts; do echo $h | sed 's:\..*::' done ) | tr '\n' ' ' echo "" elif [ "x$hosts" != x -a $fmt = pdsh ]; then ( for h in $hosts; do echo "-w $h" done ) | tr '\n' ' ' echo "" elif [ "x$hosts" != x -a $fmt = long ]; then for h in $hosts; do echo $h done elif [ "x$hosts" != x -a $fmt = bullet ]; then for h in $hosts; do echo " * $h" done elif [ "x$hosts" != x ]; then echo "Unknown format: $fmt" >&2 fi } if [ $command = list ]; then expand $format elif [ $command = group-create ]; then f=`mktemp` mkdir -p ~/.dsh/group if [ -f ~/.dsh/group/$group ]; then echo "Overwriting existing group $group" fi for h in $hosts; do echo $h >> $f done echo "Creating group $group in ~/.dsh/group" sort -u $f > ~/.dsh/group/$group rm -f $f elif [ $command = group-add ]; then if [ x$group = x ]; then echo "Please specify a group to append to" exit 1 fi f=`mktemp` mkdir -p ~/.dsh/group if [ -f ~/.dsh/group/$group ]; then cat ~/.dsh/group/$group > $f fi for h in $hosts; do echo $h >> $f done echo "Appending hosts to group $group in ~/.dsh/group" sort -u $f > ~/.dsh/group/$group rm -f $f elif [ $command = run ]; then if [ x$pdsh != x ]; then hosts=`expand pdsh` $pdsh -l $user $hosts -- $* else hosts=`expand oneline` for n in $hosts; do $ssh -l $user $n -- $* < /dev/null done if [ x"$hosts" = x ]; then echo "No hosts specified" fi fi elif [ $command = copy ]; then hosts=`expand oneline` for n in $hosts; do $scp `echo $* | sed 's@'$replace'@'$n'@'` done elif [ $command = xargs ]; then hosts=`expand oneline` for n in $hosts; do eval `echo $* | sed 's@'$replace'@'$n'@'` done fi