#!/bin/bash
# Author: Steven Shiau <steven _at_ nchc org tw>
# License: GPL
# Description: Download the netinstall kernel & initrd for DRBL client to install GNU/Linux via network.

# Load DRBL setting and functions
. /opt/drbl/sbin/drbl-conf-functions

# Load some necessary setting from drbl-ocs.conf
. /opt/drbl/conf/drbl-ocs.conf

# Load basic functions of ocs
. /opt/drbl/sbin/ocs-functions

#
supported_gnu_linux="$(set |grep -i _netinstall_ | awk -F"_" '{print $1}' | sort | uniq)"
# make it in a line, and use comma to separate them.
supported_gnu_linux="$(echo $supported_gnu_linux)"
supported_gnu_linux_with_comma="$(echo $supported_gnu_linux | sed -e "s/ /, /g")"
USAGE() {
  echo "Download GNU/Linux netinstall kernel and initrd for DRBL client to install GNU/Linux."
  echo "Usage: $0 [OPTION] DIST"
  echo "OPTION:"
  language_help_prompt_by_idx_no
  echo "-i, --install DIST:       Load GNU/Linux DIST netinstall package into DRBL environment"
  echo "-o, --overwrite:          Overwrite existing images"
  echo "-s, --skip-rerun-gen:     Skip the message about re-run generate-pxe-menu"
  echo "-u, --uninstall DIST:     Uninstall GNU/Linux DIST netinstall package."
  echo "-v, --verbose:     Verbose mode."
  echo "DIST is one of these: $supported_gnu_linux_with_comma"
  echo "Ex: To load Debian netinstall packages, run '$0 -i debian'"
  echo "    To load Fedora netinstall packages, run '$0 -i fedora'"
  echo "    To load all supported GNU/Linux netinstall packages, run '$0 -i all'"
  echo "    To remove Fedora netinstall packages, run '$0 -i fedora'"
  echo "    To remove all GNU/Linux netinstall packages, run '$0 -u all'"
}
#
get_and_put_img() {
  local img_url="$1"
  local dist="$2"
  local iver="$3"
  local iarch="$4"
  local net_ker="$5"
  local net_initrd="$6"
  netinst_tmp="$(mktemp -d /tmp/netinst_tmp.XXXXXX)"
  if [ ! -e "$pxecfg_pd/vmlinuz-netinstall-${dist}-${iver}-${iarch}" -o "$overwrite_img" = "yes" ]; then
    [ "$verbose" = "on" ] && echo "Downloading $img_url/$net_ker..."
    wget $wget_opt -P "$netinst_tmp" $img_url/$net_ker
    if [ -e "$netinst_tmp/$net_ker" ]; then
      mv -f $netinst_tmp/$net_ker $pxecfg_pd/vmlinuz-netinstall-${dist}-${iver}-${iarch}
    else
      [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
      echo "netinstall kernel $net_ker for $iarch $iver ${dist} not found!"
      [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
    fi
  else
    echo "Existing $pxecfg_pd/vmlinuz-netinstall-${dist}-${iver}-${iarch} found!"
  fi

  if [ ! -e "$pxecfg_pd/initrd-netinstall-${dist}-${iver}-${iarch}.img" -o "$overwrite_img" = "yes" ]; then
    [ "$verbose" = "on" ] && echo "Downloading $img_url/$net_initrd..."
    wget $wget_opt -P "$netinst_tmp" $img_url/$net_initrd
    if [ -e "$netinst_tmp/$net_initrd" ]; then
      mv -f $netinst_tmp/$net_initrd $pxecfg_pd/initrd-netinstall-${dist}-${iver}-${iarch}.img
    else
      [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
      echo "netinstall initrd $net_initrd for $iarch $iver ${dist} not found!"
      [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
    fi
  else
    echo "Existing $pxecfg_pd/initrd-netinstall-${dist}-${iver}-${iarch}.img found!"
  fi
  [ -d "$netinst_tmp" ] && rm -f $netinst_tmp/* && rmdir $netinst_tmp
} # end of get_and_put_img

#
get_debian_netinstall() {
  # output file format in /tftpboot/nbi_img/:
  # vmlinuz-netinstall-${dist}-${ver}-${arch)
  # initrd-netinstall-${dist}-${ver}-${i386}.img
  #
  # url ex:
  # http://free.nchc.org.tw/debian/dists/etch/main/installer-i386/current/images/netboot/debian-installer/i386
  # http://free.nchc.org.tw/debian/dists/etch/main/installer-amd64/current/images/netboot/debian-installer/amd64
  for ver in $debian_netinstall_ver; do
    for arch in $debian_netinstall_arch; do
      if [ "$ver" = "sarge" -a "$arch" = "amd64" ]; then
        echo -n "amd64 version of Sarge is not officially supported! Skip this. "
	continue
      fi
      url=$url_site/$path_to_debian/$ver/main/installer-$arch/current/images/netboot/debian-installer/$arch
      get_and_put_img $url Debian $ver $arch $debian_netinstall_kernel $debian_netinstall_initrd
    done
  done
} # end of get_debian_netinstall

#
get_ubuntu_netinstall() {
  # output file format in /tftpboot/nbi_img/:
  # vmlinuz-netinstall-${dist}-${ver}-${arch)
  # initrd-netinstall-${dist}-${ver}-${i386}.img
  #
  # url ex:
  # http://free.nchc.org.tw/ubuntu//dists/edgy/main/installer-i386/current/images/netboot/ubuntu-installer/i386/
  # http://free.nchc.org.tw/ubuntu/dists/dapper/main/installer-i386/current/images/netboot/ubuntu-installer/i386/
  for ver in $ubuntu_netinstall_ver; do
    for arch in $ubuntu_netinstall_arch; do
      url=$url_site/$path_to_ubuntu/$ver/main/installer-$arch/current/images/netboot/ubuntu-installer/$arch
      get_and_put_img $url Ubuntu $ver $arch $ubuntu_netinstall_kernel $ubuntu_netinstall_initrd
    done
  done
} # end of get_ubuntu_netinstall

#
get_fedora_netinstall() {
  # Example output file format in /tftpboot/nbi_img/:
  # vmlinuz-netinstall-Fedora-6-i386, initrd-netinstall-Fedora-6-i386.img
  # vmlinuz-netinstall-Fedora-6-x86_64, initrd-netinstall-Fedora-6-x86_64.img
  # i.e.
  # vmlinuz-netinstall-${dist}-${ver}-${arch)
  # initrd-netinstall-${dist}-${ver}-${i386}.img
  #
  # url ex:
  # http://free.nchc.org.tw/fedora/linux/core/6/i386/os/images/pxeboot/
  # http://free.nchc.org.tw/fedora/linux/releases/7/Fedora/i386/os/images/pxeboot/
  for ver in $fedora_netinstall_ver; do
    for arch in $fedora_netinstall_arch; do
      case $ver in
        [1-6])
          url=$url_site/$path_to_fedora/core/$ver/$arch/os/images/pxeboot
          ;;
        *)
          # For 7 or later... who knows about the future
          url=$url_site/$path_to_fedora/releases/$ver/Fedora/$arch/os/images/pxeboot
          ;;
      esac
      get_and_put_img $url Fedora $ver $arch $fedora_netinstall_kernel $fedora_netinstall_initrd
    done
  done
} # end of get_fedora_netinstall

#
get_centos_netinstall() {
  # output file format in /tftpboot/nbi_img/:
  # vmlinuz-netinstall-${dist}-${ver}-${arch)
  # initrd-netinstall-${dist}-${ver}-${i386}.img
  #
  # url ex:
  # http://free.nchc.org.tw/centos/4.5/os/i386/images/pxeboot
  # http://free.nchc.org.tw/centos/5.0/os/x86_64/images/pxeboot
  for ver in $centos_netinstall_ver; do
    for arch in $centos_netinstall_arch; do
      url=$url_site/$path_to_centos/$ver/os/$arch/images/pxeboot
      get_and_put_img $url CentOS $ver $arch $centos_netinstall_kernel $centos_netinstall_initrd
    done
  done
} # end of get_centos_netinstall

#
get_redhat_netinstall() {
  # output file format in /tftpboot/nbi_img/:
  # vmlinuz-netinstall-${dist}-${ver}-${arch)
  # initrd-netinstall-${dist}-${ver}-${i386}.img
  #
  # url ex:
  # http://free.nchc.org.tw/redhat/linux/8.0/en/os/i386/images/pxeboot
  # http://free.nchc.org.tw/redhat/linux/9/en/os/i386/images/pxeboot
  for ver in $redhat_netinstall_ver; do
    for arch in $redhat_netinstall_arch; do
      url=$url_site/$path_to_redhat/$ver/en/os/$arch/images/pxeboot
      get_and_put_img $url RedHat $ver $arch $redhat_netinstall_kernel $redhat_netinstall_initrd
    done
  done
} # end of get_redhat_netinstall

#
get_mandriva_netinstall() {
  # output file format in /tftpboot/nbi_img/:
  # vmlinuz-netinstall-${dist}-${ver}-${arch)
  # initrd-netinstall-${dist}-${ver}-${i386}.img
  #
  # url ex:
  # http://free.nchc.org.tw/mandrake/official/2007.0/i586/isolinux/alt0/
  # http://free.nchc.org.tw/mandrake/official/2007.1/i586/isolinux/alt0/
  for ver in $mandriva_netinstall_ver; do
    for arch in $mandriva_netinstall_arch; do
      url=$url_site/$path_to_mandriva/$ver/$arch/isolinux/alt0
      get_and_put_img $url Mandriva $ver $arch $mandriva_netinstall_kernel $mandriva_netinstall_initrd
    done
  done
} # end of get_mandriva_netinstall

#
get_scientific_netinstall() {
  # output file format in /tftpboot/nbi_img/:
  # vmlinuz-netinstall-${dist}-${ver}-${arch)
  # initrd-netinstall-${dist}-${ver}-${i386}.img
  #
  # url ex:
  # http://free.nchc.org.tw/scientific/50/i386/images/pxeboot/
  # http://free.nchc.org.tw/scientific/50/x86_64/images/pxeboot/
  for ver in $scientific_netinstall_ver; do
    for arch in $scientific_netinstall_arch; do
      # For Scientific Linux, the path is used without dot (.): 5.0 -> 50
      ver_path="$(echo $ver | sed -e "s/\.//g")"
      url=$url_site/$path_to_scientific/$ver_path/$arch/images/pxeboot
      get_and_put_img $url Scientific $ver $arch $scientific_netinstall_kernel $scientific_netinstall_initrd
    done
  done
} # end of get_scientific_netinstall

#
get_opensuse_netinstall() {
  # vmlinuz-netinstall-${dist}-${ver}-${arch)
  # initrd-netinstall-${dist}-${ver}-${i386}.img
  #
  # url ex:
  # http://free.nchc.org.tw/opensuse/distribution/SL-10.1/inst-source/boot/i386/loader
  # http://free.nchc.org.tw/opensuse/distribution/10.2/repo/oss/boot/i386/loader
  for ver in $opensuse_netinstall_ver; do
    for arch in $opensuse_netinstall_arch; do
      case $ver in
        10.1)
          url=$url_site/$path_to_opensuse/SL-10.1/inst-source/boot/$arch/loader
          ;;
        *)
          # For 10.2 or later... who knows about the future
          url=$url_site/$path_to_opensuse/$ver/repo/oss/boot/$arch/loader
          ;;
      esac
      get_and_put_img $url openSUSE $ver $arch $opensuse_netinstall_kernel $opensuse_netinstall_initrd
    done
  done
} # end of get_opensuse_netinstall

#
install_GL_netinstall() {
  # download them and put in the system...
  [ "$GL_INST" = "all" ] && GL_INST="$supported_gnu_linux"
  echo "The following action will download a lot of network install packages. This might take a long time..."
  echo "If you want to assign the url, check 'netinstall image settings' in drbl.conf."
  for i in $GL_INST; do
    echo "Downloading $i netinstall packages... "
    eval get_${i}_netinstall
  done
}

#
uninstall_GL_netinstall() {
  [ "$GL_TO_BE_REMOVED" = "all" ] && GL_TO_BE_REMOVED="$supported_gnu_linux"
  for i in $GL_TO_BE_REMOVED; do
     find $pxecfg_pd/ -iname "*netinstall*$i*" -exec rm -fv {} \;
  done
}

#############
###  MAIN ###
#############
#
check_if_root

#
GL_INST=""
show_rerun_generate_pxe_menu="yes"
overwrite_img="no"

# Parse command-line options
while [ $# -gt 0 ]; do
  case "$1" in
    -l|--language)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              specified_lang="$1"
	      [ -z "$specified_lang" ] && USAGE && exit 1
              shift
            fi
            ;;
    -i|--install)
        shift; mode="install"
        if [ -z "$(echo $1 |grep ^-.)" ]; then
          # skip the -xx option, in case 
          GL_INST="$1"
          [ -z "$GL_INST" ] && USAGE && exit 1
	  shift
        fi
	;;
    -o|--overwrite)
        shift
        overwrite_img="yes" ;;
    -s|--skip-rerun-gen)
        shift
        show_rerun_generate_pxe_menu="no" ;;
    -u|--uninstall)
        shift; mode="uninstall"
        if [ -z "$(echo $1 |grep ^-.)" ]; then
          # skip the -xx option, in case 
          GL_TO_BE_REMOVED="$1"
          [ -z "$GL_TO_BE_REMOVED" ] && USAGE && exit 1
	  shift
        fi
        ;;
    -v|--verbose)
	verbose="on"
	verbose_opt="-v"
        shift ;;
    *)  USAGE && exit 1 ;;
  esac
done

# mode is essential
[ -z "$mode" ] && USAGE && exit 1

# Load the language file
#ask_and_load_lang_set $specified_lang

[ ! -d "$pxecfg_pd" ] && mkdir -p $pxecfg_pd

# run it
case "$mode" in
   install) install_GL_netinstall;;
   uninstall) uninstall_GL_netinstall;;
esac

#
if [ "$show_rerun_generate_pxe_menu" = "yes" ] ; then
  [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
  echo "///NOTE/// You should re-run generate-pxe-menu to update the PXE menu now."
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
fi
