#!/bin/bash

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

DRIVER_PATH=$(dirname $0)
DOMAIN=$1

# Exit if no stdin data is available
if [ -t 0 ]; then
    exit 0
fi

# Read data from stdin data. Extracting the VCPU and MEMORY
XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin"

unset i XPATH_ELEMENTS

while IFS= read -r -d '' element; do
    XPATH_ELEMENTS[i++]="$element"
done < <($XPATH     /VMM_DRIVER_ACTION_DATA/VM/TEMPLATE/VCPU \
                    /VMM_DRIVER_ACTION_DATA/VM/TEMPLATE/MEMORY \
                    /VMM_DRIVER_ACTION_DATA/VM/TEMPLATE/RESIZE/VCPU \
                    /VMM_DRIVER_ACTION_DATA/VM/TEMPLATE/RESIZE/MEMORY)

unset i

VCPU="${XPATH_ELEMENTS[i++]}"
MEM="${XPATH_ELEMENTS[i++]}"
VCPU_OLD="${XPATH_ELEMENTS[i++]}"
MEM_OLD="${XPATH_ELEMENTS[i++]}"

source $(dirname $0)/../../etc/vmm/kvm/kvmrc
source $(dirname $0)/../../scripts_common.sh

# Resize mem
if [ ! -z "$MEM" -a "$MEM" -ne "$MEM_OLD" ]; then
    # Compact memory
    if [ "x$CLEANUP_MEMORY_ON_START" = "xyes" ]; then
        sudo -n sysctl vm.drop_caches=3 vm.compact_memory=1 >/dev/null
    fi

    # Extract node id from virsh dumpxml
    XML_INFO=$(virsh --connect ${LIBVIRT_URI} dumpxml ${DOMAIN})
    IFS= read -r -d '' NODE_ID < <(echo "$XML_INFO" | $XPATH --subtree /domain/cpu/numa/cell/@id)

    MEM_DIFF=$(expr $MEM - $MEM_OLD)

    case $MEM_DIFF in
    -*)
      ACTION="detach-device"
      MEM_DIFF=${MEM_DIFF#-}
      ;;
    *)
      ACTION="attach-device"
      ;;
    esac

    # Create tmp file with memory device specification
    TMPFILE=$(mktemp /tmp/resize.XXXXXX)
    echo -e "<memory model='dimm'>\n\t<target>\n\
            <size unit='MiB'>$MEM_DIFF</size>\n\
            <node>$NODE_ID</node>\n\t</target>\n</memory>" >$TMPFILE

    # Add memory to VM
    exec_and_log "virsh --connect ${LIBVIRT_URI} ${ACTION} ${DOMAIN} ${TMPFILE} --live"

    # Cleanup
    rm $TMPFILE

    # Compact memory
    if [ "x$CLEANUP_MEMORY_ON_STOP" = "xyes" ]; then
        sudo -n sysctl vm.drop_caches=3 vm.compact_memory=1 &>/dev/null &
    fi
fi

# Resize VCPU
if [ ! -z "$VCPU" -a "$VCPU" -ne "$VCPU_OLD" ]; then
    exec_and_log "virsh --connect ${LIBVIRT_URI} setvcpus ${DOMAIN} ${VCPU} --live --hotpluggable" \
    "Failed to resize VCPU to ${VCPU} on ${DOMAIN}"
fi
