#!/usr/bin/env bash

set -e

GROW_ROOTFS=${GROW_ROOTFS:-YES}
GROW_ROOTFS=${GROW_ROOTFS^^}

if [ "${GROW_ROOTFS}" != 'YES' ]; then
    echo 'Skipped root filesystem growing.' >&2
    exit 0
fi

# FreeBSD
if [ -x /etc/rc.d/growfs ]; then
    /etc/rc.d/growfs onestart
    exit $?
fi

MOUNT_LINE=$(cat /etc/mtab | grep ' / ' | grep -v '^rootfs')
DEVICE=$(echo "$MOUNT_LINE" | cut -d' ' -f1)
FSTYPE=$(echo "$MOUNT_LINE" | cut -d' ' -f3)
GROWPART=$(which growpart)

if [ $? -ne 0 ]; then
  echo "growpart command is missing"
  exit 1
fi

if [ $(lvdisplay ${DEVICE} 2>/dev/null | wc -l) -eq 0 ]; then
  DEVICE=$(findmnt -ln -o SOURCE /)
  DISK=$(echo "$DEVICE" | sed 's/[0-9]*$//')
  PARTITION=$(echo "$DEVICE" | sed "s|^$DISK||")
  LVM="no"
fi

if [ "${LVM}" != "no" ]; then
  if [ -f /etc/debian_version ]; then
    DEVICE=$(mount | grep ' / ' | grep -v '^rootfs'|cut -d' ' -f1)
  fi
  PVRESIZE=$(which pvresize)
  LVEXTEND=$(which lvextend)
  DISK=$(pvdisplay |grep "PV Name"|awk '{print $3}'|sed 's/.$//')
  PARTITION=$(pvdisplay |grep "PV Name"|awk '{print $3}'| sed "s|^${DISK}||")
  PV=$(pvdisplay |grep "PV Name"|awk '{print $3}')
  LV=$(lvdisplay ${DEVICE} |grep "LV Path"|awk '{print $3}')

  # when PV is on MSDOS logical partition, detect the umbrella
  # extended partition and grow it first
  TABLE=$(parted -s ${DISK} print 2>/dev/null | grep 'Partition Table:' | awk '{print $3}')
  if [ "${TABLE}" = 'msdos' ] && [ ${PARTITION} -gt 4 ]; then
    PARTITION="$(parted -s ${DISK} print | grep 'extended' | awk '{print $1}') $PARTITION"
  fi
fi

if [ -n "$DEBUG" ]; then
  echo DEVICE: ${DEVICE}
  echo FSTYPE: ${FSTYPE}
  echo DISK: ${DISK}
  echo PARTITION: ${PARTITION}
fi

(
  for PART in ${PARTITION}; do
    ${GROWPART} ${DISK} ${PART}
  done

  if [ "${LVM}" != "no" ]; then
    ${PVRESIZE} ${PV}
    ${LVEXTEND} -l +100%FREE ${LV}
  fi
) || :  # don't fail, partition can be already extended by dracut

case "${FSTYPE}" in
  ext2|ext3|ext4)
    resize2fs ${DEVICE}
    ;;
  xfs)
    xfs_growfs /
    ;;
  btrfs)
    btrfs filesystem resize max /
    ;;
esac
