#!/bin/sh -e

usage()
{
    cat << EOM
Usage: $0 [-p] [-c] [-n] 'command' head|backup|io|compute|vis|all
    -c = continue running if there are errors.
    -p = run in parallel, redirecting output to files. (implies -c)
    -n = omit ssh -t flag to disable full terminal control.
	 Use only if a command has output problems without -n.
    -f first-host
    -l last-host

    Note: command must be enclosed in quotes.
EOM
    exit 1
}

if ! cluster-check-cron-updates; then
    exit 0
fi

parallel=0
flags=''
terminal_control=on
while [ 0`printf '%s' "$1" | cut -c 1,1` = 0'-' ]; do
    if [ $1 = '-p' ]; then
	parallel=1
	set +e
	shift
    elif [ $1 = '-c' ]; then
	set +e
	shift
    elif [ $1 = '-n' ]; then
	terminal_control=off
	shift
    elif [ $1 = '-f' ]; then
	shift
	first_node=$1
	shift
    elif [ $1 = '-l' ]; then
	shift
	last_node=$1
	shift
    else
	usage $0
    fi
done

if [ $terminal_control = 'on' ]; then
    flags="${flags} -t"
fi

if [ $# -lt 2 ]; then
    usage $0
fi

remote_cmd="$1"

while [ $# -gt 1 ]; do
    node_type=$2
    
    if [ $node_type = 'head' ] || [ $node_type = 'all' ]; then
	nodes="$nodes localhost"
    fi
    
    if [ $node_type = 'backup' ] || [ $node_type = 'all' ]; then
	nodes="$nodes `cluster-backup-nodes`"
    fi
    
    if [ $node_type = 'io' ] || [ $node_type = 'all' ]; then
	nodes="$nodes `cluster-file-servers`"
    fi
    
    if [ $node_type = 'vis' ] || [ $node_type = 'all' ]; then
	nodes="$nodes `cluster-vis-nodes`"
    fi
    
    if [ $node_type = 'compute' ] || [ $node_type = 'all' ]; then
	nodes="$nodes `cluster-compute-nodes`"
    fi
    shift
done

if [ -z "$nodes" ] || [ "$nodes" = ' ' ]; then
    exit
fi

if [ -z $first_node ]; then
    first_node=`echo $nodes | awk '{ print $1 }'`
fi
if [ -z $last_node ]; then
    last_node=`echo $nodes | awk '{ print $NF }'`
fi
if ! echo $nodes | fgrep -q $first_node; then
    printf "$first_node is not among the selected nodes.\n"
    exit 1
fi
if ! echo $nodes | fgrep -q $last_node; then
    printf "$last_node is not among the selected nodes.\n"
    exit 1
fi

in_range=0
for node in $nodes; do
    if [ $node = $first_node ]; then
	in_range=1
    fi
    if [ $in_range = 1 ]; then
	selected_nodes="$selected_nodes $node "
    fi
    if [ $node = $last_node ]; then
	in_range=0
    fi
done

for node in $selected_nodes; do
    printf "\n============================================================\n"
    printf "$node\n"
    printf "============================================================\n\n"
    
    if [ $node = "localhost" ]; then
	ssh_cmd="sh -c"
    else
	ssh_cmd="ssh -o ConnectTimeout=10 $flags $node"
    fi
    
    if [ $parallel = 1 ]; then
	$ssh_cmd "$remote_cmd" > cluster-run.out.$node 2>&1 &
	printf "Output in cluster-run.out.$node.\n"
    else
	$ssh_cmd "$remote_cmd"
    fi
done

if [ $parallel = 1 ]; then
    # Wait for all jobs to complete
    wait
fi

