summaryrefslogtreecommitdiffstats
path: root/ctdb
diff options
context:
space:
mode:
authorMartin Schwenke <martin@meltin.net>2008-07-09 14:18:15 +1000
committerMartin Schwenke <martin@meltin.net>2008-07-10 15:39:30 +1000
commitdb55b9131717aad044347422a9b77c6be51907ed (patch)
treef8baf39b1acb385010b3e36b0d15b6c64b4ae88c /ctdb
parenta89778c048df267b36b8a1912fc2cb8f04f5ca69 (diff)
downloadsamba-db55b9131717aad044347422a9b77c6be51907ed.tar.gz
samba-db55b9131717aad044347422a9b77c6be51907ed.tar.xz
samba-db55b9131717aad044347422a9b77c6be51907ed.zip
Complete rewrite of tools/onnode. Remove old tools/onnode.ssh,
tools/onnode.rsh. (This used to be ctdb commit 2cc9aba3d7e608eccc29c897f710b69f30653bbf)
Diffstat (limited to 'ctdb')
-rwxr-xr-xctdb/tools/onnode194
-rw-r--r--ctdb/tools/onnode.rsh44
-rwxr-xr-xctdb/tools/onnode.ssh44
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