#!/bin/bash

# -------------------------------------------------------------------------- #
# Copyright 2002-2025, 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.                                             #
#--------------------------------------------------------------------------- #

# context context.sh file1 file2 ... fileN host:remote_system_ds/disk.i vmid 0
#   - context.sh file are the contents of the context ISO
#   - host is the target host to deploy the VM
#   - remote_system_ds is the path for the system datastore in the host
#   - vmid is the id of the VM
#   - 0 is the target datastore (system)

ARGV=("$@")

DS_ID="${ARGV[$(($#-1))]}"
VM_ID="${ARGV[$(($#-2))]}"
DST="${ARGV[$(($#-3))]}"
SRC=("${ARGV[@]:0:$(($#-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

. $TMCOMMON

function exit_error
{
    error_message "$ERROR"
    rm -rf $ISO_DIR > /dev/null 2>&1
    exit -1
}

#-------------------------------------------------------------------------------
# Set dst path and dirs
#-------------------------------------------------------------------------------
DST_PATH=`arg_path $DST`
DST_HOST=`arg_host $DST`
DST_DIR=`dirname $DST_PATH`
DST_FILE=`basename $DST_PATH`

#-------------------------------------------------------------------------------
# Create DST path
#-------------------------------------------------------------------------------

ssh_make_path $DST_HOST $DST_DIR

#-------------------------------------------------------------------------------
# Build the Context Block device (locally) and copy it remotely
#-------------------------------------------------------------------------------
log "Generating context block device at $DST"

VM_ID=`basename $DST_DIR`
ISO_DIR="$DS_DIR/.isofiles/$VM_ID"
ISO_FILE="$VM_ID.iso"
ISO_PATH="$ISO_DIR/$ISO_FILE"

exec_and_log "rm -rf $ISO_DIR" \
    "Could not delete temp. to make context dev"

exec_and_set_error "mkdir -p $ISO_DIR" \
    "Could not create temp. dir to make context dev"
[ -n "$ERROR" ] && exit_error

for f in "${SRC[@]}"; do
    case "$f" in
    http://*)
        exec_and_set_error "$WGET -P $ISO_DIR $f" "Error downloading $f"
        ;;
    *)
        if echo "$f" | grep -q ':'; then
            target=$(echo "$f"|cut -d':' -f2-)
            target="'$target'"
            f=$(echo "$f"|cut -d':' -f1)
        else
            target=""
        fi

        exec_and_set_error "cp -R $f $ISO_DIR/$target" \
            "Error copying $f to $ISO_DIR"
        ;;
    esac

    [ -n "$ERROR" ] && exit_error
done

# This generates context ISO first into a temporary file and renames to final
# file, to workaround problem when datastores are on FUSE mounted volume
# (e.g,. fuse-overlayfs), cached files metadata are not consistent and
# and tar sparse detection algorithm could identify file as empty.
MKCONTEXT_CMD=$(cat <<EOF
    set -e -o pipefail
    $MKISOFS -o $ISO_PATH.tmp -V CONTEXT -J -R $ISO_DIR
    mv $ISO_PATH.tmp $ISO_PATH
EOF
)

multiline_exec_and_set_error "$MKCONTEXT_CMD" "Error creating iso fs"
[ -n "$ERROR" ] && exit_error

COPY_CMD=$(cat <<EOF
    set -e -o pipefail
    $TAR -C $ISO_DIR --transform="flags=r;s|$ISO_FILE|$DST_FILE|" -cSf - $ISO_FILE | \
        $SSH $DST_HOST "$TAR -xSf - -C $DST_DIR"
EOF
)

multiline_exec_and_set_error "$COPY_CMD" "Error copying context ISO to $DST"
[ -n "$ERROR" ] && exit_error

rm -rf $ISO_DIR > /dev/null 2>&1

exit 0
