#! /bin/sh -e
#
# $Id: qemu-make-debian-root 353 2008-10-16 20:28:22Z aurel32 $
#
# Script to make a debian root image.
#

set -e

which uudecode >/dev/null || {
    echo "error: missing sharutils package" >&2
    exit 1
}

which debootstrap >/dev/null || {
    echo "error: missing debootstrap package" >&2
    exit 1
}

KEEPFS=0
SPARSE=0

while :; do
    case "$1" in
        -k)
            KEEPFS=1
            ;;
        -s)
            SPARSE=1
            ;;
        -ks|-sk)
            KEEPFS=1
            SPARSE=1
            ;;
        *)
            break
            ;;
    esac
    shift
done

if [ $# -lt 4 ]; then
    echo Usage: "$0 [-ks] size-in-MB distrib deburl image [files_to_copy_in_/root]" >&2
    echo "eg $0 150 sid http://proxy:10000/debian qemu" >&2
    echo "-k keep file system          -s sparse image" >&2
    echo "$0 is normally run as root." >&2
    exit 1
fi

SIZE=$1
DISTRO=$2
URL=$3
IMAGE=$4
shift 4

# now files to copy are in "$@".  We don't put them in a variable
# because that would coufuse spaces-in-filenames with
# whitespace-separation.


if [ $SIZE -lt 130 ]; then
    echo 'Size must be at least 130 megabytes (Debian unstable takes 100)' >&2
    exit 1
fi

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

trap cleanup EXIT

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

# Create a filesystem: one track for partition table.
if [ "$SPARSE" = "1" ]; then
    dd bs=$(($SECTORS * 512)) if=/dev/zero of=$IMAGE.ext2 count=1 seek=$(($CYLINDERS * $HEADS - 2))
else
    dd bs=$(($SECTORS * 512)) if=/dev/zero of=$IMAGE.ext2 count=$(($CYLINDERS * $HEADS - 1))
fi

mke2fs -q -m1 -F $IMAGE.ext2

TMP_DIR="$(mktemp -d /tmp/mount.XXXXXX)" || \
         { echo >&2 "Failed to create temporary directory"; exit 1; }

# Mount it.
mount -o loop $IMAGE.ext2 $TMP_DIR

# Do debian install on it.
debootstrap --variant=minbase $DISTRO $TMP_DIR $URL

# Final configuration.
cat > $TMP_DIR/etc/fstab <<EOF
/dev/hda1 / ext2 errors=remount-ro 0 1
proc /proc proc defaults 0 0
EOF

# Console on ttyS0, not tty1, and no other gettys.
sed 's,1:2345:respawn:/sbin/getty 38400 tty1,1:2345:respawn:/sbin/getty 38400 ttyS0,' < $TMP_DIR/etc/inittab | sed 's,^.:23:respawn.*,,' > $TMP_DIR/etc/inittab.new
mv $TMP_DIR/etc/inittab.new $TMP_DIR/etc/inittab

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

# Create /etc/shadow
chroot $TMP_DIR pwconv

# Set root password to "root"
sed 's/^root:[^:]*/root:$1$aybpiIGf$cB7iFDNZvViQtQjEZ5HFQ0/' < $TMP_DIR/etc/shadow > $TMP_DIR/etc/shadow.new
mv $TMP_DIR/etc/shadow.new $TMP_DIR/etc/shadow

# Remove packages we don't need
chroot $TMP_DIR /usr/bin/dpkg --remove console-common console-tools console-data base-config man-db manpages
# Try to remove all libraries: some won't be removable.
chroot $TMP_DIR dpkg --remove `chroot $TMP_DIR dpkg --get-selections | sed -n 's/^\(lib[^ \t]*\)[\t ]*install/\1/p'` 2>/dev/null || true


# Copy wanted files to /root if asked to
if [ $# -gt 0 ]; then
    cp -a "$@" $TMP_DIR/root/
fi
umount -d $TMP_DIR

# 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
dd if=$IMAGE.ext2 of=$IMAGE seek=$((`stat -c%s $IMAGE` / 512)) bs=512
rm $IMAGE.ext2

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

trap "" EXIT

echo Done.
