#!/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.
# This script works with live helper 1.0~a42-2 (Patched by DRBL team)

#
set -e

#
DRBL_SCRIPT_PATH="${DRBL_SCRIPT_PATH:-/opt/drbl/}"
. $DRBL_SCRIPT_PATH/sbin/drbl-conf-functions
. $DRBL_SCRIPT_PATH/conf/drbl-ocs.conf
. $DRBL_SCRIPT_PATH/sbin/ocs-functions

# debian_mirror_url_def, debian_mirror_security_url_def, DRBL_REPOSITORY_URL_def and DRBL_GPG_KEY_URL are loaded from drbl-ocs.conf

# debian_type can be minimal (about 67 MB for Etch)/minimal-net (about 85 MB for Etch).
debian_type="minimal"
#debian_type="standard"
DEBIAN_DIST_DEF="lenny"
pkgs="$PKG_FROM_DBN_WHICH_OCS_LIVE_NEED drbl $PKG_FROM_DRBL_FOR_CLONEZILLA_LIVE usplash usplash-theme-clonezilla"
categories_default="main"
cpu_flavor_default="486"
bootstrap_default="cdebootstrap"

# The files in dir $ocs_live_script_dir/ will be copied to the dir /live-hook-dir in dir chroot. The file "ocs-live-hook" is in $ocs_live_script_dir
# We put some files in dir ocs_minimal_hook/ to do some jobs, like clean unnecessary files, set locales...
ocs_live_script_dir="$DRBL_SCRIPT_PATH/setup/files/ocs/live-hook"
# The script inside $ocs_live_script_dir/ will be run when chroot. There are many files in $ocs_live_script_dir/, we will just run one here.
run_hook_script="ocs-live-hook"

#
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:"
    echo "-a, --packages PKG     Specify to add PKG, e.g. firmware-bnx2"
    echo "-b, --branch [s|stable|t|testing|u|unstable]  Specify the DRBL branch to be used in Live CD. Default is stable."
    echo "-bt, --bootstrap BOOTSTRAP  Specify the bootsrap type as BOOTSTRAP (cdebootstrap or debootstrap). If not specified, $bootstrap_default will be used."
    echo "-c, --categories CAT   Sepcify the category, e.g. 'main', 'main non-free', default is \'$categories_default\' if not specified."
    echo "-d, --debian-dist [stable|testing|unstable|lenny|squeeze|sid...]  Assign Debian dist, the default is $DEBIAN_DIST_DEF if not assigned."
    echo "-f, --arch-flavor ARCH  Assign the CPU architecture flavor as ARCH, e.g. 486 or 686. If it's not assigned, $cpu_flavor will be used."
    echo "-g, --drbl-repo-url URL  Assign the DRBL repository URL instead of default one $DRBL_REPOSITORY_URL_def."
    echo "-i, --assign-version-no NO  Assign the version no as NO instead of date."
    echo "-k, --live-kernel-pkg KERNEL_VER Assign kernel version as KERNEL_VER (KERNEL VER package must exist in repository. Ex. if KERNEL_VER is 2.6.20-1-486, then linux-image-2.6.20-1-486, squashfs-modules-2.6.20-1-486, and unionfs-modules-2.6.20-1-486 will be used."
    echo "-l, --drbl-live-branch [s|stable|t|testing|u|unstable|e|experimental]  specifies the DRBL live branch to be used in Live CD. Default is stable."
    echo "-p, --use-backports Include backports in the repository."
    echo "-m, --mirror-url URL  Assign the Debian repository URL instead of default one $debian_mirror_url_def. "
    echo "-s, --mirror-security-url URL  Assign the Debian security repository URL instead of default one $debian_mirror_security_url_def."
    echo "-v, --verbose   Run live helper in verbose mode"
    echo "Ex: $0 -l experimental -b unstable -k 2.6.24-etchnhalf.1"
}
#
turn_on_etch_backports() {
  # Backports
  # We use etchbpo instead of bpo to avoid being overwritten by the one "bpo" (it's for sarge-backports) in /etc/make-live.conf.
  export LIVE_REPOSITORIES="$LIVE_REPOSITORIES etchbpo"
  export LIVE_REPOSITORY_etchbpo="http://www.backports.org/debian/"
  export LIVE_REPOSITORY_KEY_etchbpo="http://backports.org/debian/archive.key"
  export LIVE_REPOSITORY_KEYRING_etchbpo=""
  export LIVE_REPOSITORY_DISTRIBUTION_etchbpo="etch-backports"
  export LIVE_REPOSITORY_SECTIONS_etchbpo="main contrib non-free"
}

# Parse command-line options
while [ $# -gt 0 ]; do
  case "$1" in
    -a|--packages)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              extra_pkgs="$1"
              shift
            fi
	    [ -z "$extra_pkgs" ] && 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
            ;;
    -bt|--bootstrap)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              bootstrap="$1"
              shift
            fi
	    [ -z "$bootstrap" ] && USAGE && exit 1
            ;;
    -c|--categories)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              categories="$1"
              shift
            fi
	    [ -z "$categories" ] && USAGE && exit 1
            ;;
    -d|--debian-dist)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              debian_dist="$1"
              shift
            fi
	    [ -z "$debian_dist" ] && USAGE && exit 1
            ;;
    -i|--assign-version-no)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              version_no="$1"
              shift
            fi
	    [ -z "$version_no" ] && USAGE && exit 1
            ;;
    -k|--live-kernel)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              live_kernel_ver="$1"
              shift
            fi
	    [ -z "$live_kernel_ver" ] && USAGE && exit 1
            ;;
    -l|--drbl-live-branch)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              drbl_live_branch="$1"
              shift
            fi
	    [ -z "$drbl_live_branch" ] && USAGE && exit 1
            ;;
    -p|--use-backports)
	    use_backports="yes"
            shift ;;
    -f|--arch-flavor)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              cpu_flavor="$1"
              shift
            fi
	    [ -z "$cpu_flavor" ] && USAGE && exit 1
            ;;
    -g|--drbl-repo-url)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              DRBL_REPOSITORY_URL="$1"
              shift
            fi
	    [ -z "$DRBL_REPOSITORY_URL" ] && USAGE && exit 1
            ;;
    -m|--mirror-url)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              mirror_url="$1"
              shift
            fi
	    [ -z "$mirror_url" ] && USAGE && exit 1
            ;;
    -s|--mirror-security-url)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              mirror_security_url="$1"
              shift
            fi
	    [ -z "$mirror_security_url" ] && USAGE && exit 1
            ;;
    -v|--verbose)
	    verbose="on"
            shift ;;
    -*)     echo "${0}: ${1}: invalid option" >&2
            USAGE >& 2
            exit 2 ;;
    *)      break ;;
  esac
done

if ! type lh &>/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-helper' to install the live-helper (version $lh_ver_required or later), then run $0 again."
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
  exit 1
fi

create_live_required_debian_based_prompt

rm -rf debian-live/.stage/

# Apply default settings if not assigned
[ -z "$debian_dist" ] && debian_dist="$DEBIAN_DIST_DEF"
[ -z "$categories" ] && categories="$categories_default"
[ -z "$DRBL_REPOSITORY_URL" ] && DRBL_REPOSITORY_URL="$DRBL_REPOSITORY_URL_def"
[ -z "$mirror_url" ] && mirror_url="$debian_mirror_url_def"
[ -z "$mirror_security_url" ] && mirror_security_url="$debian_mirror_security_url_def"
[ -z "$cpu_flavor" ] && cpu_flavor="$cpu_flavor_default"
[ -z "$bootstrap" ] && bootstrap=$bootstrap_default

# Append the extra packages
[ -n "$extra_pkgs" ] && pkgs="$pkgs $extra_pkgs"

# If version_no is not assigned, use date (Ex. 20070409)
[ -z "$version_no" ] && version_no="$(date +%Y%m%d)"
target_iso="debian-live-for-ocs-${version_no}.iso"

[ "$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
#
echo "Using Debian repository from: $mirror_url"
echo "Using Debian security repository from: $mirror_security_url"
echo "Using DRBL repository from: $DRBL_REPOSITORY_URL"

#
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
case "$drbl_live_branch" in
  t|testing)
     echo "Using DRBL Live testing branch..."
     LIVE_REPOSITORY_SECTIONS_drbl="$LIVE_REPOSITORY_SECTIONS_drbl live-stable live-testing"
     ;;
  u|unstable)
     echo "Using DRBL Live unstable branch..."
     LIVE_REPOSITORY_SECTIONS_drbl="$LIVE_REPOSITORY_SECTIONS_drbl live-stable live-testing live-unstable"
     ;;
  e|experimental)
     echo "Using DRBL Live experimental branch..."
     LIVE_REPOSITORY_SECTIONS_drbl="$LIVE_REPOSITORY_SECTIONS_drbl live-stable live-testing live-unstable live-experimental"
     ;;
  *)
     echo "Using DRBL live stable branch..."
     LIVE_REPOSITORY_SECTIONS_drbl="$LIVE_REPOSITORY_SECTIONS_drbl live-stable"
     ;;
esac

#
[ "$use_backports" = "yes" ] && turn_on_etch_backports

if [ "$debian_dist" = "squeeze" -o "$debian_dist" = "sid" ]; then
  # From around Oct/2009, the dummy package name "grub" is actually grub-pc, therefore we force to use grub-legacy and assume that if grub2 boot loader is used in the restored GNU/Linux, grub2 is available in the restored GNU/Linux so therefore we can use chroot to run it.
  pkgs="$(LC_ALL=C echo $pkgs | sed -r -e "s/grub[[:space:]]+/grub-legacy /")"
  # Since with squeeze or sid, we can use uvesafb to replace vesafb, we need v86d. Check https://bugs.launchpad.net/ubuntu/+source/v86d/+bug/189621 for more details.
  pkgs="$pkgs v86d"
fi

if [ "$verbose" = "on" ]; then
  pref="bash -x"
  export CDEBOOTSTRAP_OPTIONS="$CDEBOOTSTRAP_OPTIONS -v --debug"
fi

if [ -d "debian-live" ]; then
  echo "Found dir debian-live, clean stale debian-live files..."
  chroot debian-live/chroot umount /dev/pts &>/dev/null || true
  chroot debian-live/chroot umount /proc &>/dev/null || true
  chroot debian-live/chroot umount /sys &>/dev/null || true
  (
    cd debian-live/
    lh clean
  )
  rm -rf debian-live
fi

mkdir debian-live
(
cd debian-live

$pref lh config --archive-areas "$categories"
$pref lh config --mirror-binary $mirror_url --mirror-binary-security $mirror_security_url 
$pref lh config --mirror-bootstrap $mirror_url
$pref lh config --mirror-chroot $mirror_url --mirror-chroot-security $mirror_security_url
$pref lh config --bootstrap-flavour $debian_type --packages "$pkgs" --apt apt --apt-recommends false --binary-indices false --bootstrap $bootstrap --tasksel none
$pref lh config --volatile false
$pref lh config --initramfs live-initramfs
$pref lh config --username user --bootappend username=user
# Enable cache-indices, by doing this, "apt-get upgrade" won't be run in lh chroot_sources after hook since we might assign older package version when building.
$pref lh config --cache-indices true

# This decide_live_kernel_related_pkgs_from_debian function will output "kernel_related_pkgs" and "export MKSQUASHFS_OPTIONS"
decide_live_kernel_related_pkgs_from_debian
$pref lh config --distribution $debian_dist --linux-packages "$kernel_related_pkgs"

# We force to use the specific CPU kernel.
$pref lh config --linux-flavours $cpu_flavor

# No memtest from debian, we will use the one from drbl since it's newer.
$pref lh config --memtest none

# Put files to be included
mkdir -p config/chroot_local-includes/live-hook-dir
for i in $ocs_live_script_dir; do
  cp -pr $i/* config/chroot_local-includes/live-hook-dir/
done
cp $DRBL_SCRIPT_PATH/conf/drbl*.conf config/chroot_local-includes/live-hook-dir/

# Put hook file to be run
mkdir -p config/chroot_local-hooks
cp $ocs_live_script_dir/$run_hook_script config/chroot_local-hooks/

# prepare drbl source list
cat << AddDRBLRepository > config/chroot_sources/drbl.chroot
deb $DRBL_REPOSITORY_URL drbl $LIVE_REPOSITORY_SECTIONS_drbl
AddDRBLRepository

# prepare drbl key
LC_ALL=C wget -O config/chroot_sources/drbl.chroot.gpg $DRBL_GPG_KEY_URL

$pref lh build
)
mv -f debian-live/binary.iso $target_iso
