#!/bin/sh -e
#
#  Copyright (c) 2006 Vagrant Cascadian <vagrant@freegeek.org>
#
#  2006, Vagrant Cascadian <vagrant@freegeek.org>
#        Oliver Grawert <ogra@canonical.com>
#  2007, Vagrant Cascadian <vagrant@freegeek.org>
#        Scott Balneaves <sbalneav@ltsp.org>
#  2008, Vagrant Cascadian <vagrant@freegeek.org>
#  2012, Alkis Georgopoulos <alkisg@gmail.com>
#
#  This program 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, you can find it on the World Wide
#  Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
#  Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#

# this script is run either chrooted on the server, or by a client with write
# access to the NFS mount point. (much of this code was originally in
# server/ltsp-update-kernels). --vagrant 20060801

case "$0" in
    /etc/kernel/post*.d*)
        # Relaunch update-kernels with its correct basename so that
        # ltsp-client-functions includes /etc/ltsp/update-kernels.conf.
        QUIET=true exec /usr/share/ltsp/update-kernels "$@"
        ;;
esac

msg() {
    if [ "$QUIET" != "true" ]; then
       echo $@
    fi
}


# This also sources vendor functions and .conf file settings
. /usr/share/ltsp/ltsp-client-functions
require_root

BOOT=${BOOT:-"/boot"}
VENDOR=${VENDOR:-"$(detect_vendor)"}
CHROOT_NAME=${CHROOT_NAME:-"$(detect_arch)"}

# TODO: when a pxemenus package is implemented, distros should replace the
# following code with an /etc/ltsp/update-kernels.conf (or similar) conffile
# with their supported kernel command lines, for NFS, NBD, AoE, iSCSI etc.
if [ -z "$BOOTPROMPT_OPTS" ]; then
    if [ "$VENDOR" = "Ubuntu" ]; then
        BOOTPROMPT_OPTS="root=/dev/nbd0 init=/sbin/init-ltsp quiet splash plymouth:force-splash vt.handoff=7"
    elif [ "$VENDOR" = "Debian" ]; then
        BOOTPROMPT_OPTS="quiet root=/dev/nfs ip=dhcp boot=nfs init=/sbin/init-ltsp"
    else
        BOOTPROMPT_OPTS="root=/dev/nfs ip=dhcp init=/sbin/init-ltsp"
    fi
fi

if [ -f /usr/lib/yaboot/yaboot ]; then
    cp -a -v /usr/lib/yaboot/yaboot $BOOT
    cat > $BOOT/yaboot.conf <<EOF
timeout=0
default=ltsp
root=/dev/ram

image=/ltsp/$CHROOT_NAME/vmlinux
        label=ltsp
        initrd=/ltsp/$CHROOT_NAME/initrd.img
        append="$BOOTPROMPT_OPTS"
EOF

else
    msg "Skipping yaboot configuration. install yaboot package if you need it."
fi

syslinux_dir=/usr/lib/syslinux
if [ -f $syslinux_dir/pxelinux.0 ]; then
    PXECFG=$BOOT/pxelinux.cfg
    cp $syslinux_dir/pxelinux.0 $BOOT

    # copy over variant with extended support for gPXE
    if [ -f "$syslinux_dir/gpxelinux.0" ]; then
        cp $syslinux_dir/gpxelinux.0 $BOOT
    fi

    # copy the PXELINUX_DEFAULT helper program if installed, such as menu or
    # vesamenu
    if [ -f "$syslinux_dir/$PXELINUX_DEFAULT.c32" ]; then
        cp "$syslinux_dir/$PXELINUX_DEFAULT.c32" $BOOT
        case $PXELINUX_DEFAULT in
            # set a timeout, otherwise the menu will wait indefinitely
            menu|vesamenu) TIMEOUT=${TIMEOUT:-"50"} ;;
        esac
    fi

    if [ ! -d $PXECFG ]; then
        mkdir $PXECFG
    fi
    cat > $PXECFG/default <<EOF
default ${PXELINUX_DEFAULT:-"ltsp"}
${TIMEOUT:+timeout $TIMEOUT}

label ltsp
kernel vmlinuz
append ro initrd=initrd.img $BOOTPROMPT_OPTS
ipappend ${IPAPPEND:-2}

EOF

    if [ -f "$PXELINUX_APPEND_FILE" ]; then
        cat "$PXELINUX_APPEND_FILE" >> $PXECFG/default
    fi

    memtest_bin='memtest86+.bin memtest86.bin'
    for memtest in $memtest_bin ; do
        memtest_name=$(basename $memtest .bin)
        if [ -f $BOOT/$memtest_name ]; then
            # prefer memtest86+ and memtest86 without the .bin extension, to
            # work around bug(s) in pxelinux/memtest86*:
            # http://bugs.debian.org/546219
            memtest="$memtest_name"
        fi
        if [ -f $BOOT/$memtest ]; then
            cat >> $PXECFG/default <<EOF

label $memtest_name
kernel $memtest

EOF
        fi
    done

else
    msg "Skipping PXE configuration.  Install the syslinux package if you need it."
fi

# allow specifying a specific kernel image to update, from kernel postinst
if [ -f "$2" ]; then
    ALL_KERNELS="$2"
else
    ALL_KERNELS="$(find $BOOT -type f -name 'vmlinu*')"
fi

# look for symlinks, too, and put them after the "real" kernels
ALL_KERNELS="$ALL_KERNELS $(find $BOOT -type l -name 'vmlinu*')"

for kernel in $ALL_KERNELS ; do
    basename=$(basename "$kernel")
    initrd=initrd.img
    nbi=nbi.img

    case $basename in
        vmlinuz|vmlinux)
            # USE DEFAULT
        ;;
        vmlinu*.old) 
            initrd=$initrd.old
            nbi=$nbi.old
        ;;
        vmlinuz*) 
            version=${basename##vmlinuz-}
            initrd=$initrd-$version
            nbi=$nbi-$version
        ;;
        vmlinux*) 
            version=${basename##vmlinux-}
            initrd=$initrd-$version
            nbi=$nbi-$version
        ;;
    esac

    if [ -L "$kernel" ]; then
        basename="$(readlink $kernel)"
        if [ -f "$BOOT/$basename" ]; then
            case $basename in
                vmlinuz*)
                    version=${basename##vmlinuz-}
                ;;
                vmlinux*)
                    version=${basename##vmlinux-}
                ;;
            esac

            realnbi="nbi.img-$version"
            if [ -f "$BOOT/$realnbi" ]; then
                ln -sf $realnbi $BOOT/$nbi
            fi
        fi
    else
        if which mkelfImage >/dev/null; then
            # x86_64/amd64 i386 ia64(?): mkelfimage
            MKELFIMAGE_INITRD_OPT=""
            if [ -z "$MKELFIMAGE_OPTS" ]; then
                MKELFIMAGE_OPTS="$BOOTPROMPT_OPTS"
            fi
            if [ -f "$BOOT/$initrd" ]; then
                MKELFIMAGE_INITRD_OPT="--ramdisk=$BOOT/$initrd"
            fi
            mkelfImage --command-line="$MKELFIMAGE_OPTS" --output=$BOOT/$nbi.tmp \
                --kernel=$kernel $MKELFIMAGE_INITRD_OPT && mv $BOOT/$nbi.tmp $BOOT/$nbi
        elif which mkelf-linux >/dev/null; then
            # i386: mknbi
            MKELF_LINUX_INITRD_OPT=""
            if [ -z "$MKELF_LINUX_APPEND" ]; then
                MKELF_LINUX_APPEND="$BOOTPROMPT_OPTS"
            fi
            if [ -f "$BOOT/$initrd" ]; then
                MKELF_LINUX_INITRD_OPT="$BOOT/$initrd"
            fi
            mkelf-linux $MKELF_LINUX_OPTS --append="$MKELF_LINUX_APPEND" \
                -o $BOOT/$nbi $kernel $MKELF_LINUX_INITRD_OPT
        else
            if [ -z "$mkelf_seen" ]; then
                mkelf_seen=true
                msg "Skipping etherboot images.  Install the mkelfimage package if you need them."
            fi
        fi
        if which mknbi-linux >/dev/null ; then
            # i386: mknbi
            # generate an legacy-nbi.img for legacy versions of etherboot that
            # didn't support ELF

            MKNBI_LINUX_INITRD_OPT=""
            if [ -z "$MKNBI_LINUX_APPEND" ]; then
                MKNBI_LINUX_APPEND="$BOOTPROMPT_OPTS"
            fi
            if [ -f "$BOOT/$initrd" ]; then
                MKNBI_LINUX_INITRD_OPT="$BOOT/$initrd"
            fi
            mknbi-linux $MKNBI_LINUX_OPTS --append="$MKNBI_LINUX_APPEND" \
                -o $BOOT/legacy-"$nbi" $kernel $MKNBI_LINUX_INITRD_OPT

        fi
    fi
done
