#!/bin/sh
#
# NAME
#   
#   clustcmd -- run a command on a sequence of cluster nodes  
#
# SYNOPSIS
#
#   clustcmd [OPTIONS] <cmd>
#   clustcmd [OPTIONS] -c <f1> <f2>
#
#   clustcmd runs <cmd> on all the cluster nodes, or an optional
#   subsequence of cluster nodes, sequentially.  clustcmd requires
#   ssh-style authentication to be set up, to work sensibly.
#
#   The second form of the command, with the -c flag, copies local
#   file <f1> to file or directory <f2> on all the specified hosts.  
#   <f2> should generally include an a full local path, to make sure 
#   <f1> goes where it is wanted.
#
# OPTIONS
#
#   -e        echo the ssh calls before doing them
#   -s        print a spacer between the ssh calls
#   -n n1 n2  run <cmd> on cluster nodes n1 thru n2
#   -c        copy local file <f1> to <f2> on the specified hosts
#
# EXAMPLES
#
#      clustcmd uptime
#
#   Prints the uptime for each node.
#
#      clustcmd -n 19 24 'ls /airs/s1/motteler/*.dat'
#
#   Lists user's *.dat files on airs19 thru 24.  By quoting the 
#   command with single quotes, the wildcard is expanded on the 
#   cluster nodes rather than locally.
#   
# H. Motteler, 30 Sep 03
#

# script name
sname=`basename $0`

# process command line options
eflag=0  # flag to echo the ssh command
sflag=0  # flag to print a spacer between commands
cflag=0  # flag to do an scp instead of ssh command
n1=1     # default first node
n2=32    # default last node
while true
do
  case $1 in
    -e)  eflag=1; shift ;;
    -s)  sflag=1; shift ;;
    -c)  cflag=1; shift ;;
    -n)  shift; n1=$1; shift; n2=$1; shift ;;
    -*)  echo "$sname ERROR -- unknown option $1"; exit 1 ;;
    *)   break ;;
  esac
done

# check for empty command
if test -z "$*"
then
  echo "$sname ERROR -- empty command"
  echo "usage example: $sname -n 19 24 df -m /airs/s1"
  exit 1
fi

# check numeric parameters
nlist=`seq $n1 $n2 2> /dev/null` 
if test $? -ne 0
then
  echo "$sname ERROR -- bad number params"
  echo "usage example: $sname -n 19 24 df -m /airs/s1"
  exit 1
fi

# check asl.localnet to see if local net is accessible 
ping -qc1 blade33 > /dev/null 2>&1
if test $? -ne 0
then
  echo "$sname ERROR -- cluster network is not accessible"
  exit 1
fi

# do the ssh commands
for i in $nlist
do
  if test $sflag -eq 1
  then
    echo "============ blade$i	========================================="
  fi

  # options to echo the ssh or scp command
  if test $eflag -eq 1
  then
    if test $cflag -eq 0
    then
      echo ssh -x blade${i} $*
    else
      echo scp $1 blade${i}:$2
    fi
  fi

  # make sure the host is accessible
  ping -qc1 blade${i} > /dev/null 2>&1
  if test $? -ne 0
  then
    echo "$sname WARNING -- blade${i} is not accessible"
  else
    if test $cflag -eq 0
    then
      # do an ssh command
      ssh -x blade${i} $*
    else
      # do an scp command
      scp $1 blade${i}:$2
    fi
  fi
done