diff options
Diffstat (limited to 'ctdb')
-rwxr-xr-x | ctdb/tools/onnode | 194 | ||||
-rw-r--r-- | ctdb/tools/onnode.rsh | 44 | ||||
-rwxr-xr-x | ctdb/tools/onnode.ssh | 44 |
3 files changed, 194 insertions, 88 deletions
diff --git a/ctdb/tools/onnode b/ctdb/tools/onnode new file mode 100755 index 00000000000..a94dd1e2656 --- /dev/null +++ b/ctdb/tools/onnode @@ -0,0 +1,194 @@ +#!/bin/sh + +# Run commands on CTDB nodes. + +# See http://ctdb.samba.org/ for more information about CTDB. + +# Copyright (C) Martin Schwenke 2008 + +# Based on an earlier script by Andrew Tridgell and Ronnie Sahlberg. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. + +prog=$(basename $0) + +usage () +{ + cat >&2 <<EOF +Usage: onnode [ options ] <nodespec> <command> + + Options: + -c Run in current working directory on all nodes. + -p Run command in parallel on specified nodes. Implies -t. + -t Force tty allocation on nodes. Improves buffering. + -v Print node address even for a single node. + -q Do not print node addresses (overrides -v). + + <nodespec> all or a node number (0 base); or + list (comma separated) of <nodespec>; or + range (hyphen separated) of node numbers. +EOF + exit 1 + +} + +invalid_nodespec () +{ + echo "Invalid <nodespec>" >&2 ; echo >&2 + usage +} + +# Defaults. +current=false +parallel=false +force_tty=false +verbose=false +quiet=false + +parse_options () +{ + # $POSIXLY_CORRECT means that the command passed to onnode can + # take options and getopt won't reorder things to make them + # options ot onnode. + temp=$(POSIXLY_CORRECT=1 getopt -n "$prog" -o "cpqtv" -- "$@") + + [ $? != 0 ] && usage + + eval set -- "$temp" + + while true ; do + case "$1" in + -c) current=true ; shift ;; + -p) parallel=true ; force_tty=true ; shift ;; + -q) quiet=true ; shift ;; + -t) force_tty=true ; shift ;; + -v) verbose=true ; shift ;; + --) shift ; break ;; + *) usage ;; # Shouldn't happen, so this is reasonable. + esac + done + + [ $# -lt 2 ] && usage + + nodespec="$1" ; shift + command="$@" +} + +# Can probably be avoided if we use bash? +get_nth () +{ + n="$1" ; shift + + c=0 + for j ; do + if [ $n -eq $c ] ; then + echo $j + break + fi + c=$(($c + 1)) + done +} + +parse_nodespec () +{ + # Subshell avoids hacks to restore $IFS. + ( + IFS="," + for i in $1 ; do + case "$i" in + *-*) seq "${i%-*}" "${i#*-}" 2>/dev/null || invalid_nodespec ;; + all) echo all ;; + *) + [ $i -gt -1 ] 2>/dev/null || invalid_nodespec + echo $i + esac + done + ) +} + +get_nodes () +{ + [ -f "$CTDB_NODES_FILE" ] || CTDB_NODES_FILE=/etc/ctdb/nodes + all_nodes=$(egrep '^[[:alnum:]]' $CTDB_NODES_FILE) + + nodes="" + for n in $(parse_nodespec "$1") ; do + [ $? != 0 ] && exit 1 # Required to catch exit in above subshell. + case "$n" in + all) echo $all_nodes ;; + *) node=$(get_nth $n $all_nodes) + if [ -n "$node" ] ; then + echo $node + else + echo "${prog}: \"node ${n}\" does not exist" >&2 + exit 1 + fi + esac + + done +} + +###################################################################### + +parse_options "$@" + +$current && command="cd $PWD && $command" + +SSH_OPTS= +# Could "2>/dev/null || true" but want to see errors from typos in file. +[ -r /etc/ctdb/onnode.conf ] && . /etc/ctdb/onnode.conf +[ -n "$SSH" ] || SSH=ssh +if [ "$SSH" = "ssh" ] ; then + if $force_tty ; then + ssh_opts="-t" + else + ssh_opts="-n" + fi +else + : # rsh? All bets are off! +fi + +###################################################################### + +nodes=$(get_nodes "$nodespec") +[ $? != 0 ] && exit 1 # Required to catch exit in above subshell. + +if $quiet ; then + verbose=false +else + # If $nodes contains a space or a newline then assume multiple nodes. + nl=" +" + [ "$nodes" != "${nodes%[ ${nl}]*}" ] && verbose=true +fi + +pids="" +trap 'kill -TERM $pids 2>/dev/null' INT TERM +# There's a small race here where the kill can fail if no processes +# have been added to $pids and the script is interrupted. However, +# the part of the window where it matter is very small. +for n in $nodes ; do + if $verbose ; then + echo >&2 ; echo ">> NODE: $n <<" >&2 + fi + + if $parallel ; then + $SSH $ssh_opts $EXTRA_SSH_OPTS $n "$command" & + pids="${pids} $!" + else + $SSH $ssh_opts $EXTRA_SSH_OPTS $n "$command" + fi +done + +$parallel && wait diff --git a/ctdb/tools/onnode.rsh b/ctdb/tools/onnode.rsh deleted file mode 100644 index 593f5311138..00000000000 --- a/ctdb/tools/onnode.rsh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/sh -# onnode script for rsh - -if [ $# -lt 2 ]; then -cat <<EOF -Usage: onnode <nodenum|all> <command> -EOF -exit 1 -fi - -NODE="$1" -shift -SCRIPT="$@" - -NODES=/etc/ctdb/nodes - -NUMNODES=`egrep '^[[:alnum:]]' $NODES | wc -l` -MAXNODE=`expr $NUMNODES - 1` - -if [ $NODE = "all" ]; then - for a in `egrep '^[[:alnum:]]' $NODES`; do - echo; echo ">> NODE: $a <<" - if [ -f "$SCRIPT" ]; then - rsh $a at -f "$SCRIPT" now - else - rsh $a "$SCRIPT" - fi - done - exit 0 -fi - -if [ $NODE -gt $MAXNODE ]; then - echo "Node $NODE doesn't exist" - exit 1 -fi - -NODEPLUSONE=`expr $NODE + 1` -a=`egrep '^[[:alnum:]]' $NODES | head -$NODEPLUSONE | tail -1` - -if [ -f "$SCRIPT" ]; then - exec rsh $a at -f "$SCRIPT" now -else - exec rsh $a "$SCRIPT" -fi diff --git a/ctdb/tools/onnode.ssh b/ctdb/tools/onnode.ssh deleted file mode 100755 index 451711612a9..00000000000 --- a/ctdb/tools/onnode.ssh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/sh -# onnode script for ssh - -if [ $# -lt 2 ]; then -cat <<EOF -Usage: onnode <nodenum|all> <command> -EOF -exit 1 -fi - -NODE="$1" -shift -SCRIPT="$@" - -NODES=/etc/ctdb/nodes - -NUMNODES=`egrep '^[[:alnum:]]' $NODES | wc -l` -MAXNODE=`expr $NUMNODES - 1` - -if [ $NODE = "all" ]; then - for a in `egrep '^[[:alnum:]]' $NODES`; do - echo; echo ">> NODE: $a <<" - if [ -f "$SCRIPT" ]; then - ssh -n $a at -f "$SCRIPT" now - else - ssh -n $a "$SCRIPT" - fi - done - exit 0 -fi - -if [ $NODE -gt $MAXNODE ]; then - echo "Node $NODE doesn't exist" - exit 1 -fi - -NODEPLUSONE=`expr $NODE + 1` -a=`egrep '^[[:alnum:]]' $NODES | head -$NODEPLUSONE | tail -1` - -if [ -f "$SCRIPT" ]; then - exec ssh -n $a at -f "$SCRIPT" now -else - exec ssh -n $a "$SCRIPT" -fi |