#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Shell script to copy snapshots of a Solr Lucene collection from the master

orig_dir=$(pwd)
cd ${0%/*}/..
solr_root=$(pwd)
cd ${orig_dir}

unset master_host rsyncd_port master_data_dir master_status_dir snap_name
unset sizeonly stats data_dir user verbose debug compress startStatus
. ${solr_root}/bin/scripts-util

# set up variables
prog=${0##*/}
log=${solr_root}/logs/${prog}.log

# define usage string
USAGE="\
usage: $prog [-M master] [-P portnum] [-D mdir] [-S sdir] [-n snapshot] [-d dir] [-u username] [-svVz]
       -M master   specify hostname of master server from where to pull index
                   snapshot
       -P port     specify rsyncd port number of master server from where to
                   pull index snapshot
       -D          specify directory holding index data on master server
       -S          specify directory holding snapshot status on master server
       -n snapshot pull a specific snapshot by name
       -d          specify directory holding index data on local machine
       -u          specify user to sudo to before running script
       -s          use the --size-only option with rsync
       -v          increase verbosity (-vv show file transfer stats also)
       -V          output debugging info
       -z          enable compression of data
"

# parse args
while getopts M:P:D:S:n:d:u:svVz OPTION
do
    case $OPTION in
    M)
        master_host="$OPTARG"
        ;;
    P)
        rsyncd_port="$OPTARG"
        ;;
    D)
        master_data_dir="$OPTARG"
        ;;
    S)
        master_status_dir="$OPTARG"
        ;;
    n)
        snap_name="$OPTARG"
        ;;
    d)
        data_dir="$OPTARG"
        ;;
    u)
        user="$OPTARG"
        ;;
    s)
        sizeonly="--size-only"
        ;;
    v)
        [[ -n $verbose ]] && stats="--stats" || verbose=v
        ;;
    V)
        debug="V"
        ;;
    z)
        compress="z"
        ;;
    *)
        echo "$USAGE"
        exit 1
    esac
done

[[ -n $debug ]] && set -x

if [[ -z ${master_host} ]]
then
    echo "name of master server missing in $confFile or command line."
    echo "$USAGE"
    exit 1
fi

# try to determine rsyncd port number from $confFile if not specified on
# command line, default to solr_port+10000
if [[ -z ${rsyncd_port} ]]
then
    if [[ "${solr_port}" ]]
    then
        rsyncd_port=`expr 10000 + ${solr_port}`
    else
        echo "rsyncd port number of master server missing in $confFile or command line."
        echo "$USAGE"
        exit 1
    fi
fi

if [[ -z ${master_data_dir} ]]
then
    echo "directory holding index data on master server missing in $confFile or command line."
    echo "$USAGE"
    exit 1
fi

if [[ -z ${master_status_dir} ]]
then
    echo "directory holding snapshot status on master server missing in $confFile or command line."
    echo "$USAGE"
    exit 1
fi

fixUser "$@"

dataDir

# assume relative path to start at ${solr_root}
if [[ "`echo ${master_data_dir}|cut -c1`" != "/" ]]
then
    master_data_dir=${solr_root}/${master_data_dir}
fi
if [[ "`echo ${master_status_dir}|cut -c1`" != "/" ]]
then
    master_status_dir=${solr_root}/${master_status_dir}
fi

# push stats/state to master if necessary
function pushStatus
{
    scp -q -o StrictHostKeyChecking=no ${solr_root}/logs/snappuller.status ${master_host}:${master_status_dir}/snapshot.status.`uname -n`
}

setStartTime

logMessage started by $oldwhoami
logMessage command: $0 $@

if [[ ! -f ${solr_root}/logs/snappuller-enabled ]]
then
    logMessage snappuller disabled
    exit 2
fi

# make sure we can ssh to master
if
    ! ssh -o StrictHostKeyChecking=no ${master_host} id 1>/dev/null 2>&1
then
    logMessage failed to ssh to master ${master_host}
    exit 1
fi

# get directory name of latest snapshot if not specified on command line
if [[ -z ${snap_name} ]]
then
    snap_name=`ssh -o StrictHostKeyChecking=no ${master_host} "perl -e 'chdir q|${master_data_dir}|; print ((sort grep {/^snapshot[.][1-9][0-9]{13}$/} <*>)[-1])'"`
fi
if [[ "${snap_name}" == "" ]]
then
    logMessage no snapshot available on ${master_host} in ${master_data_dir}
    logExit ended 0
else
    name=`basename ${snap_name}`
fi

# clean up after INT/TERM
trap 'echo cleaning up, please wait ...;/bin/rm -rf ${data_dir}/${name} ${data_dir}/${name}-wip;echo ${startStatus} aborted:$(timeStamp)>${solr_root}/logs/snappuller.status;pushStatus;logExit aborted 13' INT TERM

if [[ -d ${data_dir}/${name} || -d ${data_dir}/${name}-wip ]]
then
    logMessage no new snapshot available on ${master_host} in ${master_data_dir}
    logExit ended 0
fi

# take a snapshot of current index so that only modified files will be rsync-ed
# put the snapshot in the 'work-in-progress" directory to prevent it from
# being installed while the copying is still in progress
if [[ "${OS}" == "SunOS" || "${OS}" == "Darwin" || "${OS}" == "FreeBSD"  ]]
then
  orig_dir=$(pwd)
  mkdir ${data_dir}/${name}-wip
  cd ${data_dir}/index
  find . -print|cpio -pdlmu ${data_dir}/${name}-wip 1>/dev/null 2>&1
  cd ${orig_dir}
else
  cp -lr ${data_dir}/index ${data_dir}/${name}-wip
fi
# force rsync of segments and .del files since we are doing size-only
if [[ -n ${sizeonly} ]]
then
    rm -f ${data_dir}/${name}-wip/segments
    rm -f ${data_dir}/${name}-wip/*.del
fi

logMessage pulling snapshot ${name}

# make sure master has directory for hold slaves stats/state
ssh -o StrictHostKeyChecking=no ${master_host} mkdir -p ${master_status_dir}

# start new distribution stats
rsyncStart=`date +'%Y-%m-%d %H:%M:%S'`
if [[ "${OS}" == "Darwin" || "${OS}" == "FreeBSD"  ]]
then
  startTimestamp=`date -j -f '%Y-%m-%d %H:%M:%S' "$rsyncStart" +'%Y%m%d-%H%M%S'`
  rsyncStartSec=`date -j -f '%Y-%m-%d %H:%M:%S' "$rsyncStart" +'%s'`
else
startTimestamp=`date -d "$rsyncStart" +'%Y%m%d-%H%M%S'`
rsyncStartSec=`date -d "$rsyncStart" +'%s'`
fi
startStatus="rsync of `basename ${name}` started:$startTimestamp"
echo ${startStatus} > ${solr_root}/logs/snappuller.status
pushStatus

# rsync over files that have changed
rsync -Wa${verbose}${compress} --delete ${sizeonly} \
${stats} rsync://${master_host}:${rsyncd_port}/solr/${name}/ ${data_dir}/${name}-wip

rc=$?
rsyncEnd=`date +'%Y-%m-%d %H:%M:%S'`
if [[ "${OS}" == "Darwin" || "${OS}" == "FreeBSD"  ]]
then
  endTimestamp=`date -j -f '%Y-%m-%d %H:%M:%S' "$rsyncEnd" +'%Y%m%d-%H%M%S'`
  rsyncEndSec=`date -j -f '%Y-%m-%d %H:%M:%S' "$rsyncEnd" +'%s'`
else
endTimestamp=`date -d "$rsyncEnd" +'%Y%m%d-%H%M%S'`
rsyncEndSec=`date -d "$rsyncEnd" +'%s'`
fi
elapsed=`expr $rsyncEndSec - $rsyncStartSec`
if [[ $rc != 0 ]]
then
  logMessage rsync failed
  /bin/rm -rf ${data_dir}/${name}-wip
  echo ${startStatus} failed:$endTimestamp > ${solr_root}/logs/snappuller.status
  pushStatus
  logExit failed 1
fi

# move into place atomically
mv ${data_dir}/${name}-wip ${data_dir}/${name}

# finish new distribution stats`
echo ${startStatus} ended:$endTimestamp rsync-elapsed:${elapsed} > ${solr_root}/logs/snappuller.status
pushStatus
logExit ended 0
