#!/bin/bash
#
# System installer.
#

# Load.
source $APP_BASE/lib/hydra/functions || exit 1
hydra_config_load

# Setup.
hydra_user_input device /dev/sdb "Destination device"
hydra_user_input swap_device /dev/sda1 "Final swap device"
hydra_user_input encrypt y "Encrypt system and storage volumes? (y/n)"
hydra_user_input garbage y "Pre-fill volumes with garbage? (y/n)"
hydra_user_input hostname $HOSTNAME "Hostname"
hydra_user_input domain example.com "Domain"
hydra_user_input arch amd64 "System arch"
hydra_user_input version squeeze "Distro version"
hydra_user_input vg vg "Temporary install vg"
hydra_user_input grub n "Setup GRUB? (y/n)"
hydra_user_input mirror http://cdn.debian.net/debian/ "Debian mirror"

# Check for requirements.
for req in debootstrap cryptsetup grub-pc lvm2; do
  hydra_install_package $req
done

# Warning.
cat <<-EOF
Make sure you have chosen the right parameters and that $device has the needed partitions:

    # fdisk -l $device
    Disk /dev/sdb: 1000.2 GB, 1000204886016 bytes
    255 heads, 63 sectors/track, 121601 cylinders
    Units = cilindros of 16065 * 512 = 8225280 bytes
    Disk identifier: 0x00000000
    
    Dispositivo Boot      Start         End      Blocks   Id  System
    ${device}1               1         249     2000061   82  Linux swap
    ${device}2   *         250         273      192780   83  Linux
    ${device}3             274      121601   974567160   8e  Linux LVM

The number of blocks are figurative: the important thing is to have the
partition layout listed above.

Press ENTER to continue, Ctrl-C to abort."
EOF
read answer

# Create volumes.
echo "Creating the needed disk volumes..."

if ! pvdisplay "$device"3 &> /dev/null; then
  echo "Creating physical volume..."
  pvcreate "$device"3
fi

if ! vgdisplay $vg &> /dev/null; then
  echo "Creating volume group..."
  vgcreate $vg "$device"3
fi

if ! lvdisplay $vg/root &> /dev/null; then
  echo "Creating logical volume..."
  lvcreate -L20G -n root $vg
fi

vgchange -a y $vg

# Garbage.
if [ "$garbage" == "y" ]; then
  echo "Filling volumes with garbage..."
  dd if=/dev/urandom of=/dev/$vg/root
  dd if=/dev/urandom of="$device"1
fi

# Setup mountpoint and make sure it's not mounted due to a failed install.
mkdir -p /tmp/debootstrap
umount /tmp/debootstrap/proc &> /dev/null
umount /tmp/debootstrap/dev  &> /dev/null

# Create root device.
if [ "$encrypt" == "y" ]; then
  echo "Creating encrypted root device..."
  cryptsetup -h sha256 -c aes-cbc-essiv:sha256 -s 256 luksFormat /dev/$vg/root
  cryptsetup luksOpen /dev/$vg/root debootstrap
  mkfs.ext3 /dev/mapper/debootstrap
  install_device="/dev/mapper/debootstrap"
else
  echo "Creating root device..."
  mkfs.ext3 /dev/vg/root
  install_device="/dev/vg/root"
fi

# Initial system install.
echo "Installing base system..."
mount $install_device /tmp/debootstrap/
debootstrap --arch=$arch $version /tmp/debootstrap/ $mirror

# Initial configuration.
echo "Applying initial configuration..."
mount none -t proc /tmp/debootstrap/proc/
mount -o bind /dev/ /tmp/debootstrap/dev
echo LANG=C > /tmp/debootstrap/etc/default/locale

# Resolver configuration.
echo "domain $domain" > /tmp/debootstrap/etc/resolv.conf
echo "search $hostname.$domain" >> /tmp/debootstrap/etc/resolv.conf
grep nameserver /etc/resolv.conf >> /tmp/debootstrap/etc/resolv.conf

# Hostname configuration.
echo $hostname.$domain > /tmp/debootstrap/etc/hostname
echo "127.0.0.1 $hostname $hostname.$domain" >> /tmp/debootstrap/etc/hosts
echo "127.0.0.1 localhost" >> /tmp/debootstrap/etc/hosts

# Invert hostname contents to avoid http://projects.puppetlabs.com/issues/2533
tac /tmp/debootstrap/etc/hosts > /tmp/debootstrap/etc/hosts.new
mv /tmp/debootstrap/etc/hosts.new /tmp/debootstrap/etc/hosts

# Initial upgrade.
echo "Applying initial upgrades..."
chroot /tmp/debootstrap/ apt-get update
chroot /tmp/debootstrap/ apt-get upgrade -y
chroot /tmp/debootstrap/ apt-get install locales cryptsetup lvm2 initramfs-tools -y

# Crypttab.
echo "Configuring crypttab..."
if [ "$encrypt" == "y" ]; then
  cat > /tmp/debootstrap/etc/crypttab <<-EOF
# <target name> <source device>   <key file>  <options>
root            /dev/mapper/vg-root     none            luks,cipher=aes-cbc-essiv:sha256
cswap           $swap_device               /dev/random     swap,cipher=aes-cbc-essiv:sha256
EOF
else
  cat > /tmp/debootstrap/etc/crypttab <<-EOF
# <target name> <source device>   <key file>  <options>
cswap           $swap_device               /dev/random     swap,cipher=aes-cbc-essiv:sha256
EOF
fi

# Fstab.
echo "Configuring fstab..."
if [ "$encrypt" == "y" ]; then
  cat > /tmp/debootstrap/etc/fstab <<-EOF
/dev/mapper/cswap none swap sw 0 0
/dev/mapper/root  /    ext3 defaults,errors=remount-ro 0 1
EOF
else
  cat > /tmp/debootstrap/etc/fstab <<-EOF
/dev/mapper/cswap none swap sw 0 0
/dev/vg/root      /    ext3 defaults,errors=remount-ro 0 1
EOF
fi

# Grub.
if [ "$grub" == "y" ]; then
  echo "Boot device setup..."
  mkfs.ext3 "$device"2
  mount "$device"2 /tmp/debootstrap/boot
  echo "$device""2 /boot ext3 defaults,errors=remount-ro 0 2" >> /tmp/debootstrap/etc/fstab

  echo "Setting up GRUB..."
  chroot /tmp/debootstrap/ apt-get install grub-pc -y
  grub-install --no-floppy "$device"
  mkdir -p /tmp/debootstrap/boot/grub/
  cat /tmp/debootstrap/boot/grub/menu.lst <<-EOF
title $hostname (hd0)
root  (hd0,1)
kernel  /vmlinuz-2.6.26-2-vserver-amd64 root=/dev/mapper/root ro quiet rootdelay=10
initrd  /initrd.img-2.6.26-2-vserver-amd64

title $hostname (hd0) (single)
root  (hd0,1)
kernel  /vmlinuz-2.6.26-2-vserver-amd64 root=/dev/mapper/root ro single rootdelay=10
initrd  /initrd.img-2.6.26-2-vserver-amd64
EOF
fi

# Kernel.
echo "Installing kernel..."
cat > /tmp/debootstrap/etc/initramfs-tools/modules <<-EOF
dm-mod
dm-crypt
aes
twofish
sha256
EOF

cat > /tmp/debootstrap/etc/kernel-img.conf <<-EOF
do_initrd = Yes
EOF

if [ "$arch" == "i386" ]; then
  kernel_arch="686"
else
  kernel_arch="$arch"
fi

chroot /tmp/debootstrap apt-get install linux-image-2.6-vserver-$kernel_arch -y

# Initramfs.
echo "Creating initramfs..."
chroot /tmp/debootstrap update-initramfs -v -u

# Utils.
echo "Installing basic utilities..."
chroot /tmp/debootstrap apt-get install screen cron lsb-release openssl -y

# Ssh.
echo "Installing OpenSSH daemon..."
chroot /tmp/debootstrap apt-get install openssh-server -y

echo "OpenSSH fingerprints:"
chroot /tmp/debootstrap ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub
chroot /tmp/debootstrap ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub

# Accounts.
echo "Installing sudo..."
chroot /tmp/debootstrap apt-get install sudo -y

echo "Choose a root password."
chroot /tmp/debootstrap passwd root

cat <<-EOF

Now proceeed with final steps:

  - Create an user account with sudo privileges.
  - Network setup.

See http://padrao.sarava.org/install for more information.
EOF