#!/bin/sh
#
# 	$Source: /cvsroot/bootcd/bootcd/bootcddebootstrap.src,v $
#       $Id: bootcddebootstrap.src,v 1.33 2010-03-11 15:53:04 bs Exp $
#    author: Carsten Dinkelmann <din@foobar-cpa.de>
#            Bernd Schumacher <bernd.schumacher@hp.com>
#     start: 12.09.2007
#     topic: create a small debian cd and configured it for bootcd
#

# Read supported environment variables (before set -u)
http_proxy="$http_proxy"
IAHEAD="$IAHEAD"
set -u

# Version of debian package bootcd with this tools is included
# /usr/share/doc/bootcd-backup/examples/bootcddebootstrap
VERSION=##BOOTCD_VERSION## # sources are tagged in cvs with rev=debian_version_${VERSION}

# fixe language problem
export LANG=C
export LC_ALL=C

# use for temporary files
TMPDIR=/tmp/.debootstrap

# used as basis directory
WORKDIR=/var/spool/bootcd-img

# only for help, the download path
DOWNLOADPATH="http://packages.debian.org/stable/debootstrap/all/download"

# mirrors for debootstrap
BOOTSTRAPMIRRORS="http://ftp2.de.debian.org/debian/ http://ftp.se.debian.org/debian/ http://ftp.debian.org"

# build deboostrap for this distribution
#DISTRI="squeeze"
DISTRI="wheezy"

# needed tools
TOOLS="ar tar chroot"

KERNEL="linux-image-amd64"

# bootcd packages
BOOTCDPACKAGES_APT="bootcd/unstable"
BOOTCDPACKAGES_LOCAL="bootcd"

# needed packages
PACKAGES="lvm2 genisoimage fdutils file dosfstools realpath syslinux aufs-tools"

# usefull packages
#UPACKAGES="less psmisc net-tools ssh vim netbase xbase-clients star console-common console-data console-tools wget"
# star is not available
UPACKAGES="less psmisc net-tools ssh vim netbase xauth console-common console-data console-tools wget"

# logfile
ERRLOG="/var/log/bootcddebootstrap.log"

######################### nothing to configure behind this line ###############

SCRIPTNAME=$(basename $0)

[ "$IAHEAD" ] && IAHEAD="$IAHEAD/$SCRIPTNAME" || IAHEAD="$SCRIPTNAME"

### BOOTCD-RUN_LIB Placeholder ##############

# function: usage
# get: $1 -- error string
usage()
{
  [ "$1" ] && echo  >&2 "$1"

  echo ""
  echo  " $SCRIPTNAME creates a debian bootcd image in a chroot-enviroment."
  echo  " After that, you can backup your running system to a CD/DVD."
  echo  ""
  echo  " syntax: $SCRIPTNAME [-i] [-m <mirror>] [-d <directory>] <debootstrap path|directory>"
  echo  ""
  echo  "                 -i   -- do all things interactive"
  echo  "       -d <directory> -- create image in this directory (Space needed!)"
  echo  "                         default: \"$WORKDIR\""
  echo  "        --grub-legacy -- use old GRUB instead of new GRUB"
  echo  "          -m <mirror> -- debian mirror for debootstrap (e.g. http://ftp.de.debian.org/debian)"
  echo  "       -nu            -- no usefull packages (don't install network, lvm ... in bootcdimage)"
  echo  "   <debootstrap path> -- path to debootstrap debian package, use bootcd packages from"
  echo  "                         \"apt\" source server"
  echo  "   <debootstrap directory> -- directory with debootstrap and bootcd debian packages"
  echo  ""                         
  echo  " download debootstrap: \"$DOWNLOADPATH\" "
  echo  ""
  echo  " example: $SCRIPTNAME /tmp/debootstrap_0.3.3.2etch1_all.deb"
  echo  ""
 
  exit 0
}


# function: realpath -- gives the full path of file or dir
# get: $1 - file with path
realpath()
{
  [ $# -eq 1 ] && echo "$(cd $(dirname $1); /bin/pwd)/$(basename $1)"
}


# function: extract_debootstrab -- extract debootstrap
# get: $1 -- tmpdir
#      $2 -- path to debfile
extract_debootstrap()
{
  local tmpdir=$1
  local debfile=$2

  echo >&2 "extract debootstrap from debian package"

  (cd $tmpdir; ar -x $debfile data.tar.gz)

  tar -xz -C$tmpdir -f /$tmpdir/data.tar.gz

  echo
}

# function: config_apt -- configure apt (pinning) to get unstable/testing 
#                         packages for bootcd
# get: $1 -- workdir
config_apt()
{
  local workdir=$1

  echo >&2 "write sources.list"
  cat >$workdir/etc/apt/sources.list <<END
# stable
deb http://ftp.debian.org/debian $DISTRI main

# testing
deb http://ftp.debian.org/debian testing main

# unstable
deb http://ftp.debian.org/debian unstable main
END

  echo >&2 "write apt_preferences"
  cat >$workdir/etc/apt/preferences <<END
Package: *
Pin: release a=$DISTRI
Pin-Priority: 750

Package: *
Pin: release a=stable
Pin-Priority: 700

Package: *
Pin: release a=testing
Pin-Priority: 650

Package: *
Pin: release a=unstable
Pin-Priority: 600
END

echo >&2 "Configure Cache-Limit in apt.conf"
  cat >>$workdir/etc/apt/apt.conf <<END
APT::Cache-Limit "125000000";
END

  if [ "$http_proxy" ]; then
    echo >&2 "add http_proxy to apt.conf"
  cat >>$workdir/etc/apt/apt.conf <<END
Acquire::http::Proxy "$http_proxy";
END
  fi
}

# function: in_stdout_aptget -- generic in_stdout for apt
# get: $1 -- number
# ret: stdout string in STDOUT<number>
in_stdout_aptget()
{
  local mm=$1
  in_stdout $mm "^Reading package lists..."
  in_stdout $mm "^Reading state information..."
  in_stdout $mm "^After this operation, .* of additional disk space "
  in_stdout $mm "^Building dependency tree..."
  in_stdout $mm "^The following extra packages.*"
  in_stdout $mm "^Suggested packages:"
  in_stdout $mm "^Recommended packages:"
  in_stdout $mm "^The following NEW packages will be installed:"
  in_stdout $mm "^[[:digit:]]* upgraded, .*"
  in_stdout $mm "^Need to get .*"
  in_stdout $mm "^After unpacking .*"
  in_stdout $mm "^Get:"
  in_stdout $mm "^debconf: .*"
  in_stdout $mm "^Fetched .*"
  in_stdout $mm "^Unpacking .*"
  in_stdout $mm "^Selecting .*"
  in_stdout $mm "^(Reading database..."  
  in_stdout $mm "^[[:digit:]]* files and directories .*"  
  in_stdout $mm "^[dD]one.$"  
  in_stdout $mm "^Setting up .*"
  in_stdout $mm "^$"
  in_stdout $mm "^\.$"
  in_stdout $mm " is already the newest version.$"
  in_stdout $mm "^Adding .diversion of"
}


# function: config_kernel -- configure kernel install
# get: $1 -- workdir
config_kernel()
{
  local file=$1//etc/kernel-img.conf

  echo >&2 "write kernel-img.conf"

  for i in do_symlinks do_initrd; do
     [ ! "$(grep "[[:space:]]*${i}[[:space:]]*=" $file 2>/dev/null)" ] && echo "$i = Yes" >>$file
     sed -i -e "s|\([[:space:]]*${i}[[:space:]]*=[[:space:]]*\).*|\1Yes|" $file
  done

}

# get: $1 -- workdir
config_motd()
{
  local file=$1/etc/motd

  echo >&2 "--- configuring motd ---"
  echo "to change keyboard, use \"loadkeys /usr/share/keymaps/.....kmap.gz\"" >>$file
}


# function: get_debootstrapmirror
# globals: mirror (from cmdline), BOOTSTRAPMIRRORS
# set:      debootstrapmirror
get_debootstrapmirror()
{
  local i

  echo >&2 "check mirrors"
  # if mirror set by user, use it else try all with ping
  for i in $mirror $BOOTSTRAPMIRRORS; do
     echo -n >&2 " check mirror $i ... "
     if [ $(wget --timeout=10 -t 1 -O /dev/null $i >/dev/null 2>&1; echo $?) -eq 0 ]; then
       echo >&2 "ok"
       debootstrapmirror=$i;
       break;
     else
       echo >&2 "doesn't work!"
     fi
  done

  [ ! "$debootstrapmirror" ] && echo "No working mirror found!" || :
}

# function: install_packages
# get: $1 -- workdir
#      $2 -- useful packages switch (upack | no_upack)
#      $3 -- interactive (optional)
install_packages()
{
  local workdir=$1
  local kernel=$KERNEL
  # $grub is "grub" or "grub-legacy". (we need the old grub-legacy for RH6.1)
  local packages="$grub $PACKAGES"
  [ "$DEBOOTSTRAPDIR" ] && local bootcdpackages="$BOOTCDPACKAGES_LOCAL" || local bootcdpackages="$BOOTCDPACKAGES_APT"
  [ "$2" = "upack" ] && local usepkg="$UPACKAGES" || local usepkg=""
  local interact=""; [ $# -ge 3 ] && interact="$3"
  local TODO=""
  local mm=0
  local IAHEAD="$IAHEAD / install_packages"

  mm=$(($mm+1)); eval local IGNORE${mm}=\"\"; eval local STDOUT${mm}=\"\"
  in_stdout $mm ".*"
  TODO="$TODO \"config_apt $workdir\""

  mm=$(($mm+1)); eval local IGNORE${mm}=\"\"; eval local STDOUT${mm}=\"\"
  in_stdout $mm "^Get:.*"
  in_stdout $mm "^Hit .*"
  in_stdout $mm "^Ign .*"
  in_stdout $mm "^Fetched .*"
  in_stdout $mm "^Reading package lists....*"
  TODO="$TODO \"chroot $workdir apt-get update\""

  mm=$(($mm+1)); eval local IGNORE${mm}=\"\"; eval local STDOUT${mm}=\"\"
  in_stdout $mm "write kernel-img.conf"
  TODO="$TODO \"config_kernel $workdir\""

  mm=$(($mm+1)); eval local IGNORE${mm}=\"\"; eval local STDOUT${mm}=\"\"
  in_stdout_aptget $mm
  in_stdout $mm "^/sys/class/net/ is not available, persistent interface names not saved."
  in_stdout $mm "^  busybox initramfs-tools klibc-utils libklibc libvolume-id0$"
  in_stdout $mm "^  linux-image-2.6."
  in_stdout $mm "^  linux-image-2.6-486 linux-image-2.6.18-.-486 module-init-tools udev$"
  in_stdout $mm "^  linux-doc-"
  in_stdout $mm "^ Hmm. The package shipped with a symbolic link /lib/modules/2.6.18-.-486/source"
  in_stdout $mm "^ However, I can not read the target: No such file or directory"
  in_stdout $mm "^ Therefore, I am deleting /lib/modules/2.6.18-.-486/source"
  in_stdout $mm "^A chroot environment has been detected, udev not started."
  in_stdout $mm "^Running "
  in_stdout $mm "^Processing "
  in_stdout $mm "^Finding valid ramdisk creators."
  in_stdout $mm "^Using mkinitramfs-kpkg to build the ramdisk."
  in_stdout $mm "^linux-image.*is already the newest version."
  in_stdout $mm "^After this operation, "
  in_stdout $mm "^update-initramfs: deferring update"
  in_stdout $mm "^update-initramfs: Generating"
  in_stdout $mm "^run_command: calling: test$"
  in_stdout $mm "^udevadm_test:"
  in_stdout $mm "^parse_file: reading "
  in_stdout $mm "^udev_rules_new:"
  in_stdout $mm "^udev_device_new_from_syspath:"
  in_stdout $mm "^udev_device_read_db:"
  in_stdout $mm "^udev_device_update_db:"
  in_stdout $mm "^udev_rules_apply_to_event:"
  in_stdout $mm "^util_run_program:"
  in_stdout $mm "^update-alternatives: using"
  in_stdout $mm "^df: Warning: cannot read table of mounted file systems: No such file or directory$"
  in_stdout $mm "^Examining /etc/kernel/postinst.d"
  in_stdout $mm "^run-parts: executing /etc/kernel/postinst.d/"
  in_stdout $mm "^add_matching_files: unable to open '/dev/.udev/rules.d': No such file or directory$"
  in_stdout $mm "^Setting kernel variables"
  TODO="$TODO \"chroot $workdir sh -c \\\"DEBIAN_FRONTEND=noninteractive apt-get -qq -y -f install $kernel\\\"\""

  mm=$(($mm+1)); eval local IGNORE${mm}=\"\"; eval local STDOUT${mm}=\"\"
  in_stdout_aptget $mm
  in_stdout $mm "^  \(\<\(\
genisoimage\|libmagic1\|lvm-common\|wodim\|cdrkit-doc\|grub-doc\|mdadm\|dmsetup\|\
mtools\|logrotate\|dosfstools\|fdutils\|file\|genisoimage\|grub\|libmagic1\|\
lvm-common\|lvm2\|mkisofs\|realpath\|syslinux\|grub-common\|syslinux-common\|\
cdrkit-doc\|grub-legacy-doc\|multiboot-doc\|floppyd\
\)\>[[:space:]]*\)*$"
  in_stdout $mm "^Backing up any"
  in_stdout $mm "^  Found volume group"
  in_stdout $mm " logical volume(s) in volume group .* now active"
  in_stdout $mm "^df: Warning: cannot read table of mounted file systems: No such file or directory$"
  in_stdout $mm "^install-info: "
  in_stdout $mm "^update-initramfs: "
  in_stdout $mm "^Processing triggers for initramfs-tools "
  in_stdout $mm "^update-initramfs: Generating "
  in_stdout $mm "^Moving old data out of the way"
  in_stdout $mm "^Creating config file /etc/default/grub with new version"
  in_stdout $mm "^  No volume groups found"
  in_stdout $mm "^  Reading all physical volumes."
  in_stdout $mm "^  No volume groups found"
  in_stdout $mm "^Creating /etc/network/interfaces"
  in_stdout $mm "^Looking for keymap to install:"
  in_stdout $mm "^NONE$"
  in_stdout $mm "^Creating SSH2.*key"
  in_stdout $mm "^Processing /usr/share/vim/addons"
  TODO="$TODO \"chroot $workdir sh -c \\\"DEBIAN_FRONTEND=noninteractive apt-get -qq -y -f install $packages\\\"\""

  # use packages from configured directory
  if [ "$DEBOOTSTRAPDIR" ]; then
    local inst=""
    for i in $bootcdpackages; do
       mm=$(($mm+1)); eval local IGNORE${mm}=\"\"; eval local STDOUT${mm}=\"\"
       local file=$(ls $DEBOOTSTRAPDIR/${i}_*.deb |head -1)
       TODO="$TODO \"cp $file $workdir/tmp/\""
       [ "$inst" ] && inst="$inst /tmp/$(basename $file)" || inst="/tmp/$(basename $file)"
    done  
    mm=$(($mm+1)); eval local IGNORE${mm}=\"\"; eval local STDOUT${mm}=\"\"
    in_stdout $mm "^(Reading database ... .*"
    in_stdout $mm "^Selecting .*" 
    in_stdout $mm "^Unpacking .*"
    in_stdout $mm "^Setting up .*"
    in_stdout $mm "^update-initramfs: Generating.*"
    in_stdout $mm "^[[:digit:]]* files and directories .*"
    in_stdout $mm "^update-initramfs: deferring update"
    in_stdout $mm "^Processing triggers"
    in_stdout $mm "^df: Warning: cannot read table of mounted file systems: No such file or directory$"
    TODO="$TODO \"chroot $workdir sh -c \\\"dpkg -i $inst \\\"\""
  else 
    mm=$(($mm+1)); eval local IGNORE${mm}=\"\"; eval local STDOUT${mm}=\"\"
    in_stdout_aptget $mm
    in_stdout $mm ".*"
    TODO="$TODO \"chroot $workdir sh -c \\\"DEBIAN_FRONTEND=noninteractive apt-get -qq -y -f install $bootcdpackages\\\"\""
  fi

  if [ "$usepkg" ]; then
    mm=$(($mm+1)); eval local IGNORE${mm}=\"\"; eval local STDOUT${mm}=\"\"
    in_stdout_aptget $mm
    # The following extra packages will be installed:
    # Suggested packages:
    # Recommended packages:
    # The following NEW packages will be installed:
    in_stdout $mm "^  \(\<\(\
adduser\|defoma\|fontconfig-config\|ifupdown\|iputils-ping\|libconsole\|libdrm2\|\
libedit2\|libexpat1\|libfontconfig1\|libfreetype6\|libfs6\|libgl1-mesa-glx\|\
libgpmg1\|libice6\|libkrb53\|libnewt0.52\|libpng12-0\|libpopt0\|libsm6\|libssl0.9.8\|\
libwrap0\|libx11-6\|libx11-data\|libxau6\|libxaw7\|libxcursor1\|libxdmcp6\|libxext6\|\
libxfixes3\|libxft2\|libxi6\|libxkbfile1\|libxmu6\|libxmuu1\|libxpm4\|libxrandr2\|\
libxrender1\|libxss1\|libxt6\|libxtrap6\|libxtst6\|libxv1\|libxxf86dga1\|\
libxxf86vm1\|openbsd-inetd\|openssh-blacklist\|openssh-client\|openssh-server\|tcpd\|\
ttf-dejavu\|ucf\|unicode-data\|\
update-inetd\|vim-common\|vim-runtime\|whiptail\|x11-common\|\
kbd-compat\|defoma-doc\|psfontmgr\|x-ttcidfont-conf\|dfontmgr\|\
iproute\|dhcp3-client\|dhcp-client\|ppp\|libfreetype6-dev\|gpm\|krb5-doc\|krb5-user\|\
ssh-askpass\|rssh\|molly-guard\|ctags\|vim-doc\|vim-scripts\|mesa-utils\|\
libft-perl\|libfribidi0\|debconf-utils\|\
console-common\|console-data\|console-tools\|fontconfig-config\|\
ifupdown\|iputils-ping\|less\|libconsole\|libdrm2\|libedit2\|libexpat1\|\
libfontconfig1\|libfreetype6\|libfs6\|libgl1-mesa-glx\|libgpmg1\|libice6\|libkrb53\|\
libnewt0.52\|libpng12-0\|libpopt0\|libsm6\|libssl0.9.8\|libwrap0\|libx11-6\|\
libx11-data\|libxau6\|libxaw7\|libxcursor1\|libxdmcp6\|libxext6\|libxfixes3\|\
libxft2\|libxi6\|libxkbfile1\|libxmu6\|libxmuu1\|libxpm4\|libxrandr2\|libxrender1\|\
libxss1\|libxt6\|libxtrap6\|libxtst6\|libxv1\|libxxf86dga1\|libxxf86vm1\|net-tools\|\
netbase\|openbsd-inetd\|openssh-client\|openssh-server\|psmisc\|ssh\|star\|tcpd\|\
ttf-dejavu\|ucf\|update-inetd\|vim\|vim-common\|vim-runtime\|whiptail\|x11-common\|\
xbase-clients\|libfontenc1\|libkeyutils1\|libxdamage1\|libxinerama1\|libxxf86misc1\|\
openssh-blacklist-extra\|ttf-dejavu-core\|ttf-dejavu-extra\|x11-apps\|\
x11-session-utils\|x11-utils\|x11-xfs-utils\|x11-xkb-utils\|x11-xserver-utils\|\
xauth\|xinit\|libpam-ssh\|keychain\|libgpm2\|libxcb-xlib0\|libxcb1\
\)\>[[:space:]]*\)*$"
    # special from packages
    in_stdout $mm "^ifupdown.postinst: .*"
    in_stdout $mm "^Moving old data out of the way"
    in_stdout $mm "^Stopping internet superserver: .*"
    in_stdout $mm "Not starting internet superserver:"
    in_stdout $mm "^Creating SSH2 .* key; this may take some time ...$"
    in_stdout $mm "^Moving old data out of the way"
    in_stdout $mm "^Processing /usr/share/vim/addons/doc$"
    in_stdout $mm "^\.$"
    in_stdout $mm "^Restarting OpenBSD Secure Shell server:.*"
    in_stdout $mm "^Looking for keymap to install:$"
    in_stdout $mm "^NONE$"
    in_stdout $mm "^Setting console screen modes and fonts.$"
    in_stdout $mm "^Looking for keymap to install:$"
    in_stdout $mm "^update-alternatives: using"
    in_stdout $mm "^Setting kernel variables"
    in_stdout $mm "^df: Warning: cannot read table of mounted file systems: No such file or directory$"
    in_stdout $mm "^setterm: .TERM is not defined."
    in_stdout $mm "^Creating /etc/network/interfaces.$"
    in_stdout $mm "^Looking for keymap to install:$"
    in_stdout $mm "^NONE$"
    in_stdout $mm "^Setting console screen modes and fonts.$"
    in_stdout $mm "^setterm: cannot (un)set powersave mode: Invalid argument$"
    in_stdout $mm "^Setting up console-common (0.7.87) ...$"
    in_stdout $mm "^Looking for keymap to install:$"
    in_stdout $mm "^NONE$"
    in_stdout $mm "^Creating SSH2 RSA key; this may take some time ...$"
    in_stdout $mm "^Creating SSH2 DSA key; this may take some time ...$"
    in_stdout $mm "^Creating SSH2 ECDSA key; this may take some time ...$"
    in_stdout $mm "^Processing /usr/share/vim/addons/doc$"
    TODO="$TODO \"chroot $workdir sh -c \\\"DEBIAN_FRONTEND=noninteractive apt-get -qq -y -f install $usepkg\\\"\""
  fi

  mm=$(($mm+1)); eval local IGNORE${mm}=\"\"; eval local STDOUT${mm}=\"\"
  in_stdout $mm "^--- configuring motd ---$"
  TODO="$TODO \"config_motd $workdir\""

  [ "$interact" ] && interact="" || interact="-y"
  eval "interactive -h \"=== \$IAHEAD ===\" $interact -r $TODO"
}

# function: do_clean -- clean all things
# get: $1 -- tmpdir
do_clean()
{
  local tmpdir=$1

  rm -rf $tmpdir

  return 0
}


#################### the real things #########################################


TODO=""
workdir=$WORKDIR
upack="upack"
interact=""
DEBOOTSTRAP=""
DEBOOTSTRAPDIR="" 
debootstrapmirror=""
mirror=""
grub="grub"
mm=0
while [ $# -gt 0 ]; do
  case "$1" in
    "--grub-legacy")
      grub="grub-legacy"
      ;;
    "-d")
      shift
      workdir="$1"
      ;;
    "-nu")
      upack="no_upack"
      ;;
   "-h")
     shift
     IAHEAD="$1 / $IAHEAD"
     ;;
   "-m")
     shift
     mirror="$1"
     ;;
   "-i")
     interact="$1"
     ;;
    --help|-h) 
      usage
      ;;
    *) 
      if [ ! "$DEBOOTSTRAP" -a ! "$DEBOOTSTRAPDIR" ]; then
        [ -d "$1" ] && DEBOOTSTRAPDIR=$1 || DEBOOTSTRAP=$1
      else
        usage "parameter \"$1\" unknown!"
      fi
      ;;
  esac
  shift
done

[ ! "$DEBOOTSTRAP" -a ! "$DEBOOTSTRAPDIR" ] && usage "Mandatory parameter \"debootstrap path|directory\" not found!"

# if DEBOOTSTRAPDIR is set, the user has set DIR 
#    (DEBOOTSTRAP is automatically computed!)
if [ "$DEBOOTSTRAPDIR" ]; then
  DEBOOTSTRAPDIR="$(realpath $DEBOOTSTRAPDIR)"
  # check for debootstrap and bootcd packages 
  DEBOOTSTRAP="$(ls $DEBOOTSTRAPDIR/debootstrap_*.deb |head -1)"
  echo "use debootstrap package: $DEBOOTSTRAP"
  # search local bootcd packages
  for i in $BOOTCDPACKAGES_LOCAL; do
     [ ! -f "$(ls $DEBOOTSTRAPDIR/${i}_*.deb |head -1)" ] && err "debian package of $i not found in \"$DEBOOTSTRAPDIR\"!"
  done
fi

DEBOOTSTRAP="$(realpath $DEBOOTSTRAP)"
[ ! -f "$DEBOOTSTRAP" ] && err "debootstrap file \"$DEBOOTSTRAP\" not found!"


mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
in_stdout $mm "^[[:space:]]*check for \"[^[:space:]]*\" ...ok$"
TODO="$TODO \"check_tools $TOOLS\""

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
in_stdout $mm "Directory.*"
TODO="$TODO \"do_dir $workdir 700\""

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
in_stdout $mm "Directory.*"
TODO="$TODO \"do_dir $TMPDIR 700\""

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
in_stdout $mm "check mirror"
in_stdout $mm "^--"
in_stdout $mm "=> ./dev/null."
in_stdout $mm "^Resolving"
in_stdout $mm "^Connecting"
in_stdout $mm "^Giving up."
in_stdout $mm "^doesn't work"
in_stdout $mm "^$"
in_stdout $mm "^HTTP request sent"
in_stdout $mm "^Length:"
in_stdout $mm "^[[:space:]]*0K .."
in_stdout $mm "/dev/null. saved"
in_stdout $mm "^ok$"
in_stdout $mm "^Proxy request sent"
TODO="$TODO \"get_debootstrapmirror\""

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
in_stdout $mm "^extract debootstrap from debian package$"
TODO="$TODO \"extract_debootstrap $TMPDIR $DEBOOTSTRAP\""

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
in_stdout $mm "^I: .*"
in_stdout $mm "^W: Failure .* This will be re-atempted"
TODO="$TODO \"DEBOOTSTRAP_DIR=$TMPDIR/usr/share/debootstrap $TMPDIR/usr/sbin/debootstrap --no-check-gpg --arch i386 --variant=buildd $DISTRI $workdir \\\$debootstrapmirror\""

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
in_norun $mm # do not start functions that itself use interactive with run
TODO="$TODO \"prepare_chroot $workdir <-i>\"" 

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
in_norun $mm # do not start functions that itself use interactive with run
TODO="$TODO \"[ -f $workdir/selinux/enforce ] && echo 0 > $workdir/selinux/enforce\"" 

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
in_norun $mm # do not start functions that itself use interactive with run
TODO="$TODO \"install_packages $workdir $upack <-i>\"" 

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
TODO="$TODO \"do_clean $TMPDIR\""

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
in_norun $mm # do not start functions that itself use interactive with run
TODO="$TODO \"unprepare_chroot $workdir <-i>\"" 

[ "$interact" ] && interact="" || interact="-y"
eval "interactive -h \"=== \\\$IAHEAD ===\" $interact -r -e $TODO"
