#!/bin/bash

# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs        #
#                                                                            #
# 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.                                             #
#--------------------------------------------------------------------------- #

###############################################################################
# This script is used to copy a VM image (SRC) to the image repository as DST
# Several SRC types are supported
###############################################################################

# -------- Set up the environment to source common tools & conf ------------

if [ -z "${ONE_LOCATION}" ]; then
    LIB_LOCATION=/usr/lib/one
    VMWARERC=/etc/one/vmwarerc
else
    LIB_LOCATION=$ONE_LOCATION/lib
    VMWARERC=$ONE_LOCATION/etc/vmwarerc
fi

. $LIB_LOCATION/sh/scripts_common.sh

DRIVER_PATH=$(dirname $0)
source ${DRIVER_PATH}/../libfs.sh
source ${DRIVER_PATH}/vmfs.conf

# -------- Get cp and datastore arguments from OpenNebula core ------------

DRV_ACTION=$1
ID=$2

UTILS_PATH="${DRIVER_PATH}/.."

XPATH="$UTILS_PATH/xpath.rb -b $DRV_ACTION"

unset i XPATH_ELEMENTS

while IFS= read -r -d '' element; do
    XPATH_ELEMENTS[i++]="$element"
done < <($XPATH     /DS_DRIVER_ACTION_DATA/DATASTORE/BASE_PATH \
                    /DS_DRIVER_ACTION_DATA/DATASTORE/ID \
                    /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/RESTRICTED_DIRS \
                    /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/SAFE_DIRS \
                    /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/BRIDGE_LIST \
                    /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/DS_USE_SSH \
                    /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/DS_TMP_DIR \
                    /DS_DRIVER_ACTION_DATA/IMAGE/PATH \
                    /DS_DRIVER_ACTION_DATA/IMAGE/TEMPLATE/MD5 \
                    /DS_DRIVER_ACTION_DATA/IMAGE/TEMPLATE/SHA1 \
                    /DS_DRIVER_ACTION_DATA/IMAGE/ID \
                    /DS_DRIVER_ACTION_DATA/IMAGE/TYPE \
                    /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/NO_DECOMPRESS \
                    /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/LIMIT_TRANSFER_BW)

BASE_PATH="${XPATH_ELEMENTS[0]}"
DS_ID="${XPATH_ELEMENTS[1]}"
RESTRICTED_DIRS="${XPATH_ELEMENTS[2]}"
SAFE_DIRS="${XPATH_ELEMENTS[3]}"
BRIDGE_LIST="${XPATH_ELEMENTS[4]}"
USE_SSH="${XPATH_ELEMENTS[5]:-$DS_USE_SSH}"
TMP_DIR="${XPATH_ELEMENTS[6]:-$DS_TMP_DIR}"
SRC="${XPATH_ELEMENTS[7]}"
MD5="${XPATH_ELEMENTS[8]}"
SHA1="${XPATH_ELEMENTS[9]}"
IMAGE_ID="${XPATH_ELEMENTS[10]}"
IMAGE_TYPE="${XPATH_ELEMENTS[11]}"
NO_DECOMPRESS="${XPATH_ELEMENTS[12]}"
LIMIT_TRANSFER_BW="${XPATH_ELEMENTS[13]}"

FE_DST=`generate_image_path`
DST_FOLDER=`basename $FE_DST`
DST="/vmfs/volumes/$DS_ID/$DST_FOLDER"
DST_HOST=`get_destination_host $IMAGE_ID`


# ------------ Set up datastore  -------------

set_up_datastore "$BASE_PATH" "$RESTRICTED_DIRS" "$SAFE_DIRS"

vmfs_set_up

if ! is_cdrom; then
    vmfs_create_remote_path $DS_ID
fi

# ------------  Prepare for a possible download in the front-end  -------------

if [ ! -d $TMP_DIR ]; then
    mkdir -p $TMP_DIR
fi

DOWNLOADER_ARGS=`set_downloader_args "$MD5" "$SHA1" "$NO_DECOMPRESS" "$LIMIT_TRANSFER_BW" "$SRC" "$TMP_DIR/$DST_FOLDER"`

COPY_COMMAND="$UTILS_PATH/downloader.sh $DOWNLOADER_ARGS"

# ------------ Copy the image to the repository -------------

case $SRC in
http://*|https://* )
    log "Downloading $SRC to the image repository"

    exec_and_log "$COPY_COMMAND" "Error downloading $SRC"

    SRC="$TMP_DIR/$DST_FOLDER"
    ;;

*)
    if [ `check_restricted $SRC` -eq 1 ]; then
        log_error "Not allowed to copy images from $RESTRICTED_DIRS"
        error_message "Not allowed to copy image file $SRC"
        exit -1
    fi

    if ! is_cdrom; then
        log "Copying local disk folder $SRC to the image repository"
    else
        log "Copying local CD-ROM $SRC to the image repository"
    fi

    if [ ! -d $SRC -a ! is_cdrom ]; then
        exec_and_log "$COPY_COMMAND" "Error copying $SRC to $TMP_DIR/$DST_FOLDER"
        SRC="$TMP_DIR/$DST_FOLDER"
    fi
    ;;
esac

# Rename the disk filename to disk.vmdk (warning: it does so in SRC)
if [ -d "$SRC" -a ! -f "$SRC/disk.vmdk" ]; then
    BASE_DISK_FILE=`ls $SRC | grep '\.vmdk$' | grep -v '\-\(flat\|delta\|s[0-9]*\)\.vmdk$'`

    exec_and_log "mv -f $SRC/$BASE_DISK_FILE $SRC/disk.vmdk" \
                 "Error renaming disk file $SRC/$BASE_DISK_FILE to $SRC/disk.vmdk"
fi

# Make the final hop, front-end -> VMFS Datastore
if [ "$USE_SSH" == "yes" ]; then
    if ! is_cdrom; then
        exec_and_log "$SCP -r $SRC/* $DST_HOST:$DST" "Error copying $SRC to $DST through SCP"
    else
        exec_and_log "$SCP $SRC $DST_HOST:$DST" "Error copying $SRC to $DST through SCP"
    fi
else
    if ! is_cdrom; then
        cd $SRC
        for file in $(find . -type f); do
            FNAME=$(basename $file)
            exec_and_log "vifs $VI_PARAMS -p $file [$DS_ID]$DST_FOLDER/$FNAME" \
                         "Cannot upload $file to $DST/$FNAME on $DST_HOST"
        done
    else # Type CDROM
        FILE_TO_REGISTER=$(basename $DST)
        exec_and_log "vifs $VI_PARAMS -p $SRC [$DS_ID]$FILE_TO_REGISTER" \
             "Cannot upload $SRC to $DST on $DST_HOST"
    fi
fi

if [ -d "$TMP_DIR/$DST_FOLDER" -a -n "$DST_FOLDER" ]; then
    rm -rf "$TMP_DIR/$DST_FOLDER" > /dev/null 2>&1
fi

echo "$DST"

