#!/bin/bash

# Install kernel image, modules and initrd.
# This would normally be done using 'make install', but:
# - we share /boot between distributions and install them in subdirectories
# - many older distributions did not implement the hook to build an initrd

set -e

sfc_disttag() {
    local name="$(lsb_release -i 2>/dev/null | sed 's/^Distributor ID:\s*//')"
    local release="$(lsb_release -r 2>/dev/null | sed 's/^Release:\s*//')"
    case "$name" in
	CentOS)
	    # Drop update number
	    echo "centos${release%.*}"
	    ;;
	Debian)
	    # Drop point release number
	    case "$release" in
		*.*.* | [7-9].*)
		    echo "deb%{release%.*}"
		    ;;
		*)
		    echo "deb$release";
		    ;;
	    esac
	    ;;
	'Red Hat Enterprise Linux' | RedHatEnterprise*)
	    # Drop update number
	    echo "rhel${release%.*}"
	    # XXX MRG is not differentiated
	    ;;
	Ubuntu)
	    echo "ubu$release"
	    ;;
	'SUSE LINUX')
	    echo "sles$release"
	    ;;
	'')
	    # Fedora does not install lsb_release by default
	    if [ -f /etc/fedora-release ]; then
		awk '
		    /Fedora Core release/ { printf "fc%s\n", $4; exit }
	            /Fedora release/ { printf "f%s\n", $3; exit }
		    ' /etc/fedora-release
	    elif [ -f /etc/SuSE-release ]; then
		awk '
		    /SUSE Linux Enterprise Server/ { print "sles$\n", $5; exit }
		    ' /etc/SuSE-release
	    else
		echo >&2 "Unknown distribution"
		exit 1
	    fi
	    ;;
    esac
}

arch="${ARCH:-$(uname -i)}"
dist="$(sfc_disttag)"
version="$(make kernelrelease || sed -n 's/^#define UTS_RELEASE "\(.*\)"$/\1/; T; p; q' include/linux/version.h)"
test -n "$version"

case "$arch" in
    i386 | x86_64)
	kernel_image=arch/"$arch"/boot/bzImage
	if file -L /bin/sh | grep -q 64-bit; then
	    kernel_image_dir=/boot/"$dist"-64
	else
	    kernel_image_dir=/boot/"$dist"-32
	fi
	kernel_meta_dir="$kernel_image_dir"
	;;
    ppc64)
	kernel_image=arch/powerpc/boot/zImage
	kernel_image_dir=/boot
	kernel_meta_dir=/boot
	;;
    ia64)
	# XXX This is not generic, but will do for now
	kernel_image=arch/ia64/hp/sim/boot/vmlinux.gz
	kernel_image_dir=/boot/efi/efi/redhat
	kernel_meta_dir=/boot
	;;
    *)
	echo >&2 "I don't know what to do on $arch"
	exit 1
	;;
esac

echo Installing...
O="${KBUILD_OUTPUT:-.}"
cp "$O/$kernel_image" "$kernel_image_dir"/vmlinuz-"$version"
ln -sf vmlinuz-"$version" "$kernel_image_dir"/vmlinuz-latest
cp "$O"/System.map "$kernel_meta_dir"/System.map-"$version"
[ "$kernel_meta_dir" = /boot ] || ln -sf "$kernel_meta_dir"/System.map-"$version" /boot/
cp "$O"/.config "$kernel_meta_dir"/config-"$version"
make modules_install INSTALL_MOD_STRIP=1

if [ -d /sys/module/bnx2 ]; then
    echo >&2 'N: You may need to install updated firmware for bnx2'
fi

echo Building initrd/initramfs...
case "$dist" in
    centos[45]|rhel[45])
	mkinitrd -f "$kernel_image_dir"/initrd-"$version".img "$version"
	ln -sf initrd-"$version".img "$kernel_image_dir"/initrd-latest.img
	;;
    centos*|f*|rhel*)
	dracut --force "$kernel_image_dir"/initramfs-"$version".img "$version"
	ln -sf initramfs-"$version".img "$kernel_image_dir"/initramfs-latest.img
	;;
    osuse*|sles*|suse*)
	mkinitrd -k "$kernel_image_dir"/vmlinuz-"$version" -i "$kernel_image_dir"/initrd-"$version"
	ln -sf initrd-"$version" "$kernel_image_dir"/initrd-latest
	;;
    deb*|ubu*)
	if [ -f /boot/initrd.img-"$version" ]; then
	    update-initramfs -u -k "$version"
	else
	    update-initramfs -c -k "$version"
	fi
	mv /boot/initrd.img-"$version" "$kernel_image_dir"
	ln -sf initrd.img-"$version" "$kernel_image_dir"/initrd.img-latest
	;;
esac
