#!/bin/bash
# Note, the all hostnames should be in /etc/hosts
dhosts=""

. /etc/kfs-env.sh

KFS_DIR=${INSTALL_DIR}

function usage
{
    cat << EOF
        usage       - command list
        ra          - run a command on all nodes
        rap         - run a command on all nodes in paralell
        fsync       - sync files or dirs among all nodes
        tsync       - sync time among all hosts
        version     - get version of installation
        haltall     - halt all nodes
        rebootall   - reboot all nodes
EOF
}

# Run a command on all hosts (ra stands for run all)
# Note, Should be careful to use wildcard. 
# For example, ra ls * --> ra 'ls *'
function ra
{
    cmd=${1?"Usage:ra command ..."}
    for host in $dhosts; do
        echo "+++ $host +++"
        $SSH $host "eval PATH=\$PATH:$KFS_DIR '$@'"
    done
}

# Run a command on all hosts in parallel
function rap
{
    cmd=${1?"Usage: rap command..."}
    local host tasks
    for host in $dhosts ; do
        $SSH $host "eval PATH=\$PATH:$KFS_DIR '$@'" 2>&1 | \
             sed "s/^/[$host] /" &
        tasks="$tasks $!"
    done

    wait $tasks &> /dev/null
}

# Get version of installation
function version
{
    ra "$KFS_DIR/kylinfs --version"
}

# Sync time
function tsync
{
    local d=$(date -u +%m%d%H%M%Y)
    ra date -u "$d"
    ra hwclock -w -u
}

# Sync file or dir
function fsync
{
    : ${1?"Usage: fsync filename/dirname ..."}

    # Get files with absolute path
    local file
    local flist=""
    local source_file=""
    for file in "$@"; do
        [[ $file == /* ]] || file=$(pwd)/$file

        if [ -L ${file} ]; then
            source_file="$(readlink -f $file)"
            flist="$flist $source_file"
        fi

        flist="$flist $file"
    done

    local host
    for host in $dhosts ; do
        local islocal=$(/sbin/ifconfig -a | grep "inet addr:$host")
        [[ $(hostname) == $host || -n "$islocal" ]] && continue
        echo "+++ Syncing to $host +++"
        tar cPf - $flist | $SSH $host tar xPvf -
    done
}

# Reboot all nodes
function rebootall
{
    local value
    read -p "Are you sure [${eeid}] (y/n)?   " value
    [[ $value != y && $value != Y ]] && return 1
    
    local host
    for host in $dhosts ; do
        local islocal=$(/sbin/ifconfig -a | grep "inet addr:$host")
        [[ $(hostname) == $host || -n "$islocal" ]] && continue
        echo "+++ $host +++"
        $SSH $host reboot
    done
    
    echo "+++ $(hostname) +++"
    [ -f /usr/bin/reboot ] && /usr/bin/reboot || /sbin/reboot
}

# Halt all nodes
function haltall
{
    local value
    read -p "Are you sure [${eeid}] (y/n)?   " value
    [[ $value != y && $value != Y ]] && return 1

    local host
    for host in $dhosts ; do
        local islocal=$(/sbin/ifconfig -a | grep "inet addr:$host")
        [[ $(hostname) == $host || -n "$islocal" ]] && continue
        echo "+++ $host +++"
        $SSH $host halt
    done
    
    echo "+++ $(hostname) +++"
    [ -f /usr/bin/halt ] && /usr/bin/halt || /sbin/halt
} 
function halt
{
    local value
    read -p "Are you sure [${eeid}] (y/n)?   " value
    if [[ $value == y || $value == Y ]] 
    then
        [ -f /usr/bin/halt ] && /usr/bin/halt || /sbin/halt
    else
        echo "command halt not found"
    fi
}
function reboot
{
    local value
    read -p "Are you sure [${eeid}] (y/n)?   " value
    if [[ $value == y || $value == Y ]] 
    then
        [ -f /usr/bin/reboot ] && /usr/bin/reboot || /sbin/reboot
    else
        echo "command reboot not found"
    fi
}

#
# Main function
#

if [ -f "$KFS_DIR/kfs.json" ]; then
    dhosts=$(grep '"ip":' $KFS_DIR/kfs.json |awk -F':' '{print $2}'|tr -d '",'| tr -s '\n' ' ') 
fi

if [[ -z "$dhosts" ]]; then
    echo "Failed to get node list, please check dhost variable."
    return 1
fi

export PATH="$PATH:$KFS_DIR"
kuser=$(whoami)

SSH="ssh -o User=${kuser} -o StrictHostKeyChecking=no"

ulimit -c unlimited
ulimit -n 16384 &> /dev/null

echo "Help:"
usage

echo "Hosts:"
let i=1
for host in $dhosts; do
    printf "%9d" $i
    echo "  $host"  
    let i=i+1
done
