diff options
| author | Martin Schwenke <martin@meltin.net> | 2008-07-09 14:18:15 +1000 |
|---|---|---|
| committer | Martin Schwenke <martin@meltin.net> | 2008-07-09 14:18:15 +1000 |
| commit | 55ebe458ef799ef637cf442cf5cd451c79ab1b74 (patch) | |
| tree | b10d12984ef94f4e0a040472b33833dd6f2766b0 /ctdb/tools/onnode | |
| parent | 6bf597d061786ed4e2ca5b4309dde36982b7d577 (diff) | |
Complete rewrite of tools/onnode. Remove old tools/onnode.ssh,
tools/onnode.rsh.
(This used to be ctdb commit 6b67f180668c7a05c941b4891bd2486601790165)
Diffstat (limited to 'ctdb/tools/onnode')
| -rwxr-xr-x | ctdb/tools/onnode | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/ctdb/tools/onnode b/ctdb/tools/onnode new file mode 100755 index 0000000000..a94dd1e265 --- /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 |
