#!/bin/sh
# Copyright (C) 2008 Vladimir V. Kamarzin <vvk@altlinux.org>
#
# Remove all kernels except current
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

. shell-error
. shell-args

show_help()
{
        cat <<EOF
Usage: $PROG [options]
Valid options are:
	-f, -y, --force   non-interactive kernel removal (default is interactive)
	-n, --dry-run     just simulate removal
	-t, --type        remove kernels with specified flavour (ovz-smp, std-def, etc)
	-a, --all         remove kernels with all flavours
	-h, --help        show this text and exit
EOF
exit 1
}

#parse command line options
TEMP=`getopt -n $PROG -o f,y,n,t:,h,a -l force,dry-run,type:,help,all -- "$@"` || show_help
eval set -- "$TEMP"

while :; do
        case "$1" in
                --) shift; break
                        ;;
                -f|-y|--force) force="-y"
                        ;;
		-n|--dry-run) dryrun="--no-remove"
			;;
		-t|--type) shift ; kernel_flavour="$1"
			;;
		-a|--all) all=1
			;;
                -h|--help) show_help
        esac
	shift
done

if [ -n "$force" -a -n "$dryrun" ]; then
	show_usage '--force and --dry-run are mutually exclusive options.'
fi

if [ -n "$kernel_flavour" -a -n "$all" ]; then
	show_usage '--type and --all are mutually exclusive options.'
fi

###### copied from update-kernel
# get running kernel version
current_kernel_package=$(rpmquery -qf /lib/modules/$(uname -r)/kernel 2>/dev/null)
if [ -n "$current_kernel_package" ] ; then
    current_kernel_pkgname=$(rpmquery --queryformat "%{NAME}-%{SERIAL}:%{VERSION}-%{RELEASE}\n" -q $current_kernel_package)
    echo $current_kernel_pkgname | grep -q "(none)" && current_kernel_pkgname=$(rpmquery --queryformat "%{NAME}-%{VERSION}-%{RELEASE}\n" -q $current_kernel_package)
else
    current_kernel_pkgname="UNKNOWN"
fi
echo "Running kernel version: $current_kernel_pkgname"
#######

# set kernel flavour. if not defined with -t option, use current
current_kernel_flavour="$(uname -r)"
current_kernel_flavour="${current_kernel_flavour#*-}"
current_kernel_flavour="${current_kernel_flavour%-*}"
if [ -n "$all" ] ; then
	flavours="$(rpm -qa --queryformat '%{NAME}\n' | fgrep kernel-image- | fgrep -v domU | sort -u | cut -d "-" -f3- | tr '\n' ' ')"
else
	flavours="${kernel_flavour:-$current_kernel_flavour}"
fi

echo "Checking for installed kernel packages..."
flavour_version_release="$(uname -r | awk -F- '{print $2"-"$3"-"$1"-"$4}')"

echo "For removing:"
for kernel_flavour in $flavours
do
	old_kernels="$(rpm -qa | fgrep kernel-image-$kernel_flavour | fgrep -v $flavour_version_release | sort | tr '\n' ' ')"
	if [ -n "$all" ] ; then
		echo "$kernel_flavour:"
	fi
	for kernel in $old_kernels
	do
		if [ "$current_kernel_flavour" = "$kernel_flavour" ] ; then
			comparever="$(rpmevrcmp "$current_kernel_package" "$kernel")"
			[ "$comparever" -lt 0 ] && continue
		else
			# check if kernel is latest with given flavour
			latest=1
			for kernel2 in $old_kernels
			do
				comparever="$(rpmevrcmp "$kernel" "$kernel2")"
				[ "$comparever" -lt 0 ] && latest=0
			done
			[ "$latest" -eq 1 ] && continue
		fi
		echo "  $kernel"
		apt_args_list="$apt_args_list $(rpm -q --queryformat '%{NAME}=%{EPOCH}:%{VERSION}-%{RELEASE}\n' $kernel \
			| sed -e "s,(none):,,g")"
	done
done
echo

if [ -z "$apt_args_list" ] ; then
	echo "Nothing to remove."
	exit 0
fi

# use sudo(1) if running as unprivileged user
[ "$UID" = "0" ] && SUDO= || SUDO=sudo

$SUDO apt-get $force $dryrun remove $apt_args_list

# Mask non-zero apt exit code on dry run:
if [ -n "$dryrun" ]; then
    exit 0
fi
