#!/bin/bash
# Author: Steven Shiau <steven _at_ nchc org tw>
# License: GPL
# Description: This script will create a Debian live cd iso which is used as a template for clonezilla image with restoration function.

if [ ! -f "/opt/drbl/sbin/drbl-conf-functions" ]; then
  echo "Unable to find /opt/drbl/sbin/drbl-conf-functions! Program terminated!" 
  exit 1
fi
. /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

mirror_url="http://free.nchc.org.tw/debian"
mirror_security_url="http://free.nchc.org.tw/debian-security/"
# debian_type can be minimal (about 67 MB for Etch)/minimal-net (about 85 MB for Etch).
# We have to use standard, since if using minimal, it will ignore apt key from DRBL.
#debian_type="minimal"
debian_type="standard"
debian_dist="etch"
pkgs="drbl $PKG_FROM_DBN_WHICH_OCS_LIVE_NEED $PKG_FROM_DBN"
target_iso="drbl-server-live-stage1-`date +%Y%m%d`.iso"
real_target_iso="drbl-server-live-`date +%Y%m%d`.iso"
real_target_zip="drbl-server-live-`date +%Y%m%d`.zip"
ocs_live_script="$DRBL_SCRIPT_PATH/setup/files/ocs/live-chroot"
# The files in dir $ocs_live_script/ will be copied to the root (/) dir in dir chroot when make-live is run with --include-chroot. The file "ocs-srv-live-hook" is in $ocs_live_script
# The script will be run when chroot
hook_script="/drbl_hook"

# DRBL repository
LIVE_REPOSITORIES="drbl"
LIVE_REPOSITORY_drbl="http://free.nchc.org.tw/drbl-core"
# url to the repository key
LIVE_REPOSITORY_KEY_drbl="http://drbl.nchc.org.tw/GPG-KEY-DRBL"
# the name of the keyring
LIVE_REPOSITORY_KEYRING_drbl=""
# the name of your distribution
LIVE_REPOSITORY_DISTRIBUTION_drbl="drbl"
# sections
# LIVE_REPOSITORY_SECTIONS_drbl (stable, testing, unstable) will be assigned later
export LIVE_REPOSITORIES LIVE_REPOSITORY_drbl LIVE_REPOSITORY_KEY_drbl LIVE_REPOSITORY_KEYRING_drbl LIVE_REPOSITORY_DISTRIBUTION_drbl LIVE_REPOSITORY_SECTIONS_drbl

#
check_if_root
#
prog="$(basename $0)"

# functions
USAGE() {
    echo "Usage:"
    echo "To create a Debian live CD which is used a template for Clonezilla live:"
    echo "$prog [OPTION]"
    echo "OPTION:"
    language_help_prompt_by_idx_no
    echo "-b, --branch [s|stable|t|testing|u|unstable]  specifies the DRBL branch to be used in Live CD. Default is stable."
    echo "-k, --package FILE  Specifies FILE to be installed in Live CD."
    echo "-p, --package-list FILE  specifies an external package list file (such as xfce, gnome, kde...), one package for each line"
    echo "-r, --rm-tmp-iso    Remove the first stage temp iso file"
    echo "-u, --use-existing-tmp-iso  Use the existing first stage temp iso file"
    echo "-v, --verbose       Run make-live in verbose mode"
}

# default settings
extra_pkgs=""
pkg_list=""
pkg_list_opt=""
rm_tmp_iso="no"
use_existing_stage1_iso="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"
              shift
            fi
	    [ -z "$specified_lang" ] && USAGE && exit 1
            ;;
    -b|--branch)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              drbl_branch="$1"
              shift
            fi
	    [ -z "$drbl_branch" ] && USAGE && exit 1
            ;;
    -k|--package)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              extra_pkgs="$1"
              shift
            fi
	    [ -z "$extra_pkgs" ] && USAGE && exit 1
            ;;
    -p|--package-list)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              pkg_list="$pkg_list $1"
              shift
            fi
	    [ -z "$pkg_list" ] && USAGE && exit 1
            ;;
    -r|--rm-tmp-iso)
	    rm_tmp_iso="yes"
            shift ;;
    -u|--use-existing-tmp-iso)
            use_existing_stage1_iso="yes"
            shift ;;
    -v|--verbose)
	    verbose="on"
            shift ;;
    -*)     echo "${0}: ${1}: invalid option" >&2
            USAGE >& 2
            exit 2 ;;
    *)      break ;;
  esac
done

if [ "$use_existing_stage1_iso" = "no" ]; then
  # if we use existing stage 1 iso file, then we do not have to check if make-live exists. Otherwise we need make-live to create the stage 1 iso file
  if ! type make-live &>/dev/null; then
    [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
    echo "This script only works in Debian Etch or later!"
    echo "If you are running Debian Etch or later, use 'apt-get install live-package' to install the necessary packages, then run $0 again."
    [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
    exit 1
  fi
fi

# we need zip to create the release file when target_mode is release_file
if ! type zip &>/dev/null; then
  [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
  echo "Command zip not found!"
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
  echo "$msg_program_stop"
  exit 1
fi

ask_and_load_lang_set $specified_lang

[ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
echo "Creating a Debian live cd iso which is used for clonezilla image with restoration function. The created iso will be in $target_iso" 
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL

rm -rf debian-live/.stage/

# append the extra packages
[ -n "$extra_pkgs" ] && pkgs="$pkgs $extra_pkgs"
echo "The packages to be included in this live CD:"
echo "$msg_delimiter_star_line"
echo "$pkgs"
echo "$msg_delimiter_star_line"
if [ -n "$pkg_list" ]; then
  pkg_list_opt="$pkg_list_opt --package-list $pkg_list"
  echo "The packages list to be included in this live CD:"
  echo "$msg_delimiter_star_line"
  echo "$pkg_list"
  echo "$msg_delimiter_star_line"
fi

case "$drbl_branch" in
  t|testing)
     echo "Using DRBL testing branch..."
     LIVE_REPOSITORY_SECTIONS_drbl="stable testing"
     ;;
  u|unstable)
     echo "Using DRBL unstable branch..."
     LIVE_REPOSITORY_SECTIONS_drbl="stable testing unstable"
     ;;
  *)
     echo "Using DRBL stable branch..."
     LIVE_REPOSITORY_SECTIONS_drbl="stable"
     ;;
esac
echo "$msg_delimiter_star_line"

if [ "$verbose" = "on" ]; then
  pref="bash -x"
fi

if [ "$use_existing_stage1_iso" = "no" ]; then
  # add the script in /usr/share/make-live/hooks/minimal
  if ! grep -q "/ocs-srv-live-hook" /usr/share/make-live/hooks/$debian_type; then
   echo "/ocs-srv-live-hook" >> /usr/share/make-live/hooks/$debian_type
  fi
  $pref make-live --mirror $mirror_url --mirror-security $mirror_security_url --distribution $debian_dist --flavour $debian_type --without-generic-indices --packages "$pkgs" $pkg_list_opt --include-chroot "$ocs_live_script" --bootappend ip=frommedia
  # remove the line /ocs-srv-live-hook in /usr/share/make-live/hooks/minimal
  perl -i -ne "print unless /^\/ocs-srv-live-hook/ .. /.*$/" /usr/share/make-live/hooks/$debian_type
  mv -f debian-live/binary.iso $target_iso
else
  echo "Use existing temp iso file: $target_iso"
fi
# 
[ ! -e "$target_iso" ] && echo "$target_iso does NOT exit!" && exit 1

echo "$msg_delimiter_star_line"
echo "Creating DRBL server iso file..."
echo "$msg_delimiter_star_line"
# now we can insert the boot menu of isolinux
# create isolinux menu
target_iso_TMP="$(mktemp -d /tmp/ocs-iso.XXXXXX)"
trap "[ -d "$target_iso_TMP" ] && umount $target_iso_TMP &>/dev/null && rm -rf $target_iso_TMP" HUP INT QUIT TERM EXIT
ISOLNX_TMP="$(mktemp -d /tmp/isolnx.XXXXXX)"
mount -o loop $target_iso $target_iso_TMP

# isolinux should be rw, so we have to copy it, and exclude the one in iso image.
mkdir -p $ISOLNX_TMP/isolinux
rsync -a --exclude f*.txt --exclude boot.cat --exclude isolinux.txt --exclude isolinux.bin --exclude splash.rle $target_iso_TMP/isolinux $ISOLNX_TMP/
# we have to overwrite isolinux.bin since vesamenu.c32 should be same version with that.
etherboot_zlilo="$($query_pkglist_cmd drbl-etherboot | grep -E "eb-.*-etherboot-pci.zlilo$")"
cp -f $isolinux_file $pxelinux_simple_vesamenu $pxelinux_simple_menu $pxelinux_bg_img $pxelinux_chain_file $memtest86_file $ISOLNX_TMP/isolinux/
if [ -n "$etherboot_zlilo" ]; then
  # we have to force it name as etherboot.zdsk, since isolinux only uses the "plain" ISO 9660 filenames, i.e. it does not support Rock Ridge or Joliet filenames.
  # ref: http://syslinux.zytor.com/archives/2006-October/007440.html
  # "-" will be regards as "_" if you want to use "-" for isolinux.
  # In syslinux on vfat, etherboot.zlilo is too long, make it ever shorter as eb.zli
  cp -f $etherboot_zlilo $ISOLNX_TMP/isolinux/eb.zli
fi
# generate the menu
# Since here we will overwrite the "ip=frommedia" created by "--bootappend ip=frommedia" in make live, we have to append it again.
ocs-live-boot-menu -l 0 --title "DRBL server live" --boot-param "boot=casper ip=frommedia" -m $pxelinux_bg_img isolinux $ISOLNX_TMP/isolinux/

# create the iso file
mkisofs \
 -A "DRBL server live CD" \
 -V "DRBL-live" \
 -publisher "DRBL/Clonezilla http://drbl.sf.net http://clonezilla.sf.net" \
 -r -J -l \
 -b isolinux/isolinux.bin -c isolinux/boot.cat \
 -no-emul-boot -boot-load-size 4 -boot-info-table \
 -x $target_iso_TMP/isolinux \
 -x $target_iso_TMP/md5sum.txt \
 -graft-points $target_iso_TMP \
  /isolinux/=$ISOLNX_TMP/isolinux \
  /COPYING=$DRBL_SCRIPT_PATH/doc/COPYING \
 > $real_target_iso
RC_ISO=$?
if [ "$RC_ISO" -eq 0 ]; then
  [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS
  echo "The $real_target_iso is created successfully!"
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
else
  [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
  echo "The $real_target_iso is NOT created! Something went wrong!"
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
fi

# create temp dir for usb flash drive
echo "$msg_delimiter_star_line"
echo "Creating DRBL server zip file..."
echo "$msg_delimiter_star_line"
WD="$(pwd)"
USB_TMP="$(mktemp -d /tmp/usb-dev.XXXXXX)"
echo "Copying files to temp working directory... This might take some time..."
rsync -av --exclude isolinux --exclude md5sum.txt $target_iso_TMP/*  $USB_TMP/
cp -f $DRBL_SCRIPT_PATH/doc/COPYING $USB_TMP/
cp -f $pxelinux_simple_vesamenu $pxelinux_simple_menu $pxelinux_bg_img $pxelinux_chain_file $memtest86_file $USB_TMP/
[ -z "$etherboot_zlilo" ] && cp -f $etherboot_zlilo $USB_TMP/eb.zli
cp -f $target_iso_TMP/isolinux/{$kernel_file,$initrd_file} $USB_TMP/
ocs-live-boot-menu -l 0 --title "DRBL server live" --boot-param "boot=casper ip=frommedia" -m $pxelinux_bg_img syslinux $USB_TMP/
echo "Downloading syslinux.exe and Makeboot.exe..."
wget $wget_opt -P "$USB_TMP" $syslinux_exe_url
wget $wget_opt -P "$USB_TMP" $makeboot_exe_url
# just store it. since big files, like squash flie and opt_drbl.tgz are compressed, it's not necessary to compress it again.
(cd $USB_TMP; zip -0 -r $WD/$real_target_zip *)
echo "The created release file is $real_target_zip. You can extract all the files into your pendrive, and run makeboot.exe from pendrive in M$ windows."
[ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
echo "Warning: DO NOT RUN makeboot.exe from your local hard drive!! It is intended to be run from your USB device."
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL

# unmount all iso file
umount $target_iso_TMP &>/dev/null

# Clean the tmp working directory
echo "Cleaning tmp dirs..."
[ ! -z "$target_iso_TMP" ] && rm -rf $target_iso_TMP
[ ! -z "$ISOLNX_TMP" ] && rm -rf $ISOLNX_TMP
[ ! -z "$USB_TMP" ] && rm -rf $USB_TMP
# clean the tmp iso.
[ "$rm_tmp_iso" = "yes" -a -f "$target_iso" ] && rm -f $target_iso
# 
[ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
echo "$msg_burn_drbl_live_img_iso: $real_target_iso"
echo "$msg_burn_drbl_live_img_zip: $real_target_zip"
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
