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

# resize image size vmid

SRC=$1
SIZE=$2
VM_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/tm/fs_lvm/fs_lvm.conf

#-------------------------------------------------------------------------------
# Set dst path and dir
#-------------------------------------------------------------------------------

SRC_PATH=`arg_path $SRC`
SRC_HOST=`arg_host $SRC`
SRC_DIR=`dirname $SRC_PATH`

DS_SYS_ID=$(echo $SRC_DIR | $AWK -F '/' '{print $(NF-1)}')

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

DISK_ID=$(basename ${SRC_PATH} | cut -d. -f2)

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]/LVM_THIN_ENABLE )

# This will be undefined when deleting VM dirs
LVM_THIN_ENABLE="${XPATH_ELEMENTS[j++],,}"

#-------------------------------------------------------------------------------
# Resize disk
#-------------------------------------------------------------------------------

POOL_NAME="lv-one-$VM_ID-pool"
LV_NAME="lv-one-$VM_ID-$DISK_ID"
VG_NAME="vg-one-$DS_SYS_ID"
DEV="/dev/${VG_NAME}/${LV_NAME}"

# Get current LV size
LVSIZE_CMD=$(cat <<EOF
    set -e -o pipefail
    ${SUDO} ${LVS} --nosuffix --noheadings --units B -o lv_size "${DEV}" | tr -d '[:blank:]'
EOF
)

LVSIZE_OLD=$(ssh_monitor_and_log "$SRC_HOST" "$LVSIZE_CMD" \
        "Failed to get current LV size")

if [ $? -ne 0 ] || [ -z "${LVSIZE_OLD}" ]; then
    error_message "$script_name: Could not detect current size of LV ${LV_NAME}"
    exit 1
fi

LVSIZE_DIFF=$((SIZE - LVSIZE_OLD/1024/1024))

# Execute lvextend with a lock in the frontend
RESIZE_CMD=$(cat <<EOF
    set -e -o pipefail
    $SYNC
    $SUDO $LVSCAN
    # If there exists a thin pool for this LV, extend it too
    if [ -n "\$($SUDO $LVS --noheading -S "vg_name = $VG_NAME && lv_name = $POOL_NAME")" ]; then
        $SUDO $LVEXTEND -L +${LVSIZE_DIFF}M $VG_NAME/$POOL_NAME
    fi
    $SUDO $LVEXTEND -L ${SIZE}M "$DEV"
EOF
)

LOCK="tm-fs_lvm-${DS_SYS_ID}.lock"
exclusive "${LOCK}" 120 ssh_exec_and_log "$SRC_HOST" "$RESIZE_CMD" \
        "Error resizing LV named $LV_NAME"

# Zero additional space
if [ "${ZERO_LVM_ON_CREATE}" = "yes" ] && [ "$LVM_THIN_ENABLE" != 'yes' ]; then
ZERO_CMD=$(cat <<EOF
    set -e -o pipefail

    LVSIZE_NEW=\$(${SUDO} ${LVS} --nosuffix --noheadings --units B -o lv_size "${DEV}" | \
        tr -d '[:blank:]')

    ${DD} if=/dev/zero of="${DEV}" bs=${DD_BLOCK_SIZE:-64k} \
        oflag=seek_bytes iflag=count_bytes \
        seek="${LVSIZE_OLD}" count="\$(( LVSIZE_NEW - ${LVSIZE_OLD} ))"
EOF
)

ssh_exec_and_log "$SRC_HOST" "$ZERO_CMD" \
        "Error preparing additional space on LV $LV_NAME"
fi

exit 0
