upsnapz/upsnapz.sh
2025-02-09 14:46:58 +01:00

275 lines
6.7 KiB
Bash
Executable File

#!/bin/bash
# Time-stamp: <2025-02-09 14:45:56 nomad>
#
# Michel Le Cocq <lecocq@ipgp.fr>
# <nomad@neuronfarm.net>
#
# Licence Art Libre 1.3 (LAL 1.3)
# upsnapz.sh
#
# Script to upgrade your system install on zfs root with zfs boot menu (only Debian for the moment).
#
# refresh apt
# zfs snapshot
# apt upgrade
# apt autoremove
# zfs clone promote
# check zfs boot menu release
# check zfs pool status
# Depend :
# - gh
# To do or not :
#
# ajouter zpool upgrade or not
# ajouter question cleanup zroot
#
# regarder si un nouveau kernel existe et si oui faire ce qu'il y a a faire
#
# ameliorer check zfs boot menu
function check_zpool_status
{
# check zpool status if it's upgradable
printf 'Check ZFS pool status:\n'
e=$(zpool status | grep action | grep 'zpool upgrade')
if [ $? -eq 0 ]
then
printf 'One or more ZFS pool can be upgraded\n'
zpool status
printf 'In case of ZFS Root be carefull that your bootloader is up to date and compatible with this new ZFS feature.\n'
else
printf 'every things ok for ZFS pool.\n'
fi
}
function check_ZFS_BOOT_MENU
{
# check last zfs boot menu release
# compare if we are on last release
printf '\nCheck ZFS_BOOT_MENU:\n'
PA="https://get.zfsbootmenu.org/sha256.txt"
echo " Hit:zfsbootmenu "$PA
curl -s -o /tmp/sha256.txt -L $PA
e=$(grep $(sha256sum /boot/efi/EFI/ZBM/VMLINUZ.EFI | awk '{print $1}') /tmp/sha256.txt | awk -F"[()]" '{print $2}' )
echo -n " Installed Release : "
e=$(echo $e | awk -F'-' '{print $4}')
echo $e
f=$(gh release list --repo https://github.com/zbm-dev/zfsbootmenu | grep Latest | awk -F' ' '{print $4}')
if [ "$e" != "$f" ]
then
echo " /!\ Installed Release and lastest are not same !"$PA
printf ' Latest Release : '
echo $f
fi
if [ -z $e ]
then
echo " /!\ not in sync with : "$PA
echo ' avaible release :'
cat /tmp/sha256.txt | grep EFI | grep release | awk -F"[()]" '{print $2}'
fi
rm /tmp/sha256.txt
}
function askpromote()
{
# ask if we wanted to promote that last snapshot
# promote last bootfs snapshot to a new bootfs env
# suggest name for new bootfs env
# clone promote activate new bootfs
# ask to reboot to new bootfs
snapname=$1
bootfs=$2
parents=$(zfs list -o name | grep $bootfs | awk 'BEGIN{FS=OFS="/"}{NF--; print}')
printf '\nclone and promote before upgrade %s or not \nhost will reboot to new bootfs : [Y-n]' $bootfs@$snapname
read dopromote
if [ -z $dopromote ]
then
dopromote='y'
echo y
fi
if [[ "$dopromote" == "y" ]]
then
printf '\nactual bootfs : %s\n' $bootfs
printf 'other bootfs :\n' $bootfs
zfs list -o name,creation -r $parents -s creation | grep -v ^$parents$
e=$(lsb_release -is)
f=$(date +%b)
sugsname="${e,,}_"$(lsb_release -cs)"_"$(date +%Y)"_"$(date +%m)"_"$(date +%d)
zfs list -H -o name | grep $sugsname
if [ $? -eq 0 ]
then
sugsname=$sugsname"_"$(date +%Y-%m-%d-%H%M%S)
fi
printf '\nname suggestion for new zpool bootfs : %s [Y-n]' $sugsname
read namepros
if [ -z $namepros ]
then
echo y
namepros='y'
fi
if [[ "$namepros" == "n" ]]
then
printf 'new bootfs name :'
read sugsname
if [ $(zfs list -H -o name | grep $sugsname) -eq 0 ]
then
sugsname=$newname_$(date +%Y-%m-%d-%H%M%S)
printf '%s already exist I siggest : %s\n'
fi
printf 'name suggestion : %s\n' $sugsname
fi
sudo zfs clone $bootfs@$snapname $parents/$sugsname
sudo zfs promote $parents/$sugsname
sudo zfs set -u mountpoint=/ $parents/$sugsname
sudo zfs set canmount=noauto $parents/$sugsname
sudo zpool set bootfs=$parents/$sugsname zroot
printf '%s will reboot to new bootfs %s in 5s\nHit Ctrl^c to abort' $(hostname) $sugsname
printf "\nRun again current script $(basename $0) after reboot.\n"
echo -n '.'; sleep 1; echo -n '.'; sleep 1; echo -n '.'; sleep 1; echo -n '.'; sleep 1; echo -n '.';sleep 1; echo -n '.';sleep 1; echo -n '.'
sudo reboot
else
echo no
fi
}
function askautoclean()
{
# ask to autoremove and zfs snapshot before
printf '\napt-get -s autoremove\n'
if [ $(apt-get -s autoremove | sed -n '/The following packages will be REMOVED:/,/^[0-9+] upgraded, [0-9+] newly installed, [0-9+] to remove and [0-9+] not upgraded.$/p' | wc -l) -gt 0 ]
then
apt-get -s autoremove | sed -n '/The following packages will be REMOVED:/,/^[0-9+] upgraded, [0-9+] newly installed, [0-9+] to remove and [0-9+] not upgraded.$/p'
printf '\n%s\n' 'Do we run an autoremove ? : [Y-n]'
read autoclean
if [ -z $autoclean ]
then
echo y
autoclean='y'
fi
if [[ "$autoclean" == "y" ]]
then
printf 'before autoremove : '
asksnap
sudo apt-get -y autoremove
else
echo
fi
fi
sudo apt autoclean
}
function asksnap()
{
# print creation info of last bootfs snapshot
# ask if we want a snapshot of bootfs
# snapshot bootfs
bootfs=$(zpool get bootfs -o value -H zroot)
l=$(zfs list -H -t snapshot -o creation,name -S creation $(zpool get bootfs -o value -H zroot) | head -n1)
printf 'last snapshot : \n%s\n' "$l"
printf '%s <- now\n' "$(date '+%a %b %d %H:%M %Y')"
printf 'snapshot bootfs %s or not ? : [Y-n]' $bootfs
read dosnap
if [ -z $dosnap ]
then
echo y
dosnap='y'
fi
if [[ "$dosnap" == "y" ]]
then
snapname=$(date +%Y-%m-%d-%H%M%S)
sudo zfs snapshot $bootfs@$snapname
zfs list -H -o name $bootfs@$snapname
askpromote $snapname $bootfs
else
echo no
fi
}
function askupgrade()
{
# run apt update
# if there were upgrade ask for upgrade or not
# ask for making a snapshot
# run apt upgrade
# else
# ask for making a snapshot
printf '%s\n' 'apt update'
sudo apt update
if [ $(apt list --upgradable 2>/dev/null | wc -l) -gt 1 ]
then
printf '\n%s\n' 'apt list --upgradable'
apt list --upgradable
printf '\nUpgrade or not : [Y-n]'
read answer
if [ -z $answer ]
then
echo y
answer='y'
fi
if [[ "$answer" == "y" ]]
then
printf 'before upgrade : '
asksnap
printf '%s\n' 'apt -y upgrade'
sudo apt -y upgrade
else
echo no
fi
else
echo
asksnap
fi
}
function usage()
{
echo "Usage: $(basename $0) [-h]"
echo "-b : only check zfs boot menu"
}
while getopts 'hb' OPTION; do
case "$OPTION" in
h)
usage
exit 1
;;
b)
check_ZFS_BOOT_MENU
echo
exit 1
;;
?)
usage
exit 1
;;
esac
done
askupgrade
askautoclean
echo
check_zpool_status
check_ZFS_BOOT_MENU
echo
zpool status
printf '\nNothing else to do.\n'
#~/bin/clean-snapshot.sh