#!/bin/bash

# -------------------------------------------------------------------------- #
# Copyright 2002-2017, OpenNebula Project, OpenNebula Systems                #
#                                                                            #
# Licensed 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.                                             #
#--------------------------------------------------------------------------- #

# MV <hostA:system_ds/disk.i|hostB:system_ds/disk.i> vmid dsid
#    <hostA:system_ds/|hostB:system_ds/>
#   - hostX is the target host to deploy the VM
#   - system_ds is the path for the system datastore in the host
#   - vmid is the id of the VM
#   - dsid is the target datastore (0 is the system datastore)

SRC=$1
DST=$2

VMID=$3
DSID=$4

if [ -z "${ONE_LOCATION}" ]; then
    TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
else
    TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
fi

DRIVER_PATH=$(dirname $0)

. $TMCOMMON

SRC=`fix_dir_slashes $SRC`
DST=`fix_dir_slashes $DST`

SRC_PATH=`arg_path $SRC`
DST_PATH=`arg_path $DST`

SRC_HOST=`arg_host $SRC`
DST_HOST=`arg_host $DST`

DST_DIR=`dirname $DST_PATH`

SRC_DS_DIR=`dirname  $SRC_PATH`
SRC_VM_DIR=`basename $SRC_PATH`

ssh_make_path $DST_HOST $DST_DIR

#rbt: create dirs
CMD_PRE=$(cat <<EOF
    set -ex -o pipefail

    #rbt: create dirs
    mkdir -p /var/lib/one/datastores/$DSID
    mkdir -p $DST_DIR
    if [ ! -f \$(dirname $DST_DIR)/.dm_mad ]; then
        echo "lvm_thin" > "\$(dirname $DST_DIR)/.dm_mad"
    fi
EOF
)

#rbt: copy VM $HOME
CMD_SYNC=$(cat <<EOF
    set -ex -o pipefail

    ($TAR -C $DST_DIR -cSf - . | $SSH "$DST_HOST" "$TAR -xSf - -C $DST_DIR ;  export PATH=$PATH:/sbin ; pdp-one $DST_DIR") || :
EOF
)

#rbt
ssh_exec_and_log "$DST_HOST" "$CMD_PRE" \
    "Error create virtual machine home dir"

# Activate the disk in the target host
if [ `is_disk $DST_PATH` -eq 1 ]; then

    XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin"

    unset i j XPATH_ELEMENTS

    while IFS= read -r -d '' element; do
        XPATH_ELEMENTS[i++]="$element"
    done < <(onevm show -x $VMID | $XPATH  \
                        /VM/LCM_STATE )

    LCM_STATE="${XPATH_ELEMENTS[j++]}"

    CMD=$(cat <<EOF
        if [ -L "$DST_PATH" ]; then
            DEVICE=\$(readlink "$DST_PATH")
            $SUDO $SYNC
            $SUDO $LVSCAN
            $SUDO $LVCHANGE -ay \$DEVICE
        fi
EOF
)
    #rbt
    ping -c 1 $SRC_HOST > /dev/null
    if [ $? -eq 0 ]; then
        ssh_exec_and_log "$SRC_HOST" "$CMD_SYNC" \
            "Error sync virtual machine home"
    else
        DST_DS_SYS_ID=$(echo $DST_DIR | $AWK -F '/' '{print $(NF-1)}')
        DISK_ID=${SRC_PATH##*.}
        LV_NAME="lv-one-${VMID}-${DISK_ID}"
        DST_VG_NAME="vg-one-${DST_DS_SYS_ID}"
        DST_DEV="/dev/${DST_VG_NAME}/${LV_NAME}"
CMD_LN=$(cat <<EOF
        set -ex -o pipefail
        if ! [ -L "$DST_PATH" ]; then
            ln -s $DST_DEV $DST_PATH
        fi
EOF
)
        ssh_exec_and_log "$DST_HOST" "$CMD_LN"
    fi
    if ! [[ "$LCM_STATE" =~ ^(9|31|49|50)$ ]]; then
            # deactivate
	CMD_STOP=$(cat <<EOF
	    set -ex -o pipefail
            if [ -L "$SRC_PATH" ]; then
                DEVICE=\$(readlink "$SRC_PATH")
                $SYNC
                $SUDO $LVSCAN
                $SUDO $LVCHANGE -an \$DEVICE
            fi
EOF
)
	ssh_exec_and_log "$SRC_HOST" "$CMD_STOP" \
                "Error deactivating disk ${SRC_PATH}"
    else
        ssh_exec_and_log "$DST_HOST" "$CMD" \
                "Error activating disk $DST_PATH"
    fi
fi

# Return if the target path is the same as the source path. No need to move
# anything. This is *not* a system ds migration.
if [ "$SRC_PATH" == "$DST_PATH" ]; then
    exit 0
fi

ssh_exec_and_log "$DST_HOST" "mv $SRC_PATH $DST_PATH" \
    "Error moving VM files to another System DS: $SRC_PATH to $DST_PATH in $DST_HOST"
