#!/bin/bash
#
# Module: install-system
# 
# **** License ****
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# 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.
#
# This code was originally developed by Vyatta, Inc.
# Portions created by Vyatta are Copyright (C) 2006, 2007 Vyatta, Inc.
# All Rights Reserved.
# 
# Author: Robert Bays
# Date: 2006
# Description:
# 
# **** End License ****
#
# Vyatta system installer script.
#
#
# If you set VYATTA_AUTO_INSTALL I will try to do an automated install for you

if [ -e /etc/default/vyatta ] ; then
    . /etc/default/vyatta
fi
: ${vyatta_prefix:=/opt/vyatta}
: ${vyatta_exec_prefix:=$vyatta_prefix}
: ${vyatta_bindir:=${vyatta_exec_prefix}/bin}
: ${vyatta_sbindir:=${vyatta_exec_prefix}/sbin}
: ${vyatta_sysconfdir:=${vyatta_prefix}/etc}

ofrconfdir=${vyatta_sysconfdir}/config
fdconfdir=/media/floppy/config
rootfsdir=/mnt/rootfs

# install log file name
INSTALL_LOG="install.log"
# root partition minimum size in MB
ROOT_MIN="450"
# the base install drive e.g. sda
if [ -n "$INSTALL_DRIVE" ]; then
  INSTALL_DRIVE=""
fi
# the install partition e.g. sda1
if [ -n "$ROOT_PARTITION" ]; then
  ROOT_PARTITION=""
fi
# the config partition e.g. sda2
if [ -n "$CONFIG_PARTITION" ]; then
  CONFIG_PARTITION=""
fi
# the size of the root partition
if [ -n "$ROOT_PARTITION_SIZE" ]; then
  ROOT_PARTITION_SIZE=""
fi
# global holding variable used in the select_partition sub
PARTITION=''

# Process ID of this script for the lame marketing spinner
SPID=$$

# Path to standalone root password reset script
PWRESET=/opt/vyatta/sbin/standalone_root_pw_reset

# trap signals so we can kill runaway progress indicators
trap 'progress_indicator stop; exit 1' 1
trap 'progress_indicator stop; exit 1' 2

# turn off any mounted swap partitions
turnoffswap () {
  if [ -f "/proc/swaps" ]; then
    myresponse=$(cat /proc/swaps)
    if [ -n "$myresponse" ]; then
      echo "turning off swaps..." >> $INSTALL_LOG
      swapoff -a
    fi
  fi
}

# Validates a user response.  Returns the response if valid.
# Returns the default is the user just hits enter.  
# Returns nothing if not valid.  Default parameter is $1.
# Options are in $2.  If options are defined return must be a member
# of the enum. 
get_response () {
  ldefault=$(echo "$1" | tr [:upper:] [:lower:])
  loptions=$(echo "$2" | tr [:upper:] [:lower:])

  # get the response from the user
  read myresponse
  myresponse=$(echo "$myresponse" | awk '{ printf (tolower($0)) }')

  # Check to see if the user accepts the default
  if [ -z "$myresponse" ]; then
    echo -n $ldefault
  # if we are passing in options to check, make sure response is a valid option
  elif [ -n "$loptions" ]; then
    for token in $loptions
      do
        if [ "$token" == "$myresponse" ]; then
          echo -n "$myresponse"
          return 0
        fi
      done
    return 1
  else
    echo -n "$myresponse"
  fi

  return 0
}

# Return the size of the drive in MB
get_drive_size () {
  ldrive=$1

  # Make sure you can print disk info using parted
  parted /dev/$ldrive p >/dev/null 2>&1

  # If unable to read disk, it's likely it needs a disklabel
  if [  "$?" != "0" ]; then
    echo "Creating a new disklabel on $ldrive" >> $INSTALL_LOG
    echo "parted /dev/$ldrive mklabel msdos" >> $INSTALL_LOG
    output=$(parted /dev/$ldrive mklabel msdos)

    # Get the drive size from parted
    lsize=$(parted /dev/$ldrive p | grep "^Disk" | awk '{ print $3 }')

    if [ $(echo $lsize | grep error) ]; then
      echo "Unable to read disk label.  Exiting."
      exit 1
    fi
  fi

  # Get the drive size from parted
  lsize=$(parted /dev/$ldrive p | grep "^Disk" | awk '{ print $3 }')
  # Get the reported units (mB, GB, kB)
  lmodifier=$(echo $lsize | sed 's/[0-9\.]//g')
  # remove the modifier
  lsize=$(echo $lsize | sed 's/[a-z,A-Z]//g')
  # Remove any fractions
  lsize=$(echo $lsize | cut -f1 -d'.')
  # Translate our size into mB if not there already
  if [ $lmodifier = "GB" ]; then 
    lsize=$(($lsize * 1000))
  elif [ $lmodifier = "kB" ]; then 
    lsize=$(($lsize / 1000))
  fi

  echo $lsize
}

# Probe hardrives not shown in /proc/partitions by default
probe_drives () {
  # find IDE drives.  Not all drives show up in /proc/partitions for
  # some reason.
  # TODO: not sure we have to do this for anything but compact flash
  # when we test on other platforms, we will find out and modify this section
  # as appropriate
  drive=$(find /proc/ide/ide* -name "hd*" 2>/dev/null | /usr/bin/awk -F"/" '{ print $5 }')

  # now exclude all drives but disks
  for drive in $drive
  do
    media=$(cat /proc/ide/$drive/media)
    if [ "$media" = "disk" ]; then
     output=$(mount | grep $drive)
      if [ -z "$output" ]; then
        output=$(parted /dev/$DRIVE p)
      fi
    fi
  done
}

# Takes an argument to display text before choice
# Sets INSTALL_DRIVE.  Note that select_drive should be wrapped 
# in the verification loop, not the included get_response.
select_drive () {
  # list the drives in /proc/partitions.  Remove partitions and empty lines.
  drives=$(cat /proc/partitions | awk '{ if ($4!="name") { print $4 } }' | egrep -v "[0-9]$" | egrep -v "^$")

  # take the first drive as the default
  INSTALL_DRIVE=$(echo $drives | /usr/bin/awk '{ print $1 }')

  # Add the drive sizes to the display to help the user decide
  display=''
  for drive in $drives
  do
    size=$(get_drive_size $drive)
    display="$display $drive\t$size"MB"\n"
  done

  # Display the drives and ask the user which one to install to
  echo -e "$display"
  echo
  echo -n "$1 [$INSTALL_DRIVE]:"

  INSTALL_DRIVE=$(get_response "$INSTALL_DRIVE" "$drives")
  echo

  # Assume no dma if the disk is smaller than 10G (such as a CF drive)
  size=$(get_drive_size $INSTALL_DRIVE)
  if [ $size -lt 11000 ]
  then
     ISCF="ide=nodma"
  fi
}

# Allow the user to select a partition to work with
# sets the global PARTITION
# $1 is the text to display before prompt
select_partition () {
  minsize=$1
  text=$2

  echo -n "Looking for appropriate partitions:  "
  progress_indicator start

  # initialize out global var.  using globals in this way is bad form.  I know.
  PARTITION=''

  # list only the partitions in /proc/partitions.
  parts=$(cat /proc/partitions | awk '{ if ($4!="name") { print $4 " "} }' | egrep "[0-9]" | egrep -v "loop" | tr -d '\n')

  # Get the partition sizes for display
  # only show linux partitions that have sizes, i.e. remove loops
  display=''
  for part in $parts
  do
    rootdev=$(echo $part | sed 's/[0-9]//g')
    parttype=$(fdisk -l /dev/$rootdev | grep $part | grep Linux)
    if [ -n "$parttype" ]; then
      lsize=$(get_drive_size $part)
      if [ "$lsize" -a $lsize -ge $minsize ]; then
        display="$display $part\t\t$lsize"MB"\n"
        myparts="$myparts $part"
      fi
    fi
  done

  progress_indicator stop
  echo "OK"

  if [ -n "$myparts" ]; then
    lpartition=''
    while [ -z "$lpartition" ]
    do
      # take the first partition as the default
      lpartition=$(echo $myparts | /usr/bin/awk '{ print $1 }')

      echo "I found the following partitions suitable for the Vyatta image:"
      echo -e "Partition\tSize"
      echo -e "$display"
      echo
      echo -n "$text [$lpartition]: "

      lpartition=$(get_response "$lpartition" "$myparts")
      echo
    done
  else
    echo "No suitable partition sizes found.  Exiting..."  | tee $INSTALL_LOG
    exit 1
  fi
  PARTITION=$lpartition
}

## check_config_partition
# look to see if this partition contains a config file
# and back it up
check_config_partition() {
  lpart=$1

  # Look to see if this is a config partition
  mkdir -p /mnt/tmp
  output=$(mount /dev/$lpart /mnt/tmp 2>&1)
  if [ $? != 0 ]; then
    echo -e "Cannot mount /dev/$lpart"."\nPlease see $INSTALL_LOG for more details.\nExiting.."
    echo -e "Cannot mount /dev/$lpart"."\nmount /dev/$ldrive$part /mnt/tmp\nExiting..." >> $INSTALL_LOG
    echo "$output" >> $INSTALL_LOG
    exit 1
  fi

  # Look to see if there is a config partition there
  if [ -f /mnt/tmp/opt/vyatta/etc/config/.vyatta_config ] || [ -f /mnt/tmp/.vyatta_config ]; then
    response=''
    while [ -z "$response" ]
    do
      echo "/dev/$lpart has an old configuration directory!"
      echo -ne "Would you like me to save the data on it\nbefore I delete it? (Yes/No) [Yes]: "
      response=$(get_response "Yes" "Yes No Y N")
      if [ "$response" == "yes" ] || [ "$response" == "y" ]; then
        mkdir -p /mnt/config
        if [ -d /mnt/tmp/opt/vyatta/etc/config ]; then
          output=$(cp -pR /mnt/tmp/opt/vyatta/etc/config/* /mnt/config)
        else
          output=$(cp -pR /mnt/tmp/* /mnt/config)
        fi
        if [ -n "$output" ]; then
          echo -e "Warning: error in copying the old config partition.\nSee $INSTALL_LOG for more details."
          echo -e "Warning: error in copying the old config partition.\ncp -pR /mnt/tmp/* /mnt/config\n$output\n" >> $INSTALL_LOG
        fi
      fi
    done
  fi
  umount /mnt/tmp
}

# Delete all existing partitions for an automated install
# $1 is the drive to delete partitions from
delete_partitions () {
  ldrive=$1

  # get the partitions on the drive
  partitions=$(cat /proc/partitions | grep $ldrive[0-9] | awk '{ print $4 }' | sed 's/[a-z]//g')

  # now for each part, blow it away
  for part in $partitions
  do
    # Look to see if this is a config partition
    check_config_partition "$ldrive$part"

    echo "Removing partition $part on /dev/$ldrive" >> $INSTALL_LOG
    output=$(parted /dev/$ldrive rm $part)
    status=$?
    if [ "$status" != 0 ]; then
      echo -e "Warning: cannot delete partition $part on $ldrive.\nPlease see $INSTALL_LOG for more details."
      echo -e "Warning: cannot delete partition $part on $ldrive.\nparted /dev/$ldrive rm $part\n$output" >> $INSTALL_LOG
    fi

    # We add a bogus sleep here because the loop needs to wait for udev
    sleep 5
  done
}

# make a filesystem on the drive
# $1 is the drive to format
make_filesystem () {
  ldrive=$1

  echo -n "Creating filesystem on /dev/$ldrive:  "
  echo "Creating filesystem on /dev/$ldrive..." >> $INSTALL_LOG

  progress_indicator start
  output=$(mke2fs -j /dev/$ldrive 2>&1)
  status=$?
  if [ "$status" != 0 ]; then
    echo -e "Error: couldn't create the root filesystem.\nSee $INSTALL_LOG for further details.\nExiting..."
    echo -e "Error: couldn't create the root filesystem.\n/sbin/mke2fs -j /dev/$lDRIVE\n$output"
    exit 1
  fi
  progress_indicator stop
  echo "OK"
}

# create the root partition
# $1 is the install drive e.g. sda
# $2 is the partition size e.g. 512
# This will set the global ROOT_PARTITION
create_partitions() {
  ldrive=$1
  root_part_size=$2

  # Make sure there is enough space on drive
  size=$(get_drive_size "$ldrive") 
  if [ "$root_part_size" -gt "$size" ]; then
    echo "Error: $ldrive is only $size"MB" large."
    exit 1
  fi

  echo "Creating root partition on /dev/$ldrive" >> $INSTALL_LOG
  
  # make the root partition
  output=$(parted /dev/$ldrive mkpart primary 0 $root_part_size)
  status=$?
  if [ "$status" != 0 ]; then
    echo -e "Error creating primary partition on $ldrive.\nPlease see $INSTALL_LOG for more details.\nExiting..."
    echo -e "Error creating primary partition on $ldrive.\nparted /dev/$ldrive mkpart primary 0 $root_part_size\n$output" >> $INSTALL_LOG
    exit 1
  fi

  ROOT_PARTITION=$ldrive"1"
  # udev takes time to re-add the device file, so wait for it
  while [ ! -b "/dev/$ROOT_PARTITION" ] 
  do 
    sleep 1
  done

  # make the root and config ext3 file systems.
  make_filesystem "$ROOT_PARTITION"
}

# Install the root filesystem
# $1 is the partition to install on
install_root_filesystem () {
  ldrive=$1

  dpkg="/usr/bin/dpkg --force-all --root=$rootfsdir"
  echo "Mounting /dev/$ldrive "
  echo "Mounting /dev/$ldrive..." >> $INSTALL_LOG

  # make the mount point
  output=$(/bin/mkdir -p $rootfsdir)

  # mount the partition
  output=$(mount -t ext3 /dev/$ldrive $rootfsdir)
  status=$?
  
  if [ "$status" != 0 ]; then
    echo -e "Error trying to mount the new root partition.\nPlease see $INSTALL_LOG for details.\nExiting..."
    echo -e "Error trying to mount the new root partition.\nmount -t ext3 /dev/$ldrive $rootfsdir\n$output" >> $INSTALL_LOG
    exit 1
  fi
  
  echo -n "Copying system image files to /dev/$ROOT_PARTITION: "
  progress_indicator start
  # Mount the squashfs for copying
  output=$(mkdir -p /mnt/squashfs)
  output=$(mount /live/image/live/filesystem.squashfs /mnt/squashfs -t squashfs -o loop)
  status=$?
  
  if [ "$status" != 0 ]; then
    echo -e "Error trying to mount the squashfs.\nPlease see install log for more details.\nExiting..."
    echo -e "Error trying to mount the squashfs.\nmount /live/image/live/filesystem.squashfs /mnt/squashfs -t squashfs -o loop\n$output" >> $INSTALL_LOG
    exit 1
  fi

  output=$(cp -pR /mnt/squashfs/* $rootfsdir/)
  status=$?
  
  if [ "$status" != 0 ]; then
    echo -e "Error trying to copy the rootfs.\nPlease see install log for more details.\nExiting.
.."
    echo -e "Error trying to copy the rootfs.\ncp -pR /mnt/squashfs/* $rootfsdir/\n$output" >> $INSTALL_LOG
    exit 1
  fi

  # unmount the squashfs.  No big deal if it fails.
  output=$(umount /mnt/squashfs)

  # make the dir for the boot files and copy em' over
  mkdir -p $rootfsdir/boot
  output=$(cp -pR /boot/* $rootfsdir/boot/)
  status=$?
  output+=$(cp /live/image/live/initrd1.img $rootfsdir/boot/initrd.img)
  status=$status$?
  if [ "$status" -ne 0 ]; then
    echo -e "Error trying to copy the bootfiles.\nPlease see install log for more details.\nExiting..."
    echo -e "Error trying to copy the bootfiles.\ncp /boot/initrd.img $rootfsdir/boot/\n$output" >> $INSTALL_LOG
    exit 1
  fi

  # create the fstab
  echo -e "/dev/$ROOT_PARTITION\t/\text3\tdefaults\t0 1" >> $rootfsdir/etc/fstab

  #setup the hostname file
  cp /etc/hostname $rootfsdir/etc/
  cp /etc/hosts $rootfsdir/etc/

  progress_indicator stop
  echo "OK"
}

# copy the configuration to the config partition
# $1 is the config partition device
copy_config () {
  config_partition=$1
  lerror=''
  config_default=$vyatta_sysconfdir/config.boot.default
  tmp_config_default=/tmp/${vyatta_sysconfdir//\//__}

  # create the config directory on the union file system
  mkdir -p $rootfsdir$ofrconfdir

  # create the proper perms on the new config partition
  chgrp vyattacfg $rootfsdir$ofrconfdir
  chmod 775 $rootfsdir$ofrconfdir

  # create our config partition marker
  touch $rootfsdir$ofrconfdir/.vyatta_config

  if [ -d /mnt/config ]; then
    echo "Copying old configurations to config partition."
    cp -pR /mnt/config/* $rootfsdir$ofrconfdir
  else
    # Find the config files and give the user the option to copy config files
    # TODO: this needs cleaned up
    if [ -f $ofrconfdir/config.boot ]; then
	config=$ofrconfdir/config.boot
    fi
    if [ -f $fdconfdir/config.boot ]; then
      if [ -z "$config" ]; then
        config="$fdconfdir/config.boot"
      else
        config="$config\n$fdconfdir/config.boot"
      fi
    fi

    if [ -n "$config" ]; then
      echo "I found the following configuration files"
      echo -e "$config"
      default=$(echo -e $config| head -1)

      resp=''
      while [ -z "$configfile" ]
      do
        echo -n "Which one should I copy to $INSTALL_DRIVE? [$default]: "
        configfile=$(get_response "$default" "$config")
      done
      
      echo
      output=$(cp $configfile $rootfsdir$ofrconfdir)
      if [ -n "$output" ]; then
        echo "Error copying file $configfile to config directory.  Exiting..." >> $INSTALL_LOG
        exit 1
      fi
    fi
  fi

  # set the permissions on the new config file
  if [ -f $rootfsdir$ofrconfdir/config.boot ]; then
    chgrp vyattacfg $rootfsdir$ofrconfdir/config.boot
    chmod 775 $rootfsdir$ofrconfdir/config.boot
  fi
}

# setup grub on the boot sector of a user queried drive
install_grub () {
  orig_install_drive="$INSTALL_DRIVE"
  # we now use INSTALL_DRIVE to reference the grub boot drive.
  #  that way I can re-use select_drive.  I'm lazy that way.
  INSTALL_DRIVE=''

  mkdir -p $rootfsdir/boot/grub
  # Let the user choose the boot sector
  
  while [ -z "$INSTALL_DRIVE" ]
  do
    echo "I need to install the GRUB bootloader."
    echo "I found the following drives on your system:"
    select_drive "Which drive should GRUB modify the boot partition on?"
  done

  echo -n "Setting up grub:  "
  echo "Setting up grub..." >> $INSTALL_LOG

  # Install grub in the boot sector of the primary drive
  progress_indicator start
  grub-install --no-floppy --root-directory=$rootfsdir /dev/$INSTALL_DRIVE >>$INSTALL_LOG 2>&1
  progress_indicator stop

  # TODO: This needs to be changed to map to the correct drive
  part=$(echo $ROOT_PARTITION | sed 's/[^0-9]//g')
  if [ "$(cat /sys/block/$orig_install_drive/removable)" == 0 ]; then
    root=$(grep $orig_install_drive $rootfsdir/boot/grub/device.map | /usr/bin/awk -F')' '{ print $1 }')
    root="$root,$part)"
  else 
    root="(hd0,$part)"
    echo "This looks like a removable device.  Setting root grub device to $root."
    echo "This looks like a removable device.  Setting root grub device to $root." >> $INSTALL_LOG
  fi
  
  # Figure out whether we are running on the serial or KVM console:
  if [ "`tty`" == "/dev/ttyS0" ]; then
      # Since user is running on serial console, make that the default.
      DEFAULT_CONSOLE="1"
  else
      # Since user is running on KVM console, make that the default
      DEFAULT_CONSOLE="0"
  fi

  (
    # create the grub.cfg file for grub
    # The "default=" line selects which boot option will be used by default.
    # Numbering starts at 0 for the first option.
    echo -e "set default=$DEFAULT_CONSOLE"
    echo "set timeout=5"
    #echo "#set splashimage=(hd0,0)/grub/splash.xpm.gz"
    echo "hiddenmenu"
    # set serial console options
    echo -e "serial --unit=0 --speed=9600"
    echo "terminal --timeout=5 console serial"
    echo "set root=$root"
    echo
    echo
  
    # Set first system boot option.  Make KVM the default console in this one.
    echo -e "menuentry \"Vyatta OFR (KVM console)\" {"
    echo -en "\tlinux /boot/vmlinuz root=/dev/$ROOT_PARTITION $ISCF console=ttyS0,9600 console=tty0 \n"
    echo -e  "\tinitrd /boot/initrd.img"
    echo -e "}"
  
    # Set the second system boot option.  Make the serial port be the default
    # console in this one.
    echo
    echo -e "menuentry \"Vyatta OFR (Serial console)\" {"
    echo -en "\tlinux /boot/vmlinuz root=/dev/$ROOT_PARTITION $ISCF console=tty0 console=ttyS0,9600 \n"
    echo -e  "\tinitrd /boot/initrd.img"
    echo -e "}"
  
    # Set third and fourth boot options for root password reset.  Offer 
    # options for both serial and KVM console.
  
    echo
    echo -e "menuentry \"Root password reset to factory (KVM console)\" {"
    echo -e "\tlinux /boot/vmlinuz root=/dev/$ROOT_PARTITION $ISCF console=ttyS0,9600 console=tty0 init=$PWRESET"
    echo -e "\tinitrd /boot/initrd.img"
    echo -e "}"
  
    echo
    echo -e "menuentry \"Root password reset to factory (Serial console)\" {"
    echo -e "\tkernel /boot/vmlinuz root=/dev/$ROOT_PARTITION $ISCF console=tty0 console=ttyS0,9600 init=$PWRESET"
    echo -e "\tinitrd /boot/initrd.img"
    echo -e "}"
  ) >"$rootfsdir/boot/grub/grub.cfg"

  echo "OK"
}

# ask for user input on the parted and skip setup methods
# $1 is whether or not to run parted
# sets globals INSTALL_DRIVE, ROOT_PARTITION, CONFIG_PARTITION
setup_method_manual() {
  parted=$1

  echo "The Vyatta install needs a minimum ${ROOT_MIN}MB root"
  echo "with partiton type 83 (Linux)."
  echo -e "\n\n"

  # if this is parted, let the user create the partitions
  if [ "$method" == "parted" ] || [ "$method" == "p" ]; then
    while [ -z "$INSTALL_DRIVE" ]
    do
      # TODO: right now we only run parted on a single drive
      echo -e "\nI found the following drives on your system:"
      select_drive "Which drive would you like to run parted on?"

    done

    # Unmount the install drive if it is mounted
    unmount "$INSTALL_DRIVE"

    # Run parted and let the user configure
    parted /dev/$INSTALL_DRIVE
  fi

  # Ask for the root partition and make sure it's valid
  while [ -z "$ROOT_PARTITION" ]
  do
    select_partition 500 "Which partition should I install the root on?"
    # Note that PARTITION is defined in select partition
    ROOT_PARTITION=$PARTITION
    unmount "$ROOT_PARTITION"
    vd=$(grep $ROOT_PARTITION /proc/partitions | awk '{ print $4 }')

    if [ -z "$vd" ]; then
      echo
      echo "$ROOT_PARTITION is an invalid partition. Please try again."
      ROOT_PARTITION=""
    fi
  done

  # check for an old config on the partition
  check_config_partition "$ROOT_PARTITION"

  # create the ext3 fs on the part
  make_filesystem "$ROOT_PARTITION"

  # We need to set the INSTALL_DRIVE if it wasn't set when the user ran parted
  # We assume that we will use the boot sector of the same drive that the partition is on
  # TODO: Allow different drives to function as the boot device
  if [ -z "$INSTALL_DRIVE" ]; then
    INSTALL_DRIVE=$(echo $ROOT_PARTITION | sed 's/[0-9]//g')
  fi
}

# Walk the user through the auto setup method
# sets globals INSTALL_DRIVE, ROOT_PARTITION, CONFIG_PARTITION
setup_method_auto() {
  while [ -z "$INSTALL_DRIVE" ]
  do
    echo "I found the following drives on your system:"
    select_drive "Install the image on?"

    # check to make sure the drive is large enough to hold the image
    if [ -n "$INSTALL_DRIVE" ]; then 
      lsize=$(get_drive_size "$INSTALL_DRIVE")
      total=$ROOT_MIN
      if [ "$total" -gt "$lsize" ]; then
        echo "Unfortunately, the OFR requires a total of at least $total"MB" to properly install." 
        echo "$INSTALL_DRIVE is below the minimum required capacity and therefore, cannot be used to"
        echo -e "complete the installation.\n"
        echo "If other drives are present"
        echo -e "Please select another drive...\n"

        INSTALL_DRIVE=''
      fi
    fi
  done

  # Give the user a requisite warning that we are about to nuke their drive
  response=''
  while [ -z $response ]
  do
    echo "This will destroy all data on /dev/$INSTALL_DRIVE."
    echo -n "Continue? (Yes/No) [No]: "
    response=$(get_response "No" "Yes No Y N")

    if [ "$response" == "no" ] || [ "$response" == "n" ]; then
      echo "Ok then.  Exiting..."
      exit 1
    fi
  done

  echo

  # make sure we aren't working on a mounted part
  unmount "$INSTALL_DRIVE"

  # remove any existing partitions on that drive
  delete_partitions "$INSTALL_DRIVE"

  # Enforce minimum partion size requirement.
  ROOT_PARTITION_SIZE=0
  while [ $ROOT_MIN -gt $ROOT_PARTITION_SIZE ]; do
    # Get the size of the drive
    size=$(get_drive_size $INSTALL_DRIVE)
    echo -n "How big of a root partition should I create? ($ROOT_MIN"MB" - $size"MB") [$size]MB: "
    response=$(get_response "$size")
    # TODO: need to have better error checking on this value
    ROOT_PARTITION_SIZE=$(echo "$response" | sed 's/[^0-9]//g')
    if [ $ROOT_PARTITION_SIZE -lt $ROOT_MIN ] || [ $ROOT_PARTITION_SIZE -gt $size ]; then
      echo "Root partion must be between $ROOT_MIN"MB" and $size"MB""
      echo
      ROOT_PARTITION_SIZE=0
    fi
  done

  echo

  # now take the data and create the partitions
  create_partitions "$INSTALL_DRIVE" "$ROOT_PARTITION_SIZE" 
}

unmount () {
  # grab the list of mounted drives
  # make sure to reverse sort so as to unmount up the tree
  mounted=$(mount | grep "$1" | cut -f3 -d' ' | sort -r)
  if [ -n "$mounted" ]; then
    echo    "I need to unmount: "
    echo    "$mounted"

    response=''
    while [ -z $response ]
    do 
      echo -n "Continue (Yes/No) [No]: "
      response=$(get_response "No" "Yes No Y N")
      if [ "$response" == "no" ] || [ "$response" == "n" ]; then
        echo -e "Ok then.  Need to unmount to continue.\nExiting..."
        exit 1
      fi
    done
 
    for parts in "$mounted"
    do
      echo "umount $parts" >> $INSTALL_LOG
      output=$(umount $parts)
      status=$?
      if [ "$status" != 0 ]; then
        echo -e "Exiting: error unmounting $parts.\nPlease see $INSTALL_LOG for more details."
        echo -e "Exiting: error unmounting $parts.\numount $parts\n$output" >> $INSTALL_LOG
        exit 1
      fi
    done
  fi
}

progress_indicator () {
  case "$1" in
    start) $vyatta_bindir/progress-indicator $SPID &
             ;;
    *)
	     if ! rm /tmp/pi.$SPID 2>/dev/null
	     then
		sleep 1
		rm /tmp/pi.$SPID 2>/dev/null
	     fi

             sleep 1
	     echo -n -e "\b"
             ;;
  esac
}

#####  Main
##
# clean up existing log files
if [ -f $INSTALL_LOG.old ]; then 
  rm -f $INSTALL_LOG.old
fi
if [ -f $INSTALL_LOG ]; then
  mv $INSTALL_LOG $INSTALL_LOG.old
  rm -f $INSTALL_LOG
fi

# turn off any mounted swap files
turnoffswap

# Print welcome and instructions.
echo "Welcome to the Vyatta install program.  This script"
echo "will walk you through the process of installing the"
echo "Vyatta image to a local hard drive."
echo

response=''
while [ -z $response ]
do
  echo -n "Would you like to continue? (Yes/No) [Yes]: "
  response=$(get_response "Yes" "Yes No Y N")
  if [ "$response" == "no" ] || [ "$response" == "n" ]; then
    echo "Ok then.  Exiting..."
    exit 1
  fi
done

# some drives don't show up in /proc/partitions so we need to bootstrap them
echo -n "Probing drives:  "
progress_indicator start
probe_drives
progress_indicator stop
echo "OK"

echo "The Vyatta image will require a minimum ${ROOT_MIN}MB root."
echo "Would you like me to try to partition a drive automatically"
echo "or would you rather partition it manually with parted?  If"
echo "you have already setup your partitions, you may skip this step."
echo

method=''
while [ -z $method ]
do
  echo -n "Partition (Auto/Parted/Skip) [Auto]: "
  method=$(get_response "Auto" "Auto Parted Skip A P S")
done

echo
  
# TODO: Note installs assume an LBA BIOS.  So no boot partition currently.
# also note that we are not creating a swap partition right now.
if [ "$method" == "parted" ] || [ "$method" == "p" ]; then
  setup_method_manual "parted"
elif [ "$method" == "skip" ] || [ "$method" == "s" ]; then
  setup_method_manual "skip" 
elif [ "$method" == "auto" ] || [ "$method" == "a" ]; then
  setup_method_auto
elif [ "$method" == "vyatta" ]; then
  echo "Automated install..."
  echo "unmounting $INSTALL_DRIVE"
  unmount "$INSTALL_DRIVE"
  echo "deleting partitions on $INSTALL_DRIVE"
  delete_partitions "$INSTALL_DRIVE"
  echo "creating config partition"
  create_partitions "$INSTALL_DRIVE" "$ROOT_PARTITION_SIZE"
fi

# Install the root filesystem
install_root_filesystem "$ROOT_PARTITION"

# Copy the config files
copy_config "$CONFIG_PARTITION"

# Install grub
install_grub

cp $INSTALL_LOG $rootfsdir/install.log

umount $rootfsdir

echo "Done!"
echo "Done!" >> $INSTALL_LOG

exit 0