1#!/bin/bash
2
3hosts=
4group=$cluster_name
5user=root
6pdsh=`which pdsh 2>/dev/null`
7ssh=`which qarsh 2>/dev/null`
8scp=`which qacp 2>/dev/null`
9command=list
10format=oneline
11replace="{}"
12
13if [ x$ssh = "x" ]; then
14    ssh=ssh
15    scp=scp
16fi
17
18function helptext() {
19    echo "cluster-helper - A tool for running commands on multiple hosts"
20    echo ""
21    echo "Attempt to use pdsh, qarsh, or ssh (in that order) to execute commands"
22    echo "on multiple hosts"
23    echo ""
24    echo "DSH groups can be configured and specified with -g instead of listing"
25    echo "the individual hosts every time"
26    echo ""
27    echo "Usage: cluster-helper [options] [command]"
28    echo ""
29    echo "Options:"
30    echo "--ssh            Force the use of ssh instead of qarsh even if it available"
31    echo "-g, --group      Specify the group to operate on/with"
32    echo "-w, --host       Specify a host to operate on/with.  May be specified multiple times"
33    echo "-f, --format     Specifiy the output format When listing hosts or group contents"
34    echo "                 Allowed values: [oneline], long, short, pdsh, bullet"
35    echo ""
36    echo ""
37    echo "Commands:"
38    echo "--list   format  List the contents of a group in the specified format"
39    echo "--add    name    Add supplied (-w) hosts to the named group"
40    echo "--create name    Create the named group with the supplied (-w) hosts"
41    echo "--run, --        Treat all subsequent arguments as a command to perform on"
42    echo "                 the specified command on the hosts or group"
43    echo "--xargs          Run the supplied command having replaced any occurrences"
44    echo "                 of {} with the node name"
45    echo ""
46    echo "--copy file(s) host:file   Pass subsequent arguments to scp or qacp"
47    echo "                           Any occurrences of {} are replaced with the node name"
48    echo "--key            Install an ssh key"
49    echo ""
50    exit $1
51}
52
53while true ; do
54    case "$1" in
55	--help|-h|-\?) helptext 0;;
56	-x)  set -x; shift;;
57	--ssh) ssh="ssh"; scp="scp"; pdsh=""; shift;;
58	-g|--group) group="$2"; shift; shift;;
59	-w|--host) for h in $2; do
60		hosts="$hosts $h";
61	    done
62	    shift; shift;;
63	-f|--format) format=$2; shift; shift;;
64	-I) replace=$2; shift; shift;;
65	--list|list) format=$2; command=list; shift; shift;;
66	--add|add) command=group-add; shift;;
67	--create|create) group="$2", command=group-create; shift; shift;;
68	--run|run) command=run; shift;;
69	--copy|copy) command=copy; shift; break ;;
70	--key|key) command=key; shift; break ;;
71	--xargs) command=xargs; shift; break ;;
72	--) command=run; shift; break ;;
73	"") break;;
74	*) helptext 1;;
75    esac
76done
77
78if [ x"$group" = x -a x"$hosts" = x ]; then
79    group=$CTS_GROUP
80fi
81
82function expand() {
83    fmt=$1
84    if [ x$group != x -a -f ~/.dsh/group/$group ]; then
85	hosts=`cat ~/.dsh/group/$group`
86    elif [ x$group != x ]; then
87	echo "Unknown group: $group" >&2
88	exit 1
89    fi
90
91    if [ "x$hosts" != x -a $fmt = oneline ]; then
92	echo $hosts
93
94    elif [ "x$hosts" != x -a $fmt = short ]; then
95	( for h in $hosts; do
96		echo $h | sed 's:\..*::'
97		done ) | tr '\n' ' '
98	echo ""
99
100    elif [ "x$hosts" != x -a $fmt = pdsh ]; then
101	( for h in $hosts; do
102		echo "-w $h"
103	    done ) | tr '\n' ' '
104	echo ""
105
106    elif [ "x$hosts" != x -a $fmt = long ]; then
107	for h in $hosts; do
108	    echo $h
109	done
110
111    elif [ "x$hosts" != x -a $fmt = bullet ]; then
112	for h in $hosts; do
113	    echo " * $h"
114	done
115
116    elif [ "x$hosts" != x ]; then
117	echo "Unknown format: $fmt" >&2
118    fi
119}
120
121if [ $command = list ]; then
122    expand $format
123
124elif [ $command = key ]; then
125    hosts=`expand oneline`
126    for h in $hosts; do
127	ssh-copy-id root@$h
128    done
129
130elif [ $command = group-create ]; then
131
132    f=`mktemp`
133    mkdir -p ~/.dsh/group
134
135    if [ -f ~/.dsh/group/$group ]; then
136	echo "Overwriting existing group $group"
137    fi
138
139    for h in $hosts; do
140	echo $h >> $f
141    done
142
143    echo "Creating group $group in ~/.dsh/group"
144    sort -u $f > ~/.dsh/group/$group
145    rm -f $f
146
147elif [ $command = group-add ]; then
148    if [ x$group = x ]; then
149	echo "Please specify a group to append to"
150	exit 1
151    fi
152
153    f=`mktemp`
154    mkdir -p ~/.dsh/group
155
156    if [ -f ~/.dsh/group/$group ]; then
157	cat ~/.dsh/group/$group > $f
158    fi
159
160    for h in $hosts; do
161	echo $h >> $f
162    done
163
164    echo "Appending hosts to group $group in ~/.dsh/group"
165    sort -u $f > ~/.dsh/group/$group
166    rm -f $f
167
168elif [ $command = run ]; then
169    if [ x$pdsh != x ]; then
170	hosts=`expand pdsh`
171	$pdsh -l $user $hosts -- $*
172
173    else
174	hosts=`expand oneline`
175	for n in $hosts; do
176	    $ssh -l $user $n -- $* < /dev/null
177	done
178	if [ x"$hosts" = x ]; then
179	    echo "No hosts specified"
180	fi
181    fi
182elif [ $command = copy ]; then
183    hosts=`expand oneline`
184    for n in $hosts; do
185	$scp `echo $* | sed 's@'$replace'@'$n'@'`
186    done
187
188elif [ $command = xargs ]; then
189    hosts=`expand oneline`
190    for n in $hosts; do
191	eval `echo $* | sed 's@'$replace'@'$n'@'`
192    done
193fi
194