#!/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.                                             #
#--------------------------------------------------------------------------- #

# DELETE <host:remote_system_ds/disk.i|host:remote_system_ds/>
#   - host is the target host to deploy the VM
#   - remote_system_ds is the path for the system datastore in the host

DST=$1
VM_ID=$2
DS_ID=$3

#--------------------------------------------------------------------------------

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 $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

#-------------------------------------------------------------------------------
# Process destination
#-------------------------------------------------------------------------------

DST_HOST=`arg_host $DST`
DST_PATH=`arg_path $DST`

if [ `is_disk $DST_PATH` -eq 0 ]; then
    DS_ID=$(echo $DST_PATH | $AWK -F/ '{print $(NF-1)}')
else
    DS_ID=$(echo $DST_PATH | $AWK -F/ '{print $(NF-2)}')
fi

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 $DS_ID | $XPATH \
                    /DATASTORE/TEMPLATE/LS_CONTROLLERS \
                    /DATASTORE/TEMPLATE/LS_CERTFILE \
                    /DATASTORE/TEMPLATE/LS_KEYFILE \
                    /DATASTORE/TEMPLATE/LS_CAFILE \
                    /DATASTORE/TEMPLATE/BRIDGE_LIST)

LS_CONTROLLERS="${XPATH_ELEMENTS[j++]}"
LS_CERTFILE="${XPATH_ELEMENTS[j++]}"
LS_KEYFILE="${XPATH_ELEMENTS[j++]}"
LS_CAFILE="${XPATH_ELEMENTS[j++]}"
BRIDGE_LIST="${XPATH_ELEMENTS[j++]}"

linstor_load_keys

unset i j XPATH_ELEMENTS
while IFS= read -r -d '' element; do
    XPATH_ELEMENTS[i++]="$element"
done < <(onevm show -x $VM_ID | $XPATH \
    '/VM/HISTORY_RECORDS/HISTORY[last()]/HOSTNAME')

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

# Change DST_HOST to one of the BRIDGE_LIST to prevent
# running on frontend for undeployed VMs
if [ "$LAST_HOST" != "$DST_HOST" ]; then
    DST_HOST=$(linstor_get_bridge_host)
fi

#-------------------------------------------------------------------------------
# Delete and exit if directory
#-------------------------------------------------------------------------------

if [ `is_disk $DST_PATH` -eq 0 ]; then
    # Directory: delete checkpoint and directory

    CHECKPOINT_RES="one-vm-${VM_ID}-checkpoint"

    # Check if vm have checkpoint resource
    $LINSTOR -m --output-version v0 resource-definition list -r "$CHECKPOINT_RES" | \
        $JQ -er '.[].rsc_dfns[]?' >/dev/null

    # Remove checkpoint resource
    if [ $? -eq 0 ]; then
        linstor_exec_and_log \
            "resource-definition delete $CHECKPOINT_RES"
    fi

    log "Deleting $DST_PATH"
    ssh_exec_and_log "$DST_HOST" "rm -rf $DST_PATH" \
                     "Error deleting $DST_PATH"
    exit 0
fi

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

DISK_ID=$(echo "$DST_PATH" | $AWK -F. '{print $NF}')
DST_DEV="$DST_PATH"
DST_RES="one-vm-${VM_ID}-disk-${DISK_ID}"

unset i j XPATH_ELEMENTS

while IFS= read -r -d '' element; do
    XPATH_ELEMENTS[i++]="$element"
done < <(onevm show -x $VM_ID| $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)}')"

#-------------------------------------------------------------------------------
# Delete the device
#-------------------------------------------------------------------------------

# Unlink resource
ssh_exec_and_log_no_error "$DST_HOST" "rm -f $DST_PATH" \
    "Error unlinking $DST_PATH"

# No need to delete no cloned images
if [ "$CLONE" = "NO" ]; then
    # Detach diskless resources
    SRC_RES_DISKLESS_HOSTS=$(linstor_get_diskless_hosts_for_res "$SRC_RES")
    if item_in_list "$DST_HOST" "$SRC_RES_DISKLESS_HOSTS"; then
        linstor_exec_and_log \
            "resource delete $DST_HOST $SRC_RES --async"
    fi
    exit 0
fi

log "Deleting $DST_RES"

ALL_SNAP_IDS=$(linstor_get_snap_ids_for_res "$DST_RES" 1)

for SNAP_ID in $ALL_SNAP_IDS; do

    SNAPSHOT="snapshot-${SNAP_ID}"

    # Remove snapshot from monitoring
    linstor_exec_and_log \
        "resource-definition set-property $DST_RES Aux/one/SNAPSHOT_${SNAP_ID}/DISK_SIZE"

    # Remove snapshot
    linstor_exec_and_log \
        "snapshot delete $DST_RES $SNAPSHOT"

done

# Remove resource definition
linstor_exec_and_log \
    "resource-definition delete $DST_RES"

# Check if source image have snapshot (CLONE_MODE=snapshot)
linstor_get_snap_names_for_res "$SRC_RES" | grep -q "^${DST_RES}$"

# Remove snapshot from SOURCE image if found
if [ $? -eq 0 ]; then
    linstor_exec_and_log \
        "snapshot delete $SRC_RES $DST_RES"
fi

exit 0
