273 lines
6.6 KiB
Bash
Executable File
273 lines
6.6 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Time-stamp: <2025-02-09 14:48:00 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
|
|
|
|
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
|