#!/bin/bash

set -o pipefail

echo -e "UUID update utility v0.2\n"


root=`df / | grep " /$" | awk '{print $1}'`
[[ $root != /dev/* ]] && echo "Error: unable to get root partition" && exit 1

root_disk=`echo ${root} | sed 's/\([[:digit:]]\)//'`
efi_part=$(fdisk -l ${root_disk} | grep EFI | awk '{print $1}')

uuid=`blkid $root | grep -oP " UUID=\"\K[^\"]+"`
[[ $? -ne 0 || -z $uuid ]] && echo "Error: unable to get uuid of $root" && exit 2

if ! grep -q "$uuid" /etc/fstab; then
	echo "Error: UUID not found in FSTAB"
	exit 3
fi
echo "> Root partition: $root, UUID: $uuid"

[[ "$1" != "--new" ]] && echo -e "\n use with --new to update UUID on root partition\n" && exit

#sleep 5

echo "> Changing UUID"
tune2fs -O ^uninit_bg $root > /dev/null || echo "Error: tune2fs feature clearing failed"
tune2fs -U random $root > /dev/null || echo "Error: UUID changing failed"
tune2fs -O +uninit_bg $root > /dev/null || echo "Error: tune2fs feature setting failed"

new_uuid=`blkid $root | grep -oP " UUID=\"\K[^\"]+"`
[[ $? -ne 0 || -z $new_uuid ]] && echo "Error: unable to get new UUID of $root" && exit 4

if [[ ! -z $new_uuid && $new_uuid != $uuid ]]; then
	echo "> New UUID: $new_uuid"
	rc=0
	sed -i "s/$uuid/$new_uuid/g" /etc/fstab
	grep -q "$new_uuid" /etc/fstab && echo "> FSTAB update complete" || { echo "> FSTAB update failed"; rc=1; }
	update-grub 2>/dev/null && echo "> GRUB update complete" || { echo "> GRUB update failed"; rc=1; }
	if [[ ! -z $efi_part ]]; then
		efi_mnt=/var/tmp_uuid_efi
		mkdir -p $efi_mnt
		if mount ${efi_part} $efi_mnt; then
			# Patch every grub config on the ESP, not only /EFI/BOOT/grub.cfg:
			# replace the old UUID and force any 'search --fs-uuid' to the new one.
			found=0
			while read -r cfg; do
				sed -i -E "s/${uuid}/${new_uuid}/g; s/(--fs-uuid[= ])[^ \"']+/\1${new_uuid}/g" "$cfg" && found=1
			done < <(grep -rlIs -e "$uuid" -e "fs-uuid" $efi_mnt 2>/dev/null)
			sync
			umount $efi_mnt
			[[ $found -eq 1 ]] && echo "> EFI GRUB update complete" || { echo "> EFI grub.cfg with UUID not found"; rc=1; }
		else
			echo "> Unable to mount EFI partition $efi_part"
			rc=1
		fi
		rmdir $efi_mnt 2>/dev/null
	fi
	[[ $rc -ne 0 ]] && exit 5
fi

sync
exit 0

