#!/bin/bash

#rbt

# PREMIGRATE SOURCE DST remote_system_dir vmid dsid template
#  - SOURCE is the host where the VM is running
#  - DST is the host where the VM is to be migrated
#  - remote_system_dir is the path for the VM home in the system datastore
#  - vmid is the id of the VM
#  - dsid is the target datastore
#  - template is the template of the VM in XML and base64 encoded

SRC_HOST=$1
DST_HOST=$2

DST_PATH=$3

VMID=$4
DSID=$5

TEMPLATE_64=$6

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

. $TMCOMMON

CURRENT_DS_ID=$(onevm show -x $VMID | xmlstarlet sel -t -v "/VM/HISTORY_RECORDS/HISTORY[position() = (last()-1)]/DS_ID")
SRC_DIR=/var/lib/one/datastores/$CURRENT_DS_ID/$VMID
SRC_MAP=vg--one--$CURRENT_DS_ID-lv--one--vm--$VMID--*
SRC_DEV=/dev/vg-one-$CURRENT_DS_ID/lv-one-vm-$VMID-*
DST_MAP=vg--one--$DSID-lv--one--vm--$VMID--*
DST_DEV_MAP=/dev/mapper/$DST_MAP
SRC_DEV_MAP=/dev/mapper/$SRC_MAP


CMD_CREATE=$(cat <<EOF
    set -ex -o pipefail

    export PATH=$PATH:/sbin
    mkdir -p /var/lib/one/datastores/$DSID
    pdp-one "/var/lib/one/datastores/$DSID"
    mkdir -p $DST_PATH
    pdp-one "$DST_PATH"

    for disk in /var/lib/one/datastores/$CURRENT_DS_ID/$VMID/*; do
        if [ -L "\$disk" ]; then

            DISK_ID=\${disk##*.}
            DEVICE=\$(readlink "\$disk")
            LV_NAME="lv-one-vm-${VMID}-\${DISK_ID}"
            DST_VG_NAME="vg-one-${DSID}"
            DST_DEV="/dev/\${DST_VG_NAME}/\${LV_NAME}"

            if [ -e "$DST_DEV_MAP" ]; then
                $SUDO $SYNC
                $SUDO $DMSETUP remove $DST_DEV_MAP
            fi

            $SUDO $SYNC
            set +e
            $SUDO $LVSCAN | grep "\${DST_DEV}"

            CURRENT_DS_VG_NAME="vg-one-$CURRENT_DS_ID"

            if echo "\$DEVICE" | grep "^/dev/\$CURRENT_DS_VG_NAME" &>/dev/null; then
                set -ex -o pipefail
                FILE_SIZE=\$(qemu-img measure -U --output=json -O qcow2 \$DEVICE  --force-share | jq '."required"')
                FILE_SIZEMB=\$(( \$FILE_SIZE / 1024 / 1024))
                if [ \$FILE_SIZEMB -eq 0 ];then
                    FILE_SIZEMB=100
                fi
                SIZE8=\$(bc<<<"scale=1;\$FILE_SIZEMB*1.08"   | awk '{ print int(\$1) }')
                ${SUDO} ${LVCREATE} --wipesignatures n -L"\${SIZE8}" -n "\${LV_NAME}" "\${DST_VG_NAME}"
                if [ -L $DST_PATH/disk.\${DISK_ID} ];then
                    rm -f $DST_PATH/disk.\${DISK_ID}
                fi
                ln -s \$DST_DEV $DST_PATH/disk.\${DISK_ID}
            else
                if [ -L $DST_PATH/disk.\${DISK_ID} ];then
                    rm -f $DST_PATH/disk.\${DISK_ID}
                fi
                ln -s \$DEVICE $DST_PATH/disk.\${DISK_ID}

            fi
            set -ex -o pipefail
        fi
    done
EOF
)

if [ "$SRC_HOST" == "$DST_HOST" ]; then
    if [ "$CURRENT_DS_ID" != "$DSID" ]; then
        ssh_exec_and_log $DST_HOST "$CMD_CREATE" "Error brest_lvm premigrate first step"
    fi

    exit 0
fi

if [ "$SRC_HOST" != "$DST_HOST" ]; then
    #rbt: create dirs
    CMD_PRE=$(cat <<EOF
    set -ex -o pipefail

    #rbt: create dirs
    export PATH=$PATH:/sbin
    mkdir -p /var/lib/one/datastores/$DSID
    pdp-one "/var/lib/one/datastores/$DSID"
    mkdir -p $DST_PATH
    pdp-one "$DST_PATH"
EOF
)
    #rbt: copy VM $HOME
    CMD_SYNC=$(cat <<EOF
    set -ex -o pipefail
    cd $SRC_DIR
    tar cfp - * | ssh $DST_HOST "(cd $DST_PATH; tar xfp - )"
EOF
)

    CMD=$(cat <<EOF
    set -ex -o pipefail

    $SUDO $SYNC
    $SUDO $LVSCAN

	for disk in \$(ls ${DST_PATH}/disk.*); do
    	    if [ -L "\$disk" ]; then
        	DEVICE=\$(readlink "\$disk")
                DISK_ID=\${disk##*.}
                DST_MAP="vg--one--${DSID}-lv--one--vm--${VMID}--\${DISK_ID}"
                DST_DEV_MAP="/dev/mapper/\${DST_MAP}"
                if [ -e "\${DST_DEV_MAP}" ]; then
                    $SUDO $DMSETUP remove \${DST_MAP}
                fi
    	    fi
	done
EOF
)

    #clean old LV
    CLEAN_CMD=$(cat <<EOF
        set -e -o pipefail
        for disk in \$(ls ${SRC_DIR}/disk.*); do
            CURRENT_DS_VG_NAME="vg-one-$CURRENT_DS_ID"
            if [ -L "\$disk" ]; then
                DEVICE=\$(readlink "\$disk")
                if echo "\$DEVICE" | grep "lv-one-vm" &>/dev/null; then
                    $SUDO $SYNC
                    $SUDO $LVREMOVE -f \${DEVICE}
                fi
            fi
        done
        if [ -d "${SRC_DIR}" ]; then
            rm -rf ${SRC_DIR}
        fi
EOF
)

    ssh_exec_and_log $DST_HOST "$CMD_PRE" \
    "Error running brest_lvm premigrate"

    if [ "$CURRENT_DS_ID" != "$DSID" ]; then
    deploy_id=one-$VMID

    MOVE_CMD=$(cat <<EOF
        set -e -o pipefail

            OUT="\$(mktemp)"
            virsh -c qemu:///system domblklist "$deploy_id" --details | tail -n+3 > \$OUT
            while read disk; do
            if [ -n "\$disk" ]; then
                tdisk=(\$disk)
                DISK_ID=\${disk##*.}
                NEW_DISK_PATH=/var/lib/one/datastores/$DSID/$VMID/disk.\${DISK_ID}

                if [ "\${tdisk[0]}" == "block" ]; then
                    if echo "\${tdisk[3]}" | grep "lv-one-vm" &>/dev/null; then
                        DISK_ID=\${disk##*-}
                        NEW_DISK_PATH="/dev/vg-one-$DSID/lv-one-vm-$VMID-\${DISK_ID}"
                        virsh -c qemu:///system blockcopy --domain $deploy_id --path \${tdisk[3]} --dest \$NEW_DISK_PATH --blockdev  --wait --verbose --pivot
                    fi
                else
                    cp \${tdisk[3]} \$NEW_DISK_PATH
                    virsh -c qemu:///system change-media --domain $deploy_id \${tdisk[2]} \$NEW_DISK_PATH --live
                fi
            fi
            done < \$OUT
EOF
)
    ssh_exec_and_log $SRC_HOST "$CMD_CREATE" \
        "Error running brest_lvm premigrate"

    ssh_exec_and_log $SRC_HOST "$MOVE_CMD" \
    "Error move disks between datastore  $deploy_id"

    ssh_exec_and_log $SRC_HOST "$CMD_SYNC" \
    "Error sync virtual machine home"

    ssh_exec_and_log  $SRC_HOST "$CLEAN_CMD" \
    "Error clean old logic volumes"

    ssh_exec_and_log $DST_HOST "$CMD" \
        "Error running brest_lvm premigrate"

    ssh_exec_and_log $DST_HOST "$CLEAN_MAP_SRC" \
    "Error clean old $DST_HOST mapper"

    else

    ssh_exec_and_log $SRC_HOST "$CMD_SYNC" \
    "Error sync virtual machine home"

    ssh_exec_and_log $DST_HOST "$CMD" \
        "Error running brest_lvm premigrate"
    fi
fi

migrate_other "$@"
