#!/bin/bash
#
# metadata_begin
# recipe: Grow Disk 
# tags: centos,alma,rocky,oracle,fedora,debian,ubuntu
# revision: 2
# description_ru: Увеличение диска
# description_en: Grow Disk
# metadata_end
#

RNAME="GROW_DISK"

set -x

LOG_PIPE=/tmp/log.pipe.$$
mkfifo ${LOG_PIPE}
LOG_FILE=/root/${RNAME}.log
touch ${LOG_FILE}
chmod 600 ${LOG_FILE}
tee < ${LOG_PIPE} ${LOG_FILE} &
exec > ${LOG_PIPE}
exec 2> ${LOG_PIPE}

killjobs() {
    test -n "$(jobs -p)" && kill $(jobs -p) || :
}
trap killjobs INT TERM EXIT

echo
echo "== Recipe ${RNAME} started at $(date) =="
echo

# Переменные
ROOT_PART=$(mount | grep " / " | awk '{print $1}' | sed 's/\/dev\///')
ROOT_PART_FS=$(lsblk -f /dev/${ROOT_PART} | grep -v "NAME" | awk '{print $2}')
SYSTEM_DISK=$(echo ${ROOT_PART} | sed 's/[^[:alpha:]]\+//')
PART_NUMBER=$(blkid | grep "${SYSTEM_DISK}" | awk '{print $1}' | grep -Eo '[0-9]+' | sort -nk1 | tail -n 1)

# Проверка переменных
[ -n ${ROOT_PART} -a -n ${ROOT_PART_FS} -a -n ${SYSTEM_DISK} -a -n ${PART_NUMBER} ] || exit 1

# Информация об ОС
. /etc/os-release
osLike="${ID_LIKE}"
[ "${ID}" = "debian" ] && osLike="debian"
echo ${ID_LIKE} | grep -q "rhel\|fedora" && osLike="rhel"
[ "${ID}" = "fedora" ] && osLike="rhel"

# Определение пакетного менеджера
DNF="/usr/bin/yum"
[ -f /usr/bin/dnf ] && DNF="/usr/bin/dnf"
[ -f /usr/bin/apt ] && { export DEBIAN_FRONTEND=noninteractive ; DNF="apt_Installer" ; }
[ -n "${DNF}" ] || exit 1

# Финальный текст
final_text() {
cat > /root/${RNAME}-script-final.txt <<- EOF
=========================
Работа скрипта ${RNAME} успешно завершена.
Раздел /dev/${SYSTEM_DISK}${PART_NUMBER} увеличен до максимального размера.
=========================

=========================
The ${RNAME} script completed successfully.
Partition /dev/${SYSTEM_DISK}${PART_NUMBER} increased to maximum size.
=========================

$(date '+%Y-%m-%d %H:%M:%S')
EOF
}

# Определяем инсталятор apt и его опции. Обходим фоновые задачи установки и одновления ОС
apt_Installer() {
while ps uxaww | grep -v grep | grep -Eq 'apt|dpkg' ; do echo "waiting..." ; sleep 5 ; done && \
/usr/bin/apt -o Dpkg::Options::="--force-confold" -o Dpkg::Options::="--force-confdef" -q --allow-downgrades --allow-remove-essential --allow-change-held-packages $@
}

# Установка основных программ и подготовка базовых репозиториев
install_soft() {
which growpart >/dev/null 2>&1 || \
case "${osLike}" in
	"debian" )
	[ $(systemctl is-active unattended-upgrades.service 2>/dev/null) = "active" ] && { systemctl stop unattended-upgrades.service && unattServ="1" ; } ;
	${DNF} update && ${DNF} -y install cloud-guest-utils gdisk
	;;
	"rhel" )
	${DNF} -y install cloud-utils-growpart gdisk
	;;
esac
which partprobe >/dev/null 2>&1 || { ${DNF} -y install parted || echo "No partprobe utils. Please install parted" ; }
# Включаем обратно сервис самообновления Ubuntu
[ -n "${unattServ}" ] && systemctl start unattended-upgrades.service
which growpart >/dev/null 2>&1 || { echo "No growpart utils. Please install cloud-utils-growpart or cloud-guest-utils" && exit 1 ; }
}

grow_disk() {
partprobe >/dev/null 2>&1 || echo "Can not start partprobe" >&2
sleep 2
growpart /dev/${SYSTEM_DISK} ${PART_NUMBER} >/dev/null 2>&1 && { echo "Growing partition completed" ; } || { echo "Can not grow partition because there is no free space" >&2 ;}
case "${ROOT_PART_FS}" in
	"xfs" )
		xfs_growfs -d /dev/${SYSTEM_DISK}${PART_NUMBER} 2>&1 | grep -i -q "data size unchanged" && \
		{ echo "Can not grow XFS FS because there is no free space" >&2 && return 1 ; } || { echo "Growing FS completed" ; }
	;;
	ext* )
		resize2fs /dev/${SYSTEM_DISK}${PART_NUMBER} 2>&1 | grep -i -q "Nothing to do" && \
		{ echo "Can not grow EXT4 FS because there is no free space" >&2 && return 1 ; } || { echo "Growing FS completed" ; }
	;;
	* )
		echo "Can not grow. Unknow FS"
		return 1
	;;
esac
}

install_soft
grow_disk && final_text || { echo "Can not GROW DISK" >&2 && exit 1 ; }
