#!/bin/bash # Remove old kernels safely and cleanly. As it uses urpme, grub is automatically updated. # # LISTK contains the list of kernels to analyse # The script keep the NBK most recents for each of them # Pierre Jarillon - 3 avril 2018 - Tested on Mageia 5..8 # Jean-Baptiste Biernacki 2021 # rev 2021-08-07 PJ # Script permettant de supprimer les anciens kernels # Si il est lancé en tant que root, il propose de supprimer les kernels écrits en rouge. Si on le lance sans être root, il fait le test de la même façon mais affiche "Must be root" et se termine. # Nouvelle version ajoutant la protection du noyau en cours et des options. # Utilisation : remove-old-kernels : [-a] [-d] [-n valeur] # -a = automatique, pas de question. Interactif si non spécifié # -d = mode débogage ou test, rien n'est supprimé, urpme est simulé # -n valeur = nombre de noyaux à garder (-n3 ou -n 3 garde 3 noyaux), Min=2, Défaut=2 # Par exemple remove-old-kernels -d -a ( ou -ad ou -ad) permet de simuler un mode automatique sans rien modifier. # Ce script peut être lancé avec plusieurs options. Pour les afficher : # remove-old-kernels -? # Seul root peut réduire le nombre de kernels. Lancé avec un autre compte, on # obtient un état des noyaux présents et des packages rpm correspondants. # Avec le mode -t (ou -d) les modifications sont simulées. VERSION="Remove-old-kernels 0.9 \n" DEBUG=0 # 1 for debug/test mode, urpme is simulated and not applied NBK=2 # Number of kernels to keep MODE="I" # mode A)utomatic, I)nteractve VISU=0 # If VISU=1, show commands which can be used USAGE=\ "Usage: %s: [-a] [-d] [-t] [-n value] [-p] -a = automatic, no question. Interactive if not specified -d or -t = Debug or test mode, nothing is removed, urpme is simulated -n value = number of kernels to keep (-n3 or -n 3 keep 3 kernels), Min=2, Default=2 -p = show (print) the urpme commands which can be used -v = version -? or -h = show this help. Old kernels are removed safely and cleanly. As urpme is used, grub is automatically updated.\n " # Colors Normal="\033[0m" Green="\033[32m" Red="\033[31m" GrBg="\033[102;30m" # Green Background ClearLine="\r\033[2K" # Clear the line LISTK=\ "kernel-desktop586 kernel-desktop kernel-desktop-devel kernel-server kernel-server-devel kernel-source kernel-tmb-desktop kernel-tmb-desktop-devel kernel-tmb-source kernel-linus kernel-linus-devel kernel-linus-source " #Parsing arguments if [[ ${#} -gt 0 ]] ; then while getopts adtpvn:?h NAME ; do case ${NAME} in a) MODE="A";; d|t) DEBUG=1 ;; p) VISU=1 ;; n) NBK=${OPTARG} ;; v) printf "${VERSION}" exit 2;; ?|h) printf "${USAGE}" ${0} exit 2;; esac done if [[ ${NBK} -lt 2 ]]; then NBK=2 # Unsafe if less fi fi # Get the release of the current kernel CURK=$(uname -r | cut -d- -f1) # Storage for the list of kernels to remove TMPKTR=$(mktemp) # Check storage usage on root partition OCCDISK1=$(df -B 1k -l --output=used / | tail -n1 | awk '{ print $1 }') #================================= Analyse /boot/ ============================= NK=$(ls /boot/vmlinuz*.mga* | wc -l) echo -e "${GrBg} Number of kernels in /boot/ : ${NK} ${Normal} " #================================= Analyse rpm ============================= for kernelType in ${LISTK} ; do echo -ne "${ClearLine}" echo -ne "\r ==> ${kernelType}" export n=0; installedKernelCounter=0; rpm -qa --last "${kernelType}-[0-9]*" | while read installedKernel ; do # Not possible, as it is kernelType-[0-9]andAnything and kernelType-lastest is not included. # [ $(echo ${installedKernel} | grep "latest" | wc -l ) -eq 1 ] && continue # Security installedKernelCounter=$((${installedKernelCounter} + 1)) #Return to the line if there exists at least one installedKernel of this kernelType if [[ ${installedKernelCounter} -eq 1 ]] ; then echo "" ; fi installedKernelPackage=$(echo ${installedKernel} | cut -d ' ' -f 1 ) if [[ $(echo ${installedKernel} | grep ${CURK} | wc -l ) -eq 1 ]] ; then NOTA="used now " # current kernel REMVBL=0 # not removable else NOTA="" # not currently used REMVBL=1 # is removable fi if [[ ${installedKernelCounter} -gt $NBK ]] ; then if [[ ${REMVBL} -ne 1 ]] ; then echo -e "\r ${installedKernelCounter} : keep : ${Green}${installedKernel} ${Normal}${NOTA}" else echo -e "\r ${installedKernelCounter} : remove : ${Red}${installedKernel} ${Normal}${NOTA}" echo ${installedKernelPackage} >>${TMPKTR} fi else echo -e "\r ${installedKernelCounter} : keep : ${Green}${installedKernel} ${Normal}${NOTA}" fi done done echo -e "${ClearLine}" #================================= Mode of execution =================== nbt=$(cat ${TMPKTR} | wc -l) if [[ ${nbt} -ne 0 ]] ; then if [[ $(id -u) -ne 0 ]] ; then echo "Must be root to allow urpme" if [ ${VISU} -eq 1 ]; then for f in $(tac ${TMPKTR}) ; do echo "urpme ${f}" done fi else if [[ ${MODE} != "A" ]] ; then if [[ ${DEBUG} -eq 1 ]] ; then echo -e "\n${Green}>> Debug/test mode is on - kernels won't be removed <<${Normal}" fi plural="s" ; [ ${nbt} -eq 1 ] && plural="" read -p "Remove ${nbt} kernel${plural} ? y/N/i (i=confirm for each) " -n 1 response if [[ -z ${response} ]] ; then response="n" ; fi case ${response} in [Yy]) AUTO="--auto" ASK=0 MODE="A" echo -e " \n" ;; [Ii]) AUTO="--auto" MODE="I" echo " interactif" ;; *) echo -e "\nAborted" rm -f ${TMPKTR} exit 0 ;; esac fi #================================= Execution =========================== for installedKernelPackage in $(tac ${TMPKTR}) ; do if [[ ${MODE} = "I" ]] ; then # --- interactive mode --- read -p "Remove ${installedKernelPackage} ? y/N/q (q=quit/abort) " -n 1 response if [[ -z ${response} ]] ; then response="N" ; fi case ${response} in [Yy]) if [[ ${DEBUG} -eq 1 ]] ; then echo "\nDEBUG: Could execute: urpme ${AUTO} ${installedKernelPackage}" nbt=$((${nbt} - 1)) else urpme ${installedKernelPackage} nbt=$((${nbt} - 1)) fi ;; [qQ]) echo -e "\nAborted" rm -f ${TMPKTR} exit 0 ;; *) #echo "do nothing" continue ;; esac else # --- automatic mode --- if [[ ${DEBUG} -eq 1 ]] ; then echo "DEBUG: Could execute: urpme ${AUTO} ${installedKernelPackage}" nbt=$((${nbt} - 1)) else #echo "Here is the execution" urpme ${AUTO} ${installedKernelPackage} nbt=$((${nbt} - 1)) fi fi done NK=$(ls /boot/vmlinuz*.mga? | wc -l) OCCDISK2=$(df -B 1k -l --output=used / | tail -n1 | awk '{ print $1 }') echo -e "${GrBg} Gain : $((OCCDISK1 - OCCDISK2)) k - Kernels in /boot/: ${NK} ${Normal}" fi fi rm -f ${TMPKTR} # Run again if some removable kernels are left [ $(id -u) -ne 0 ] && exit 0 [ ${MODE} != "I" ] && exit 0 [ ${nbt} -gt 0 ] && ${0}