#!/bin/bash

# -------------------------------------------------------------------------- #
# Copyright 2002-2019, 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)

source ${DRIVER_PATH}/../../etc/tm/fs_lvm/fs_lvm.conf

source $TMCOMMON
source ${DRIVER_PATH}/../../datastore/libfs.sh
source ${DRIVER_PATH}/../../etc/datastore/linstor_un/linstor_un.conf
source ${DRIVER_PATH}/../../datastore/linstor_un/linstor_utils.sh

#-------------------------------------------------------------------------------
# Get Image information
#-------------------------------------------------------------------------------

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

unset i j XPATH_ELEMENTS

while IFS= read -r -d '' element; do
    XPATH_ELEMENTS[i++]="$element"
done < <(onedatastore show -x $DSID | $XPATH \
                    /DATASTORE/TEMPLATE/BRIDGE_LIST \
                    /DATASTORE/TEMPLATE/LS_CONTROLLERS \
                    /DATASTORE/TEMPLATE/LS_CERTFILE \
                    /DATASTORE/TEMPLATE/LS_KEYFILE \
                    /DATASTORE/TEMPLATE/LS_CAFILE \
                    /DATASTORE/TEMPLATE/RESOURCE_GROUP \
                    /DATASTORE/TEMPLATE/NODE_LIST \
                    /DATASTORE/TEMPLATE/LAYER_LIST \
                    /DATASTORE/TEMPLATE/PROVIDERS \
                    /DATASTORE/TEMPLATE/REPLICAS_ON_SAME \
                    /DATASTORE/TEMPLATE/REPLICAS_ON_DIFFERENT \
                    /DATASTORE/TEMPLATE/AUTO_PLACE \
                    /DATASTORE/TEMPLATE/REPLICA_COUNT \
                    /DATASTORE/TEMPLATE/DO_NOT_PLACE_WITH \
                    /DATASTORE/TEMPLATE/DO_NOT_PLACE_WITH_REGEX \
                    /DATASTORE/TEMPLATE/STORAGE_POOL \
                    /DATASTORE/TEMPLATE/DISKLESS_POOL \
                    /DATASTORE/TEMPLATE/ENCRYPTION)

BRIDGE_LIST="${XPATH_ELEMENTS[j++]}"
LS_CONTROLLERS="${XPATH_ELEMENTS[j++]}"
LS_CERTFILE="${XPATH_ELEMENTS[j++]}"
LS_KEYFILE="${XPATH_ELEMENTS[j++]}"
LS_CAFILE="${XPATH_ELEMENTS[j++]}"
RESOURCE_GROUP="${XPATH_ELEMENTS[j++]}"
NODE_LIST="${XPATH_ELEMENTS[j++]}"
LAYER_LIST="${XPATH_ELEMENTS[j++]}"
PROVIDERS="${XPATH_ELEMENTS[j++]}"
REPLICAS_ON_SAME="${XPATH_ELEMENTS[j++]}"
REPLICAS_ON_DIFFERENT="${XPATH_ELEMENTS[j++]}"
AUTO_PLACE="${XPATH_ELEMENTS[j++]}"
REPLICA_COUNT="${XPATH_ELEMENTS[j++]:-$AUTO_PLACE}"
DO_NOT_PLACE_WITH="${XPATH_ELEMENTS[j++]}"
DO_NOT_PLACE_WITH_REGEX="${XPATH_ELEMENTS[j++]}"
STORAGE_POOL="${XPATH_ELEMENTS[j++]}"
DISKLESS_POOL="${XPATH_ELEMENTS[j++]:-DfltDisklessStorPool}"
ENCRYPTION="${XPATH_ELEMENTS[j++]}"

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++]}"

linstor_load_keys

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

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

SRC_DIR=`dirname $SRC_PATH`
DST_DIR=`dirname $DST_PATH`

# Activate the disk in the target host
if [ `is_disk $SRC_PATH` -eq 1 ]; then
    #---------------------------------------------------------------------------
    # Get Image information
    #---------------------------------------------------------------------------

    DISK_ID=$(echo $SRC | $AWK -F. '{print $NF}')

    unset i j XPATH_ELEMENTS

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

    SRC_DEV="${XPATH_ELEMENTS[j++]}"
    CLONE="${XPATH_ELEMENTS[j++]}"

    SRC_RES="$(echo "$SRC_DEV" | $AWK -F/ '{print $(NF-1)}')"

    if [ "$CLONE" != "NO" ]; then
        SRC_RES="one-vm-${VMID}-disk-${DISK_ID}"
        SRC_DEV="/dev/drbd/by-res/${SRC_RES}/0"
    fi

    DST_RES="$SRC_RES"
    DST_DEV="$SRC_DEV"
    SRC_DS_SYS_ID=$(echo $SRC_DIR | $AWK -F '/' '{print $(NF-1)}')
    DST_DS_SYS_ID=$(echo $DST_DIR | $AWK -F '/' '{print $(NF-1)}')

    # for PROLOG_RESUME + PROLOG_UNDEPLOY skip deactivate
    if ! [[ "$LCM_STATE" =~ ^(9|31|49|50)$ ]]; then

        # Detach resource
        # We use 'no_error' due VM can be migrated from the failed host
        SRC_RES_DISKLESS_HOSTS=$(linstor_get_diskless_hosts_for_res "$SRC_RES")
        if item_in_list "$SRC_HOST" "$SRC_RES_DISKLESS_HOSTS"; then
            linstor_exec_and_log_no_error \
                "resource delete $SRC_HOST $SRC_RES --async"
        fi

        ssh_exec_and_log_no_error "$SRC_HOST" \
            "rm -f $SRC_PATH" \
            "Error unlinking $SRC_PATH on $SRC_HOST"
    fi

    # for EPILOG_STOP + EPILOG_UNDEPLOY we got nothing to do
    if [[ "$LCM_STATE" =~ ^(10|30|41|42)$ ]]; then
        exit 0
    fi

    # copy volume between datastores
    if [ "${SRC_PATH}" != "${DST_PATH}" ]; then
        linstor_exec_and_log \
            "resource-definition set-property $DST_RES Aux/one/DS_ID $DSID"
    fi

    # Attach diskless resource on destination host
    linstor_attach_diskless "$DST_HOST" "$DST_RES" "$DISKLESS_POOL"

    # Link device on destination host
    LINK_CMD=$(cat <<EOF
        set -e -o pipefail
        mkdir -p $DST_DIR
        rm -f $DST_PATH
        ln -s $DST_DEV $DST_PATH
EOF
    )

    ssh_exec_and_log "$DST_HOST" "$LINK_CMD" \
        "Error linking $DST_DEV to $DST_PATH on $DST_HOST"
    exit 0
fi

# for PROLOG_RESUME + PROLOG_UNDEPLOY we got nothing to do
if [[ "$LCM_STATE" =~ ^(9|31|49|50)$ ]]; then
    exit 0
fi

ssh_exec_and_log_no_error "$SRC_HOST" \
    "rm -rf $SRC_PATH" \
    "Error removing VM files on System DS: $SRC_PATH on $SRC_HOST"

exit 0
