├── README.md └── purge-old-kernels /README.md: -------------------------------------------------------------------------------- 1 | purge-old-kernels 2 | ================= 3 | 4 | Overview 5 | -------- 6 | 7 | This program remove old kernel packages on Linux distros or Proxmox. 8 | 9 | 10 | Installing 11 | ---------- 12 | 13 | You can install it simply running these commands on your computer: 14 | 15 | ``` 16 | wget --no-check-certificate -O /usr/local/sbin/purge-old-kernels https://github.com/algodelinux/purge-old-kernels/raw/master/purge-old-kernels 17 | chmod 755 /usr/local/sbin/purge-old-kernels 18 | ``` 19 | 20 | ## Authors 21 | 22 | - Dustin Kirkland 23 | - Kees Cook 24 | - Esteban M. Navas Martín 25 | -------------------------------------------------------------------------------- /purge-old-kernels: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # purge-old-kernels - remove old kernel packages 4 | # Copyright (C) 2012 Dustin Kirkland 5 | # 2017-2025 Esteban M. Navas Martín 6 | # 7 | # Authors: Dustin Kirkland 8 | # Kees Cook 9 | # Esteban M. Navas Martín 10 | # 11 | # This program is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, version 3 of the License. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program. If not, see . 22 | 23 | export VERSION=1.5 24 | 25 | SCRIPT="$(basename $0)" 26 | 27 | RED='\033[0;31m' 28 | GREEN='\033[0;32m' 29 | NC='\033[0m' 30 | 31 | 32 | # Ensure we're running as root 33 | if [ "$(id -u)" != 0 ]; then 34 | echo -e "${RED}ERROR: This script must run as root. Hint...${NC}" 1>&2 35 | echo " sudo $0 $@" 1>&2 36 | exit 1 37 | fi 38 | 39 | print_version() { 40 | echo "$SCRIPT $VERSION" 41 | } 42 | 43 | print_help () { 44 | echo "$SCRIPT $VERSION" 45 | echo "Purge old kernels tool" 46 | echo "" 47 | echo "Usage: $SCRIPT [OPTIONS]" 48 | echo "Recognized options:" 49 | echo " -h, --help display this help and exit" 50 | echo " -v --version display $SCRIPT version and exit" 51 | echo " -s, --show-installed-kernels display installed kernels" 52 | echo " -k, --keep N keep last N kernels" 53 | echo " ALWAYS keep the currently running kernel" 54 | echo " -n, --no-rm-modules don't remove non installed kernels directories in /lib/modules" 55 | echo " -q, --quiet pass -q option to apt-get" 56 | echo " -y, --yes pass -y option to apt-get" 57 | echo " -o, --option pass extra options to apt-get" 58 | echo 59 | } 60 | 61 | parse_options() { 62 | TEMP=`getopt -o hvsk:qyno: --long help,version,show-installed-kernels,keep:,quiet,yes,no-rm-modules,option -n 'purge-old-kernels' -- "$@"` 63 | 64 | if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi 65 | 66 | eval set -- "$TEMP" 67 | 68 | while true; do 69 | case "$1" in 70 | -h | --help) 71 | print_help 72 | exit 0 73 | ;; 74 | -v | --version) 75 | print_version 76 | exit 0 77 | ;; 78 | -s | --show-installed-kernels ) 79 | show_installed_kernels 80 | shift 81 | ;; 82 | -n | --no-rm-modules ) 83 | NO_RM_MODULES=true 84 | shift 85 | ;; 86 | -k | --keep ) 87 | KEEP="$2" 88 | shift 2 89 | ;; 90 | -q | --quiet ) 91 | APT_OPTS="$APT_OPTS -q" 92 | shift 1 93 | ;; 94 | -y | --yes ) 95 | APT_OPTS="$APT_OPTS -y" 96 | shift 1 97 | ;; 98 | -o | --option ) 99 | APT_OPTS="$APT_OPTS -o $2" 100 | shift 2 101 | ;; 102 | -- ) 103 | shift 104 | break 105 | ;; 106 | * ) 107 | echo "Internal error: doesn't recognize argument '$1'" 108 | exit 1 109 | ;; 110 | esac 111 | done 112 | } 113 | 114 | show_installed_kernels () { 115 | INSTALLED_KERNELS=$(ls /boot/vmlinuz-* | sed -e "s/^\/boot\/vmlinuz-//" | awk -F'[.-]' '{print $1"\t"$2"\t"$3"\t"$4"\t"$0}' | sort -k1 -k2 -k3 -k4 -n | cut -f5) 116 | echo -e "Installed kernels:" 117 | echo -e "${GREEN}$INSTALLED_KERNELS${NC}" 118 | } 119 | 120 | # NOTE: This script will ALWAYS keep the currently running kernel 121 | # NOTE: Default is to keep 2 more, user overrides with --keep N 122 | KEEP=2 123 | APT_OPTS= 124 | NO_RM_MODULES=false 125 | PURGE="" 126 | COUNT_KERNEL_SERIES=0 127 | 128 | parse_options "$@" 129 | 130 | echo "We keep last $KEEP installed kernels" 131 | 132 | # Get kernel type: pve or not 133 | PVE_KERNEL=$(uname -r|grep pve) 134 | 135 | # Build our list of kernel packages to purge 136 | CANDIDATES=$(ls /boot/vmlinuz-* | sed -e "s/^\/boot\/vmlinuz-//" | awk -F'[.-]' '{print $1"\t"$2"\t"$3"\t"$4"\t"$0}' | sort -k1 -k2 -k3 -k4 -n | cut -f5 | head -n -${KEEP} | grep -v "$(uname -r)$" | grep -oiE '[0-9]+\.[0-9]+\.[0-9]+-[0-9]+') 137 | 138 | for c in $CANDIDATES; do 139 | PURGE="$PURGE $(dpkg -l | awk '{print $2}' | grep -E "^(linux|proxmox).*$c" | tr "\n" " ")" 140 | 141 | if [[ "$PURGE" == *"proxmox-kernel"* ]]; then 142 | SERIES=$(echo "$c" | awk -F'.' '{print $1 "." $2}') 143 | COUNT_INSTALLED_KERNEL_SERIES=$(dpkg -l | grep "proxmox-kernel" | grep -E "$SERIES.*pve" | wc -l) 144 | COUNT_CANDIDATES_KERNEL_SERIES=$(echo $PURGE | tr ' ' '\n' | grep "proxmox-kernel" | grep -E "$SERIES.*pve" | wc -l) 145 | 146 | if [ $COUNT_CANDIDATES_KERNEL_SERIES -eq $COUNT_INSTALLED_KERNEL_SERIES ]; then 147 | PURGE="$PURGE proxmox-kernel-$SERIES proxmox-headers-$SERIES" 148 | fi 149 | fi 150 | done 151 | 152 | if [ -z "$PURGE" ]; then 153 | echo "No kernels are eligible for removal" 154 | exit 0 155 | fi 156 | 157 | # Purge old installed kernels 158 | apt-get $APT_OPTS remove --purge $PURGE 159 | 160 | # Build our list of uninstalled kernel packages to purge 161 | REMOVED=$(dpkg -l| grep ^rc | awk '{print $2}' | grep -E "(proxmox-kernel|proxmox-headers|linux-image|linux-headers)") 162 | 163 | # Purge old uninstalled kernels 164 | [ -n "$REMOVED" ] && apt-get $APT_OPTS remove --purge $REMOVED 165 | 166 | if [ -z "$PVE_KERNEL" ] && [ "$NO_RM_MODULES" = false ]; then 167 | # Remove old /lib/modules kernel directories 168 | find /lib/modules -mindepth 1 -maxdepth 1 $(dpkg --get-selections | grep -e 'linux-image.[0-9].*' | awk '{print $1}' | sed 's/linux-image-/-not -name /' | tr "\n" " ") -exec rm -fr {} \; 169 | fi 170 | --------------------------------------------------------------------------------