Author: pwesolek
Date: Thu Dec 4 00:35:10 2008
New Revision: 86
Added:
trunk/distcomp/scripts/rshrunner.sh
Modified:
trunk/distcomp/scripts/rshknowhosts.sh
trunk/distcomp/scripts/rshlst.sh
trunk/distcomp/scripts/rshpar.sh
trunk/distcomp/scripts/rshseq.sh
Log:
Restructured rsh* scripts a lot; one common scenario put into rshrunner.sh,
other scripts simply define some hooks to be called in important places.
Modified: trunk/distcomp/scripts/rshknowhosts.sh
==============================================================================
--- trunk/distcomp/scripts/rshknowhosts.sh (original)
+++ trunk/distcomp/scripts/rshknowhosts.sh Thu Dec 4 00:35:10 2008
@@ -1,43 +1,20 @@
#!/bin/sh
-if [ $# -lt 1 ]; then
- echo "Feeds SSH's known_hosts with a list of hosts. Usage:"
- echo "$0 [ --ssh known_hosts ] hosts_file [username]"
- exit 1
-fi
+hook_usage_head="Feeds SSH's known_hosts with a list of hosts."
+hook_usage_args=""
-if [ "$1" == "--ssh" ]; then
- SSH_KNOWN_HOSTS_OPTS="-o UserKnownHostsFile=$2"
- shift
- shift
-else
- SSH_KNOWN_HOSTS_OPTS=''
-fi
+hook_specific_args() {
+ # allow host keys being added without asking
+ SSH_STRICT_HK=no
+}
+
+hook_foreach_host() {
+ ( ssh $SSH_OPTS $H "true" && echo $H ) > $TMP/$H.result &
+}
+
+hook_afterall_hosts() {
+ wait
+ cat $TMP/*.result | sort
+}
-HOSTS=$1
-shift
-
-if [ $# -lt 1 ]; then
- SSH_USER=$USER
-else
- SSH_USER=$1
-fi
-
-# Don't wait too long for inaccessible hosts.
-SSH_OPTS="-o ConnectTimeout=2 -o BatchMode=yes -o StrictHostKeyChecking=no
$SSH_KNOWN_HOSTS_OPTS"
-
-TMP=`mktemp -t -d`
-sed -e 's/#.*//' -e '/^[ \t]*$/d' $HOSTS > $TMP/hosts
-
-for H in `cat $TMP/hosts`
-do
- (ssh -q $SSH_OPTS -l $SSH_USER $H "true" && echo $H ) > $TMP/$H.result &
-done
-
-wait
-
-cat $TMP/*.result | sort
-
-if [ -e $TMP ]; then
- rm -rf $TMP
-fi
+. rshrunner.sh
Modified: trunk/distcomp/scripts/rshlst.sh
==============================================================================
--- trunk/distcomp/scripts/rshlst.sh (original)
+++ trunk/distcomp/scripts/rshlst.sh Thu Dec 4 00:35:10 2008
@@ -1,43 +1,20 @@
#!/bin/sh
-if [ $# -lt 1 ]; then
- echo "Lists SSH-accessible hosts. Usage:"
- echo "$0 [ --ssh known_hosts ] hosts_file [username]"
- exit 1
-fi
+hook_usage_head="Lists SSH-accessible hosts."
+hook_usage_args=""
-if [ "$1" == "--ssh" ]; then
- SSH_KNOWN_HOSTS_OPTS="-o UserKnownHostsFile=$2"
- shift
- shift
-else
- SSH_KNOWN_HOSTS_OPTS=''
-fi
+hook_specific_args() {
+ # forbid host keys being added
+ SSH_STRICT_HK=yes
+}
+
+hook_foreach_host() {
+ ( ssh $SSH_OPTS $H "true" && echo $H ) > $TMP/$H.result &
+}
+
+hook_afterall_hosts() {
+ wait
+ cat $TMP/*.result | sort
+}
-HOSTS=$1
-shift
-
-if [ $# -lt 1 ]; then
- SSH_USER=$USER
-else
- SSH_USER=$1
-fi
-
-# Don't wait too long for inaccessible hosts.
-SSH_OPTS="-o ConnectTimeout=2 -o BatchMode=yes -o StrictHostKeyChecking=yes
$SSH_KNOWN_HOSTS_OPTS"
-
-TMP=`mktemp -t -d`
-sed -e 's/#.*//' -e '/^[ \t]*$/d' $HOSTS > $TMP/hosts
-
-for H in `cat $TMP/hosts`
-do
- (ssh -q $SSH_OPTS -l $SSH_USER $H "true" && echo $H ) > $TMP/$H.result &
-done
-
-wait
-
-cat $TMP/*.result | sort
-
-if [ -e $TMP ]; then
- rm -rf $TMP
-fi
+. rshrunner.sh
Modified: trunk/distcomp/scripts/rshpar.sh
==============================================================================
--- trunk/distcomp/scripts/rshpar.sh (original)
+++ trunk/distcomp/scripts/rshpar.sh Thu Dec 4 00:35:10 2008
@@ -1,59 +1,43 @@
#!/bin/sh
-if [ $# -lt 2 ]; then
- echo "Executes the command in parallel. Usage:"
- echo "$0 [ -q | --quiet ] [ --ssh known_hosts ] hosts_file remote_command"
- exit 1
-fi
-
-if [ "$1" == "-q" -o "$1" == "--quiet" ]; then
- quiet=true
- shift
-fi
-
-if [ "$1" == "--ssh" ]; then
- SSH_KNOWN_HOSTS_OPTS="-o StrictHostKeyChecking=yes -o UserKnownHostsFile=$2"
- shift
- shift
-else
- SSH_KNOWN_HOSTS_OPTS=''
-fi
-
-HOSTS=$1
-shift
-
-SSH_OPTS="-o ConnectTimeout=2 -o BatchMode=yes $SSH_KNOWN_HOSTS_OPTS"
-
-TMP=`mktemp -t -d`
-sed -e 's/#.*//' -e '/^[ \t]*$/d' $HOSTS > $TMP/hosts
-
-for H in `cat $TMP/hosts`
-do
- ( ssh -q $SSH_OPTS $H "$*" && touch $TMP/$H.ok || touch $TMP/$H.failed )
>$TMP/$H.result 2>&1 &
-done
-
-wait
-
-if [ ! $quiet ]; then
- for OUT in `ls $TMP/*.result`
- do
- H=`basename $OUT .result`
- if [ -e $TMP/$H.ok ]; then
- echo "--- $H OK:"
- cat $OUT
- else
- echo "--- $H FAILED:"
- cat $OUT
- fi
- done
- echo
-fi
-
-# Calculate summary
-GOOD=`ls -l $TMP/*.ok 2>/dev/null | wc -l`
-BAD=`ls -l $TMP/*.failed 2>/dev/null | wc -l`
-echo "$GOOD successful, $BAD failed."
-
-if [ -e $TMP ]; then
- rm -rf $TMP
-fi
+hook_usage_head="Executes the command in parallel."
+hook_usage_args="remote_command"
+
+hook_specific_args() {
+ if [ $# -lt 1 ]; then
+ print_usage
+ exit 1
+ fi
+
+ # slurp the rest of command line
+ SSH_REMOTE_CMD="$*"
+ params_cnt=$#
+}
+
+hook_foreach_host() {
+ ( ssh $SSH_OPTS $H "$SSH_REMOTE_CMD" && touch $TMP/$H.ok || touch
$TMP/$H.failed ) >$TMP/$H.result 2>&1 &
+}
+
+hook_afterall_hosts() {
+ wait
+
+ if [ ! $quiet ]; then
+ for OUT in $TMP/*.result; do
+ H=`basename $OUT .result`
+ if [ -e $TMP/$H.ok ]; then
+ echo "--- $H OK:"
+ else
+ echo "--- $H FAILED:"
+ fi
+ cat $OUT
+ done
+ echo
+ fi
+
+ # Calculate summary
+ GOOD=`ls $TMP/*.ok 2>/dev/null | wc -l`
+ BAD=`ls $TMP/*.failed 2>/dev/null | wc -l`
+ echo "$GOOD successful, $BAD failed."
+}
+
+. rshrunner.sh
Added: trunk/distcomp/scripts/rshrunner.sh
==============================================================================
--- (empty file)
+++ trunk/distcomp/scripts/rshrunner.sh Thu Dec 4 00:35:10 2008
@@ -0,0 +1,133 @@
+#!/bin/sh
+
+##########
+# This file contains common code used in rsh* set of commands.
+#
+# If you want to write a custom script using this predefined code, you have to:
+# * define the following "hook" functions
+# - hook_specific_args(): for reading additional parameters from the command
+# line, after the default ones has been read, or for modifying variables
+# (see below). If reading additional command line parameters, $params_cnt
+# must be set to their number.
+# - hook_foreach_host(): what actions to perform for a single host. The most
+# common is to run ssh command (see examples). Host name is received in $H.
+# - hook_afterall_hosts(): additional actions (like waiting for ssh sessions
+# to end, cleanup) performed after `serving' the last host.
+# * define help-connected variables: $hook_usage_head for one-liner describing
+# scripts role, and $hook_usage_args for one-liner listing script-specific
+# command line arguments
+# * source this file, like
+# . rshrunner.sh
+#
+# If a specific hook is not required, it can be as simple as:
+# hook_something() ;
+# but it must occur.
+#
+# Variables, which are defined and used in this helper:
+# SSH_KNOWN_HOSTS -- if set, defines the hosts public key file to be used;
+# optional in the command line, can be overriden
+# SSH_USER -- defines username to use on SSH connections. Defaults to current
+# user's login; optional in the command line, can be overriden
+# quiet -- loosely-defined flag for quiet output. Optional in the command line,
+# can be overriden
+# SSH_COMMON_OPTS -- default options for SSH, hardcoded, can be overriden
+# HOSTS -- file keeping the list of hosts to operate on; set only after
+# hook_specific_args()
+# SSH_STRICT_HK -- whether it is forbidden to add new keys to the key file.
+# Defaults to system-wide setting (usually: ask for permission, which is
+# the same as denying in batch mode). When not explicitly set and
+# SSH_KNOWN_HOSTS is set, this is forced to be 'yes'. Can be overriden.
+# TMP -- temporary directory, can be used to store e.g. partial results. Read
+# only, set only after hook_specific_args().
+# H -- the host currently being processed. Read-only, available in
+# hook_foreach_host().
+##########
+
+# Parses command line options, which are common to all rsh* commands
+# and sets useful variables
+parse_common_opts() {
+ SSH_KNOWN_HOSTS=''
+ SSH_USER=$USER
+
+ params_cnt=0
+ while [[ $1 = -* ]]; do
+ p=1
+ case $1 in
+ (-q | --quiet)
+ quiet=true
+ ;;
+ --ssh)
+ SSH_KNOWN_HOSTS="$2"
+ p=2
+ ;;
+ --user)
+ SSH_USER="$2"
+ p=2
+ ;;
+ --help)
+ print_usage
+ exit 0
+ ;;
+ *)
+ echo "Ignoring unknown option: $1" 1>&2
+ ;;
+ esac
+ shift $p
+ params_cnt=$((params_cnt+p))
+ done
+}
+
+# Prints program usage
+print_usage() {
+ echo $hook_usage_head 1>&2
+ echo "Usage: $0 [ --help ] [ --quiet | -q ] [ --ssh known_hosts ] [ --user
username ] hosts_file $hook_usage_args" 1>&2
+}
+
+
+##########
+# Run
+
+SSH_COMMON_OPTS="-q -o ConnectTimeout=3 -o BatchMode=yes"
+
+parse_common_opts $@
+shift $params_cnt
+
+if [ $# -lt 1 ]; then
+ print_usage
+ exit 1
+fi
+
+HOSTS=$1
+shift
+
+params_cnt=0
+hook_specific_args $@
+shift $params_cnt
+
+SSH_OPTS="$SSH_COMMON_OPTS -l $SSH_USER"
+if [ "$SSH_KNOWN_HOSTS" != "" ]; then
+ SSH_OPTS="$SSH_OPTS -o UserKnownHostsFile=$SSH_KNOWN_HOSTS"
+ if [ "$SSH_STRICT_HK" == "" ]; then
+ SSH_STRICT_HK=yes
+ fi
+fi
+
+if [ "$SSH_STRICT_HK" != "" ]; then
+ SSH_OPTS="$SSH_OPTS -o StrictHostKeyChecking=$SSH_STRICT_HK"
+fi
+
+TMP=`mktemp -t -d`
+sed -e 's/#.*//' -e '/^[ \t]*$/d' $HOSTS > $TMP/hosts
+
+for H in `cat $TMP/hosts`; do
+ hook_foreach_host
+done
+
+hook_afterall_hosts
+
+if [ -e $TMP ]; then
+ rm -rf $TMP
+fi
+
+exit 0;
+
Modified: trunk/distcomp/scripts/rshseq.sh
==============================================================================
--- trunk/distcomp/scripts/rshseq.sh (original)
+++ trunk/distcomp/scripts/rshseq.sh Thu Dec 4 00:35:10 2008
@@ -1,50 +1,35 @@
#!/bin/sh
-if [ $# -lt 2 ]; then
- echo "Executes the command sequentially. Usage:"
- echo "$0 [ -q | --quiet ] [ --ssh known_hosts ] hosts_file remote_command"
- exit 1
-fi
+hook_usage_head="Executes the command sequentially."
+hook_usage_args="remote_command"
-if [ "$1" == "-q" -o "$1" == "--quiet" ]; then
- quiet=true
- shift
-fi
-
-if [ "$1" == "--ssh" ]; then
- SSH_KNOWN_HOSTS_OPTS="-o StrictHostKeyChecking=yes -o UserKnownHostsFile=$2"
- shift
- shift
-else
- SSH_KNOWN_HOSTS_OPTS=''
-fi
-
-HOSTS=$1
-shift
-
-SSH_OPTS="-o ConnectTimeout=2 -o BatchMode=yes $SSH_KNOWN_HOSTS_OPTS"
-
-TMP=`mktemp -t -d`
-sed -e 's/#.*//' -e '/^[ \t]*$/d' $HOSTS > $TMP/hosts
-
-for H in `cat $TMP/hosts`
-do
- if [ ! $quiet ]; then
- echo "--- $H:"
- ( ssh -q $SSH_OPTS $H "$*" && touch $TMP/$H.ok || touch $TMP/$H.failed
) 2>&1
- else
- ( ssh -q $SSH_OPTS $H "$*" && touch $TMP/$H.ok || touch $TMP/$H.failed
) >/dev/null 2>&1
-
- if [ -e $TMP/$H.ok ]; then echo -n "."; else echo -n "x"; fi
+hook_specific_args() {
+ if [ $# -lt 1 ]; then
+ print_usage
+ exit 1
+ fi
+
+ # slurp the rest of command line
+ SSH_REMOTE_CMD="$*"
+ params_cnt=$#
+}
+
+hook_foreach_host() {
+ if [ ! $quiet ]; then
+ echo "--- $H:"
+ ( ssh $SSH_OPTS $H "$SSH_REMOTE_CMD" && touch $TMP/$H.ok || touch
$TMP/$H.failed ) 2>&1
+ else
+ ( ssh $SSH_OPTS $H "$SSH_REMOTE_CMD" && touch $TMP/$H.ok || touch
$TMP/$H.failed ) >/dev/null 2>&1
+ if [ -e $TMP/$H.ok ]; then echo -n "."; else echo -n "x"; fi
fi
-done
+}
+hook_afterall_hosts() {
# Calculate summary
-GOOD=`ls -l $TMP/*.ok 2>/dev/null | wc -l`
-BAD=`ls -l $TMP/*.failed 2>/dev/null | wc -l`
-echo
-echo "$GOOD successful, $BAD failed."
+ # Calculate summary
+ GOOD=`ls $TMP/*.ok 2>/dev/null | wc -l`
+ BAD=`ls $TMP/*.failed 2>/dev/null | wc -l`
+ echo "$GOOD successful, $BAD failed."
+}
-if [ -e $TMP ]; then
- rm -rf $TMP
-fi
+. rshrunner.sh