#! /bin/sh -e
# Script to make a debian root image.
# Written by Rusty Russell, http://lists.gnu.org/archive/html/qemu-devel/2003-07/msg00043.html --jbarnold

set -e

if [ $# -lt 2 ]; then
    echo Usage: "%s imagename [download] [build]" >&2
    exit 1
fi

SIZE="150"
DISTRO="sarge"
#URL="http://ftp.us.debian.org/debian/"
URL="http://debian.lcs.mit.edu/debian/"
IMAGE=$1

if ! which /usr/sbin/debootstrap &> /dev/null; then
    echo "No debootstrap.  Please install debootstrap"
    exit 1
fi
if ! which uudecode &> /dev/null; then
    echo "No uudecode.  Please install sharutils"
    exit 1
fi
if ! which /sbin/sfdisk &> /dev/null; then
    echo "No sfdisk.  Please install util-linux"
    exit 1
fi

cleanup()
{
    echo Cleaning up... >&2
    umount /tmp/mount.$$ || true
    rm -f $IMAGE.ext2 $IMAGE
}

trap cleanup EXIT

debify()
{
    /usr/sbin/debootstrap --include=python2.4 --exclude=syslinux,at,exim4,exim4-base,exim4-config,exim4-daemon-light,mailx,mbr,setserial,fdutils,info,ipchains,iptables,lilo,grub,pcmcia-cs,ppp,pppoe,pppoeconf,pppconfig $*
}

download()
{
    if [ -f packages.tgz ]; then
        echo "packages.tgz already exists.  Delete to allow download"
        exit 0
    fi
    debify --make-tarball packages.tgz $DISTRO packages $URL
}

build()
{
    if [ $EUID -ne 0 ]; then
        echo "Must be run as root (yeah, yeah...)"
        exit 1
    fi
    create_image
    mount_image
    install_debian
    configure
    unmount_image
    fixup_partitions
}

HEADS=16
SECTORS=63
# 512 bytes in a sector: cancel the 512 with one of the 1024s...
CYLINDERS=$(( $SIZE * 1024 * 2 / ($HEADS * $SECTORS) ))

create_image()
{
    echo "Creating image"
    # Create a filesystem: one track for partition table.
    dd bs=$(($SECTORS * 512)) if=/dev/zero of=$IMAGE.ext2 count=$(($CYLINDERS * $HEADS - 1))
    echo "Formatting image"
    /sbin/mke2fs -q -m1 -F $IMAGE.ext2
}

mount_image()
{
    # Mount it.
    mkdir /tmp/mount.$$
    mount -o loop $IMAGE.ext2 /tmp/mount.$$
}

install_debian()
{
    echo "Installing Debian on image"
    # Do debian install on it.
    debify --verbose --unpack-tarball `pwd`/packages.tgz $DISTRO /tmp/mount.$$ $URL
}

configure()
{
    # Remove leftover debian packages from install
    rm /tmp/mount.$$/var/cache/apt/archives/*.deb
    
    echo "Configuring Debian"
    # Final configuration.
    cat > /tmp/mount.$$/etc/fstab <<EOF
/dev/hda1 / ext2 errors=remount-ro 0 1
/dev/hdc /cdrom auto noauto,ro 0 0
tmpfs /tmp tmpfs auto,size=10M,nr_inodes=2k,mode=777 0 0
proc /proc proc defaults 0 0
EOF

    # Console on console (whatever the kernel's using), not tty1, and
    # no other gettys.
    sed 's,1:2345:respawn:/sbin/getty 38400 tty1,cd:2345:wait:/etc/init.d/canopy\n1:2345:respawn:/sbin/getty 38400 console,' < /tmp/mount.$$/etc/inittab | sed 's,^.:23:respawn.*,,' > /tmp/mount.$$/etc/inittab.new
    mv /tmp/mount.$$/etc/inittab.new /tmp/mount.$$/etc/inittab

    # Set hostname to base of image name.
    basename $IMAGE > /tmp/mount.$$/etc/hostname

    # Remove ones we can remove.
    #chroot /tmp/mount.$$ /usr/bin/dpkg --remove console-tools console-data base-config

    # Make devices
    (cd /tmp/mount.$$/dev; /sbin/MAKEDEV generic)

    # Make additional mount-points
    mkdir /tmp/mount.$$/cdrom

    # Install canopy, thttpd, rmtp, etc
    (cd extra; find . -type f | cpio -pd --no-preserve-owner /tmp/mount.$$/)
    dd if=/dev/urandom of=/tmp/mount.$$/random bs=4k count=5000
}

unmount_image()
{
    umount /tmp/mount.$$
    rmdir /tmp/mount.$$
}

fixup_partitions()
{
    echo "Fixing up partitions"
    # Create file with partition table.
    uudecode -o- << "EOF" | gunzip > $IMAGE
begin 664 partition-table.gz
M'XL("*_<##\"`W!A<G1I=&EO;BUT86)L90#LT#$-`"`0!,&']D6A`D6XP1T&
M"%B@))FIMKGF(OA9C;%;EENYZO.Z3P\"````!P``__\:!0````#__QH%````
M`/__&@4`````__\:!0````#__QH%`````/__&@4`````__\:!0````#__QH%
M`````/__&@4`````__\:!0````#__QH%`````/__&@4`````__\:!0````#_
M_QH%`````/__&@4`````__\:!0````#__QH%`````/__&@4`````__\:!0``
M``#__QH%`````/__&@4`````__\:!0````#__QH%`````/__&@4`````__\:
M!0````#__QH%`````/__&@4`````__\:!0````#__QH%`````/__&@4`````
M__\:!0````#__QH%`````/__&@4`````__\:!0````#__QH%`````/__&@4`
M````__\:!0````#__QH%`````/__&@4`````__\:!0````#__QH%`````/__
M&@4`````__\:!0````#__QH%`````/__&@4`````__\:!0````#__QH%````
M`/__&@4`````__\:!0````#__QH%`````/__&@4`````__\:!0````#__QH%
M`````/__&@4`````__\:!0````#__QH%`````/__&@4`````__\:!0````#_
M_QH%`````/__&@4`````__\:!0````#__QH%`````/__&@4`````__\:!0``
M``#__QH%`````/__&@4`````__\:!0````#__QH%`````/__&@4`````__\:
M!0````#__QH%`````/__&@4`````__\:!0````#__QH%`````/__&@4`````
M__\:!0````#__QH%`````/__&@4`````__\:!0````#__QH%`````/__&@4`
M````__\:!0````#__QH%`````/__&@4`````__\:!0````#__QH%`````/__
M&@4`````__\:!0````#__QH%`````/__&@4`````__\:!0````#__QH%````
M`/__&@4`````__\:!0````#__QH%`````/__&@4`````__\:!0````#__QH%
M`````/__&@4`````__\:!0````#__QH%`````/__&@4`````__\:!0````#_
M_QH%`````/__&@4`````__\:!0````#__QH%`````/__0@``````__\#`%&_
&<90`?@``
`
end
EOF
    cat $IMAGE.ext2 >> $IMAGE
    rm $IMAGE.ext2

    # Repartition so one partition covers entire disk.
    echo '63,' | /sbin/sfdisk -uS -H$HEADS -S$SECTORS -C$CYLINDERS $IMAGE
}

shift
while [ ! -z $1 ]; do
    if [ x$1 == xdownload ]; then
        download
    elif [ x$1 == xbuild ]; then
        build
    else
        echo "Unknown action $1"
        exit 1
    fi
    shift
done

trap "" EXIT

echo Done.
