#!/bin/bash 
# $Id: debootstrap.sh,v 1.99 2009-10-28 01:37:01 cvs Exp $

DEFAULT_DISTRO="debian"
DEFAULT_RELEASE="lenny"
DEFAULT_CHROOT="/raid"
DEFAULT_PASSWD="foobar8192"
DEBOOTSTRAP_MIRROR=http://us.archive.ubuntu.com/ubuntu
DEBOOTSTRAP_VERSION="1.0.20"
DEBOOTSTRAP_PACKAGE=$DEBOOTSTRAP_MIRROR/pool/main/d/debootstrap/debootstrap_${DEBOOTSTRAP_VERSION}.tar.gz
MIRROR_UBUNTU="http://us.archive.ubuntu.com"
MIRROR_DEBIAN="http://ftp.us.debian.org"
CONF_DIR=/rimu
MIRROR_DT="http://192.168.254.2"
MIRROR_MISC="http://downloads.rimuhosting.com"
APT_PROXY="http://192.168.254.2:9999"

function usage() {
echo "$0 Usage: <--distro debian|ubuntu> <--passwd passwd> [--arch {i386|amd64}] [--release] [--chroot /path/to/install/into] [--noprompt]"
echo "By default ${DEFAULT_DISTRO}/${DEFAULT_RELEASE} ${DEFAULT_ARCH} will be installed into ${DEFAULT_CHROOT}."
echo "Example usage: $0 --distro ubuntu --arch amd64 --release hardy --passwd foo"
}

if [ "$(uname -m)" == "x86_64" ]; then
	DEFAULT_ARCH="amd64"
else
	DEFAULT_ARCH="i386"
fi

while  [ -n "$1" ]; do
	case "$1" in
		--distro)
			shift
			if [ -n "$1" ]; then
				DISTRO="$1"
			else
				echo "No distro passed in with --distro, exiting."
				usage
				exit 1
			fi
			;;
		--arch)
			shift
			if [ "$1" == "amd64" -o "$1" == "x86_64" ]; then
				ARCH="amd64"
			elif [ "$1" == "i386" ]; then
				ARCH="i386"
			else
				echo "* Unknown arch '$1'. Exiting."
				exit 1
			fi
			;;
		--release)
			shift
			RELEASE="$1"
			;;
		--chroot)
			shift
			CHROOT="$1"
			;;
		--passwd)
			shift
			if [ -z "$1" ]; then
				echo "* No password passed in with --passwd, exiting."
				usage
				exit 1
			else
				PASSWD="$1"
			fi
			;;
		--noprompt)
			NO_PROMPT=true
			;;
		--ip)
			shift
			if [ -z "$1" ]; then
				echo "* No IP passed in with --ip, exiting."
				usage
				exit 1
			else
				IP=$1
			fi
			;;
		--netmask)
			shift
			if [ -z "$1" ]; then
				echo "* No netmask passed in with --netmask, exiting."
				usage
				exit 1
			else
				NETMASK=$1
			fi
			;;
		--gateway)
			shift
			if [ -z "$1" ]; then
				echo "* No gateway passed in with --gateway, exiting."
				usage
				exit 1
			else
				GATEWAY=$1
			fi
			;;
		--hostname)
			shift
			if [ -z "$1" ]; then
				echo "* No hostname passed in with --hostname, exiting."
				usage
				exit 1
			else
				HOSTNAME=$1
			fi
			;;
		--dt)
			DT=true
			;;
		--help|-h|-help|*)
			usage
			exit 0
			;;
			
	esac
	shift
done

if [ -z "$ARCH" ]; then
	ARCH=$DEFAULT_ARCH
fi

if [ -z "$DISTRO" ]; then
	echo "You need to select a distro with --distro"
	usage
	exit 1
fi

if [ -n "${DT}" ]; then
	MIRROR_MISC=${MIRROR_DT}
	DEBOOTSTRAP_PACKAGE=${MIRROR_DT}/debootstrap_${DEBOOTSTRAP_VERSION}.tar.gz
	MIRROR_DEBIAN="${APT_PROXY}"
	MIRROR_UBUNTU="${APT_PROXY}"
fi

if ! which debootstrap &> /dev/null; then
        wget "$DEBOOTSTRAP_PACKAGE"
        if [ $? -ne 0 ]; then echo "* Failed to download $DEBOOTSTRAP_PACKAGE. Exiting."; exit 1; fi
        tar xzf $(basename $DEBOOTSTRAP_PACKAGE)
        if [ $? -ne 0 ]; then "* Failed to untar $(basename $DEBOOTSTRAP_PACKAGE). Exiting."; exit 1; fi
        cd debootstrap*
        if [ $? -ne 0 ]; then echo "* Found no 'debootstrap' directory. Exiting."; exit 1; fi
	# temp fix. see launchpad bug #172659
        mkdir -p /usr/share/debootstrap/scripts
	make
        make install
        if [ $? -ne 0 ]; then echo "* debootstrap install failed. Exiting."; exit 1; fi
fi

if [ -z "$RELEASE" ]; then
	RELEASE=$DEFAULT_RELEASE
fi

if [ ! -e "/usr/share/debootstrap/scripts/${RELEASE}" ]; then
	echo "* Unknown release '${RELEASE}'. Check /usr/share/debootstrap/scripts for supported releases. Exiting."
	exit 1
fi

if [ -z "$CHROOT" ]; then
	CHROOT=$DEFAULT_CHROOT
fi

# We set these here to avoid the debootstrap mirror interferring
if [ "$DISTRO" == "ubuntu" ]; then
	MIRROR=$MIRROR_UBUNTU
fi

if [ "$DISTRO" == "debian" ]; then
	MIRROR=$MIRROR_DEBIAN
fi
if [ -z "${DT}" ]; then
	# Don't do the partition check on kickstart/DT installs
	if [ $(df -h | grep -ic $CHROOT) -eq 0 ]; then
		echo "* Root partition '$CHROOT' not found. Exiting."
		exit 1
	else
		ROOTPARTITION=$(df -h | grep "$CHROOT" | awk '{print $1}')
		if [ -z "$ROOTPARTITION" ]; then
		        echo "* Root parition for $CHROOT not found. Exiting."
  	     	 	exit 1
		fi
	fi
fi

while [ -z "$PASSWD" ]; do
	if [ -z "${NO_PROMPT}" ]; then
		echo -n "* Enter root password for chroot: "
		read PASSWD
	else
		PASSWD=${DEFAULT_PASSWD}
	fi
done


ETH0ALIAS=$(grep eth0 /etc/modprobe.conf)
HOSTNAME=${HOSTNAME:-$(hostname)}
IP=${IP:-$(ifconfig eth0 | grep inet | cut -d":" -f2 | cut -f1 -d" ")}
#BROADCAST=$(ifconfig eth0 | grep inet | cut -d":" -f3 | cut -f1 -d" ")
NETMASK=${NETMASK:-$(ifconfig eth0 | grep 'inet addr:' | cut -d":" -f4)}
GATEWAY=${GATEWAY:-$(route -n | grep UG | awk '{print $2}')}
if [ -z "$(which replace)" ]; then
	        wget -O /usr/bin/replace "${MIRROR_MISC}/replace"
		chmod +x /usr/bin/replace
fi
if [ ! -e /usr/lib/debootstrap/devices.tar.gz ]; then
	mkdir -p /usr/lib/debootstrap/
	tar  cf - --directory / dev | gzip -9 > /usr/lib/debootstrap/devices.tar.gz
fi

if [ -d ${CONF_DIR} ]; then 
	echo "* Found ${CONF_DIR}. Already inside a chroot? Exiting."
	exit 1
fi

function bootstrapit() {
	echo "* Going to run '/usr/sbin/debootstrap --arch $ARCH $RELEASE $CHROOT ${MIRROR}/${DISTRO}'"  
	echo "* Network settings - "
	echo "  IP Address: $IP"
	echo "  Gateway: $GATEWAY"
	echo "  Netmask: $NETMASK"
	echo "  Hostname: $HOSTNAME"
	echo "  Root Password: $PASSWD"
	if [ -z "${NO_PROMPT}" ]; then
	echo ""
	echo -n "Hit enter to continue, CTRL-C to abort."	
	read yn
	fi
	/usr/sbin/debootstrap --arch $ARCH $RELEASE $CHROOT ${MIRROR}/${DISTRO}
#	echo "  Broadcast: $BROADCAST"
}
function prepchroot() {
	echo "* Preparing chroot..."
	mkdir -p $CHROOT/${CONF_DIR}
	mkdir -p $CHROOT/proc
	echo "$HOSTNAME" > $CHROOT/etc/hostname
	echo "$HOSTNAME" > $CHROOT/etc/mailname
	echo "127.0.0.1 localhost localhost.localdomain
$IP $HOSTNAME" > $CHROOT/etc/hosts
	[ -e /root/prepdedserver.sh -a ! -e $CHROOT/root/prepdedserver.sh ] && mkdir -p $CHROOT/root && cp /root/prepdedserver.sh $CHROOT/root/
	echo "search $HOSTNAME
nameserver 4.2.2.1" > $CHROOT/etc/resolv.conf

	echo "auto lo
  iface lo inet loopback

auto eth0
  iface eth0 inet static
  address $IP
  netmask $NETMASK
# broadcast $BROADCAST
  gateway $GATEWAY" > $CHROOT/etc/network/interfaces

	if [ ! -e $CHROOT/etc/fstab.orig ] ; then
        	cp $CHROOT/etc/fstab $CHROOT/etc/fstab.orig
	fi

	cat /etc/fstab | grep '/boot' > $CHROOT/etc/fstab
	cat /etc/fstab | grep '^none' >> $CHROOT/etc/fstab
	echo "$ROOTPARTITION	/ 	ext3    	defaults        1 1" >> $CHROOT/etc/fstab
	swapon -s | grep -v Filename | awk '{print $1}' | {
		while true; do read line || break;
			if grep -qai $line $CHROOT/etc/fstab  ; then
    				echo "$line already in /etc/fstab"
    				continue
			fi
			echo "$line swap swap defaults 0 0" >> $CHROOT/etc/fstab
		done
	}

	if [ -e /root/.ssh/authorized_keys -a ! -e /$CHROOT/root/.ssh/authorized_keys ]; then
		mkdir -p $CHROOT/root/.ssh
		cp -arp /root/.ssh/authorized_keys /$CHROOT/root/.ssh/authorized_keys
	fi

	if [ "$DISTRO" == "debian" ]; then
		echo "deb http://ftp.us.debian.org/debian $RELEASE main contrib
deb http://security.debian.org/ $RELEASE/updates main
deb-src http://ftp.us.debian.org/debian $RELEASE main contrib" > $CHROOT/etc/apt/sources.list
	fi

	if [ "$DISTRO" == "ubuntu" ]; then
		echo "deb http://us.archive.ubuntu.com/ubuntu/ ${RELEASE} main restricted
deb http://us.archive.ubuntu.com/ubuntu/ ${RELEASE}-updates main restricted
deb http://us.archive.ubuntu.com/ubuntu/ ${RELEASE} universe
deb http://us.archive.ubuntu.com/ubuntu/ ${RELEASE} multiverse
deb http://us.archive.ubuntu.com/ubuntu/ ${RELEASE}-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu ${RELEASE}-security main restricted
deb http://security.ubuntu.com/ubuntu ${RELEASE}-security universe
deb http://security.ubuntu.com/ubuntu ${RELEASE}-security multiverse" > $CHROOT/etc/apt/sources.list
	fi

	if [ "$RELEASE" == "etch" ] || [ "$RELEASE" == "lenny" ]; then
		echo "deb http://www.backports.org/backports.org/ ${RELEASE}-backports main contrib non-free" >> $CHROOT/etc/apt/sources.list
		echo "Package: *
Pin: release a=${RELEASE}-backports
Pin-Priority: 200" > $CHROOT/etc/apt/preferences
	fi

	if [ -n "${DT}" ]; then
		cp $CHROOT/etc/apt/sources.list $CHROOT/etc/apt/sources.list.dt
		replace "http://ftp.us.debian.org" "${APT_PROXY}" -- $CHROOT/etc/apt/sources.list
		replace "http://security.debian.org" "${APT_PROXY}" -- $CHROOT/etc/apt/sources.list
		replace "http://us.archive.ubuntu.com" "${APT_PROXY}" -- $CHROOT/etc/apt/sources.list
		replace "http://security.archive.ubuntu.com" "${APT_PROXY}" -- $CHROOT/etc/apt/sources.list
		cat ${CHROOT}/etc/apt/sources.list
	fi

	echo "do_initrd = Yes" > $CHROOT/etc/kernel-img.conf

	wget -O $CHROOT/bin/replace "${MIRROR_MISC}/replace"
	if [ $? -ne 0 ]; then return 1; fi	
	chmod +x $CHROOT/bin/replace

	echo "#!/bin/bash
if [ ! -d ${CONF_DIR} ]; then
	echo "Not running inside the chroot. Exiting"
	exit 1
fi" > $CHROOT/${CONF_DIR}/setup.sh
if [ -n "${DT}" ]; then
	echo "mount -t ext3 /dev/md0 /boot" >> $CHROOT/${CONF_DIR}/setup.sh
fi
echo 'mount -a
mount -t proc proc /proc
mount /boot
export DEBIAN_PRIORITY=critical
export DEBIAN_FRONTEND=noninteractive
wget -O - http://backports.org/debian/archive.key | apt-key add -
apt-get update
apt-get -y upgrade
PACKAGE_LIST="postfix mdadm ssh openssh-server locales module-init-tools wget man manpages less lvm2 grub host ethtool smartmontools"
for package in $PACKAGE_LIST; do
	apt-get -y install $package
	if [ $? -ne 0 ]; then
		echo "* Failed to install package $package."
		exit 1
	fi
sed s/"# en_US.UTF-8 UTF-8"/"en_US.UTF-8 UTF-8"/g --in-place /etc/locale.gen
locale-gen
done' >> $CHROOT/${CONF_DIR}/setup.sh

if [ "$DISTRO" == "debian" ]; then
	if [ "$ARCH" == "amd64" ]; then
		KERNEL=linux-image-2.6-amd64
	else
		KERNEL=linux-image-686-bigmem
	fi
fi
if [ "$DISTRO" == "ubuntu" ]; then
	KERNEL=linux-image-server
fi
if [ "$RELEASE" == "etch" ]; then
	echo "apt-get -y install linux-image-2.6-${ARCH}-etchnhalf" >> $CHROOT/${CONF_DIR}/setup.sh
else
	echo "apt-get -t ${RELEASE}-backports -y install $KERNEL" >> $CHROOT/${CONF_DIR}/setup.sh
fi
echo "mv -f /etc/apt/sources.list.dt /etc/apt/sources.list" >> $CHROOT/${CONF_DIR}/setup.sh
echo "echo 'Setting the password on the chroot distro'
echo 'root:$PASSWD' | chpasswd" >> $CHROOT/${CONF_DIR}/setup.sh
chmod +x $CHROOT/${CONF_DIR}/setup.sh

}

function dochroot() {
	LANG= chroot $CHROOT /bin/bash ${CONF_DIR}/setup.sh
	if [ $? -ne 0 ]; then 
		echo "* $CHROOT/${CONF_DIR}/setup.sh script failed to complete."
		return 1
	else
		rm -rf $CHROOT/${CONF_DIR}
	fi
	# Work around for the bug that's causing /raid/boot to not get mounted
	cd /raid/boot; for i in *; do if [ ! -e /boot/$i ]; then mv $i /boot/; fi; done; cd /root
	# Setup GRUB now kernels are installed
	KERNEL_VERSION=$(ls -1 /boot/vmlinuz*-bigmem | head -n1 | cut -d"-" -f2-)
	if [ -z "$KERNEL_VERSION" ]; then
		KERNEL_VERSION=$(ls -1 /boot/vmlinuz*-server | head -n1 | cut -d"-" -f2-)
	fi
	if [ -z "$KERNEL_VERSION" ]; then
		KERNEL_VERSION=$(ls -1 /boot/vmlinuz*-amd64 | head -n1 | cut -d"-" -f2-)
	fi
	if [ -z "$KERNEL_VERSION" ]; then
		echo "* Unable to find kernel version. Set one manually."
	else
		if ! grep -qai $DISTRO /boot/grub/menu.lst ; then	
			newdefault=$(grep -c "^title" /boot/grub/grub.conf)
			echo "title $DISTRO
	root (hd0,0)
	kernel /vmlinuz-${KERNEL_VERSION} ro root=$ROOTPARTITION panic=30
	initrd /initrd.img-${KERNEL_VERSION}" >> /boot/grub/menu.lst

			lastdefault=$(grep -v "#" /boot/grub/grub.conf | grep "^default=" | cut -f2 -d"=")
			replace "default=$lastdefault" "default=$newdefault" -- /boot/grub/grub.conf
			if [ $? -ne 0 ]; then return 1; fi
		fi
	fi

	replace "splashimage" "#splashimage" -- /boot/grub/grub.conf
	replace "hiddenmenu" "#hiddenmenu" -- /boot/grub/grub.conf
	replace "timeout=5" "timeout=15" -- /boot/grub/grub.conf
	replace "title debian" "title Debian" -- /boot/grub/grub.conf
	replace "title ubuntu" "title Ubuntu" -- /boot/grub/grub.conf
	
	# so we don't get key warnings when we boot between distros
	/bin/cp -f /etc/ssh/ssh_host_* $CHROOT/etc/ssh/

	# put the same alias eth0 xxx into the new debian setup
	if [ -z "$ETH0ALIAS" ]; then
		ETH0ALIAS=$(grep eth0 /etc/modprobe.conf)
	fi
	if [ -n "$ETH0ALIAS" ]; then
		for i in $CHROOT/etc/modprobe.d/aliases $CHROOT/etc/modules.conf $CHROOT/etc/modules; do
			if [ -e $i ]; then
				echo $ETH0ALIAS >> $i
				echo "Adding $ETH0ALIAS to $i"
			else
				echo "Skipping eth0 alias for $i"
			fi
		done
	fi
}

function installdebian() {
	bootstrapit
	if [ $? -ne 0 ]; then return 1; fi
	prepchroot
	if [ $? -ne 0 ]; then return 1; fi
	dochroot
}

installdebian
if [ $? -ne 0 ]; then
	echo "* Install failed."
	exit 1
else
	echo "* Install complete. Check the output below before rebooting."

	echo "Configured network interfaces:"
	cat $CHROOT/etc/network/interfaces

	echo "GRUB:"
	cat /boot/grub/grub.conf

	echo "/etc/fstab:"
	cat $CHROOT/etc/fstab

	modprobe_conf="${CHROOT}/etc/modprobe.d/aliases ${CHROOT}/etc/modprobe.conf ${CHROOT}/etc/modules"
	for conf in ${modprobe_conf}; do
		if [ -e ${conf} ]; then
			[ $(grep -ic eth0 ${conf}) -gt 0 ] && eth0_conf=${conf}
		fi
	done
	if [ -n "${eth0_conf}" ]; then
		echo "${eth0_conf} eth0 alias:"
		grep -i eth0 ${conf}
	else
		echo "* Warning: No eth0 found in ${modprobe_conf}. Make sure you add one before rebooting."
	fi
fi

