#!/bin/bash
# Settings !!!*** PLEASE MODIFY THESE ***!!!
export MIRROR="http://mirrors.kernel.org/centos/5.6/os/i386/CentOS/"
export TMPDIR=`pwd`"/tmp"
export ROOT_FS=`pwd`"/CentOS5.6-x86-root_fs"
export RPM_DIR=`pwd`"/RPMS"
export CHROOTCMD="linux32 chroot"
export RPMCMD="rpm"
export PACKAGES="packages.x86"
export ARCHES="i386 i486 i586 i686 noarch"
export DEBUG=""
export DUPES=""
export TEXT_BROWSER="elinks"

function doGetRPM() {
	rpmfile=""
	if [ ! -z "$DEBUG" ]; then
		echo "grep $1 $PACKAGES | grep $2 | wc -l"
	fi
	rpmfilescount=`grep ^$1 $PACKAGES | grep $2 | wc -l`
	#echo "filecount=$rpmfilescount"
	if [ "$rpmfilescount" -eq 0 ]; then
		if [ ! -z "$DEBUG" ]; then
			echo "No RPMs found for $1 - $2"
		fi
	else
		if [ "$rpmfilescount" == "1" ]; then
			# echo "Found "`$grep`
			rpmfile=`grep ^$1 $PACKAGES | grep $2`
		else
			if [ ! -z "$DEBUG" ]; then
				echo "Too many packages matching $1: $rpmfilescount"
			fi
			rpmfile=`grep ^$1 $PACKAGES | grep $2 | sort | head -n 1`
		fi
	fi
}
function getRPM() {
	for arch in $ARCHES; do
		doGetRPM $1- $arch
		if [ ! -z "$rpmfile" ]; then
			return
		fi
	done
	for arch in $ARCHES; do
		doGetRPM $1 $arch
		if [ ! -z "$rpmfile" ]; then
			return
		fi
	done
	echo "No RPM package found for $1"
	exit 1
}

function fetch() {
	base=$1
	getRPM $base
	local=$RPM_DIR"/$rpmfile"
	echo "fetch() base=$base, local=$local, rpmfile=$rpmfile"
	if [ ! -e "$local" ]; then
		echo "Downloading $base ($rpmfile)"
		wget -c -O $local "$MIRROR$rpmfile"
	fi
}

function rpminstall() {
	base=$1
	fetch $base
	stripped=`echo $base | sed 's+\.noarch++g' | sed 's+\.[3-6]86++g'`
	exists="0"
	if [ ! -z "$DUPES" ]; then
		exists=`$RPMCMD -qa --root $TMPDIR | grep $stripped | wc -l`
	fi
	if [ "$exists" -ne "0" ]; then
		echo "skipped: $stripped"
	else
		$RPMCMD -Uvh --root $TMPDIR $local
		rm -fr $TMPDIR/var/lib/rpm/__db*
	fi
}
function rpminstallgroup() {
	echo "SIZE="$#
	list=""
	while [ $# -ne 0  ]
	do
		package=$1
		fetch $package

		stripped=`echo $1 | sed 's+\.noarch++g' | sed 's+\.[3-6]86++g'`
		exists="0"
		if [ ! -z "$DUPES" ]; then
			exists=`$RPMCMD -qa --root $TMPDIR | grep $stripped | wc -l`
		fi
		if [ "$exists" -ne "0" ]; then
			echo "skipped: $stripped"
		else
			list="$list $local"
		fi
		shift
	done
	# echo	"installing list=$list"
	# echo "installcommand=$RPMCMD -ivh --root $TMPDIR $list"
	$RPMCMD -Uvh --root $TMPDIR $list
	rm -fr $TMPDIR/var/lib/rpm/__db*
}


# Making the filesystem
if [ ! -e "$ROOT_FS" ]; then
	dd if=/dev/zero of=$ROOT_FS bs=1024 count=1 seek=1572864
	mkfs.ext3 -L ROOT -F $ROOT_FS
else
	echo "Filesystem already created"
fi
if [ ! -e "$TMPDIR" ]; then
	mkdir $TMPDIR
	mount -o loop $ROOT_FS $TMPDIR
else
	echo "Filesystem already mounted"
fi
mkdir -p $RPM_DIR
#rpm bug?
mkdir -p $TMPDIR/var/lock/rpm
mkdir -p $TMPDIR/var/lib/rpm

if [ ! -e "$TMPDIR/var/lib/rpm" ]; then
	echo "initrpm:"
	echo "$RPMCMD --initdb --root $TMPDIR"
	$RPMCMD --initdb --root $TMPDIR
	rm -fr $TMPDIR/var/lib/rpm/__db*
fi
if [ ! -e "$TMPDIR/dev" ]; then
	mkdir $TMPDIR/dev
	mknod $TMPDIR/dev/null c 1 3
fi

#Get the list of packages
PKG_DATA=""
if [ -f $PACKAGES ]; then
	PKG_DATA=`cat $PACKAGES`
fi
if [ -z "${PKG_DATA}" ]; then
	if [ -x "`which ${TEXT_BROWSER}`" ]; then
		echo "${TEXT_BROWSER} -dump $MIRROR |grep rpm\$ |awk -F "CentOS/" '{print $2}' >$PACKAGES"
		${TEXT_BROWSER} -dump $MIRROR |grep rpm\$ |awk -F "CentOS/" '{print $2}' >$PACKAGES
		PKG_DATA=`cat $PACKAGES`
		if [ -z "${PKG_DATA}" ]; then
			echo "error: failed to get the list of packages"
			exit 1
		fi
	else
		echo "error :$PACKAGES does not exist, and I could not build it with ${TEXT_BROWSER}"
		echo "error :$PACKAGES should contain a list of all rpms on your mirror site"
		exit 1
	fi
fi

echo "going to fetch"
# pretend to have a kernel (we don't need one):
KERNEL=`grep kernel-2.6 $PACKAGES`
fetch $KERNEL
$RPMCMD -Uvh --justdb --force --nodeps --root $TMPDIR $local
rm -fr $TMPDIR/var/lib/rpm/__db*

mkdir -p $TMPDIR/etc
# create an /etc/fstab
echo "LABEL=ROOT      /               auto    defaults                1   1" >>$TMPDIR/etc/fstab
echo "none            /dev/pts        devpts  gid=5,mode=620          0   0" >>$TMPDIR/etc/fstab
echo "none            /proc           proc    defaults                0   0" >>$TMPDIR/etc/fstab
echo "tmpfs           /tmp            tmpfs   defaults,size=768M      0   0" >>$TMPDIR/etc/fstab

mkdir -p $TMPDIR/usr/kerberos

# Installing the base packages
# no deps for these - got problems otherwise...
packages="centos-release-notes glibc libsepol pam passwd usermode setup filesystem basesystem util-linux libgcc tzdata termcap libtermcap zlib zip man-pages mktemp bash ncurses info gawk vim-common libattr libacl libstdc++ pcre grep cracklib-dicts glib2 centos-release chkconfig sed iputils rootfiles ethtool audit-libs popt libsysfs sysfsutils cpio less gzip readline tar db4 iproute mingetty libselinux libsemanage SysVinit module-init-tools hwdata sysklogd udev procps diffutils libcap vim-minimal findutils device-mapper e2fsprogs-libs e2fsprogs net-tools shadow lvm2 MAKEDEV psmisc bzip2-libs libxml beecrypt expat sqlite tcp_wrappers gdbm coreutils cracklib python python-libs python-docs python-iniparse fipscheck fipscheck-lib openssl libgssapi krb5-libs libselinux-python initscripts db4 glibc-headers audit-libs-python policycoreutils libselinux-python libsemanage mkinitrd dmraid nss"
for package in $packages; do
	fetch $package
	$RPMCMD -Uvh --force --noscripts --nodeps --root $TMPDIR $local
	rm -fr $TMPDIR/var/lib/rpm/__db*
done
mkdir $TMPDIR/etc/profile.d

$CHROOTCMD $TMPDIR useradd rpm
packages="rpm rpm-libs"
for package in $packages; do
	fetch $package
	$RPMCMD -Uvh --force --noscripts --nodeps --root $TMPDIR $local
	rm -fr $TMPDIR/var/lib/rpm/__db*
done

# some extras
packages="which nspr python-iniparse keyutils-libs vixie-cron m2crypto python-urlgrabber neon elfutils-libelf elfutils-libs elfutils openssh openssh-clients openssh-server wget python-elementtree python-sqlite elfutils rpm-python dhcp yum-metadata-parser"
for package in $packages; do
	rpminstall $package
done

#$RPMCMD -e --nodeps --root $TMPDIR rpm
#fetch rpm
#$RPMCMD -ivh --force --nodeps --root $TMPDIR $local

# rpm gets confused by these:
rm -f $TMPDIR/var/lib/rpm/__db*

# yum needs to be installed by the real rpm...
fetch yum-fastestmirror
cp $local $TMPDIR/root
YUMVER=`grep yum-[0-9] $PACKAGES`
fetch $YUMVER
cp $local $TMPDIR/root
$CHROOTCMD $TMPDIR rpm -Uvh /root/yum*rpm /root/yum-fastestmirror*
rm $TMPDIR/root/yum*rpm $TMPDIR/root/yum-fastestmirror*

# ldconfig the newly installed libraries
ldconfig -r $TMPDIR
# create the ubd devices
if [ ! -e "$TMPDIR/dev/ubda" ]; then
	if [ -e "$TMPDIR/dev" ]; then
		for ((i=0; i<8; i++))
		do
			let=$(echo $i|tr '0-7' 'a-z')
			mknod $TMPDIR/dev/ubd$let b 98 $[16 * $i]
			for ((p=1; p<=16; p++)) do
				mknod $TMPDIR/dev/ubd$let$p b 98 $[16 * $i + $p]
			done
		done
	else
		echo "/dev not found!"
		exit 1
	fi
fi
# basic devices so we can boot without an initrd:
cp -avpr /dev/console /dev/null /dev/zero $TMPDIR/dev
mkdir $TMPDIR/dev/pts

# copy current resolv
cp /etc/resolv.conf $TMPDIR/etc

# use yum to update the system
mount -t proc none $TMPDIR/proc
echo "/dev/ROOT	/ ext3 rw 0 0" > $TMPDIR/etc/mtab
$CHROOTCMD $TMPDIR rpm --rebuilddb
$CHROOTCMD $TMPDIR yum update

# tweak the inittab to only use tty0 and add it to securetty
tweaked=`grep tty0 $TMPDIR/etc/inittab | wc -l`
if [ "$tweaked" -eq "0" ]; then
	cp $TMPDIR/etc/inittab $TMPDIR/etc/inittab.save
	grep -v "mingetty" $TMPDIR/etc/inittab.save > $TMPDIR/etc/inittab
	echo "# We launch just one console on tty0:" >> $TMPDIR/etc/inittab
	echo "c0:1235:respawn:/sbin/mingetty tty0 --noclear" >> $TMPDIR/etc/inittab
	echo "tty0" >> $TMPDIR/etc/securetty

	# For uml change ctrl-alt-del to shutdown instead of reboot
	sed -i -e "s%/sbin/shutdown -t3 -r%/sbin/shutdown -t3 -h %" $TMPDIR/etc/inittab
fi

#enable shadow passwords
chroot $TMPDIR pwconv

#Remove the root password
sed -i -e "s/^root:\*:/root::/" $TMPDIR/etc/shadow

# We need an /etc/hosts file!
echo "127.0.0.1		localhost	localhost.localdomain" > $TMPDIR/etc/hosts

# make the first network interface start with dhcp
# Use ifcfg-eth0 from currrent directory if we have it, otherwise create
$CHROOTCMD $TMPDIR yum install dhclient
if [ ! -f "ifcfg-eth0" ]; then
    echo "DEVICE=eth0" >> $TMPDIR/ifcfg-eth0
    echo "BOOTPROTO=dhcp" >> $TMPDIR/ifcfg-eth0
    echo "ONBOOT=yes" >> $TMPDIR/ifcfg-eth0
else
    cp "ifcfg-eth0"  $TMPDIR/ifcfg-eth0
fi
cp $TMPDIR/ifcfg-eth0 $TMPDIR/etc/sysconfig/networking/devices/ifcfg-eth0
cp $TMPDIR/ifcfg-eth0 $TMPDIR/etc/sysconfig/networking/profiles/default/ifcfg-eth0
mv $TMPDIR/ifcfg-eth0 $TMPDIR/etc/sysconfig/network-scripts/ifcfg-eth0
echo "NETWORKING=yes" > $TMPDIR/etc/sysconfig/network
echo "HOSTNAME=localhost.localdomain" >> $TMPDIR/etc/sysconfig/network

# clear specific settings:
echo "" > $TMPDIR/etc/resolv.conf

# clear rest of image
dd if=/dev/zero of=$TMPDIR/blank >& /dev/null
sync
rm $TMPDIR/blank

umount $TMPDIR/proc
umount $TMPDIR
rmdir $TMPDIR
echo "Done!"
