#!/bin/sh

# Usage: make-chroot SUITE ARCH

# Constructs a chroot environment for the Debian/Ubuntu version SUITE
# and architecture ARCH, and sets up schroot configuration for it.
# Assumes an approx cache is running at localhost:9999.

DEBUG=0
BZ2=0
TYPE=overlayfs
while getopts 'dzot' opt; do
    case "$opt" in
	d)
	    DEBUG=1
	    set -x
	    ;;
	z)
	    BZ2=1;;
	o)
	    TYPE=overlayfs;;
	t)
	    TYPE=tar;;
    esac
done
shift $((OPTIND-1))

if [ $BZ2 -eq 1 ] && [ "$TYPE" != "tar" ]; then
    echo "-z is meaningless if not using a tar chroot and will be ignored" >&2
fi

if [ -z "$1" ] || [ -z "$2" ]; then
    echo "Usage: $0 <suite> <arch>" >&2
    exit 1
fi

set -e

: ${VG=/dev/builder}
: ${CHROOTDIR=/srv}
: ${MIRRORHOST=localhost:9999}
: ${DATA="/usr/share/debathena-build-server"}
# This used to include its own copy of the key, we now just use the
# one from archive-keyring
: ${APTKEY="/usr/share/keyrings/debathena-archive-keyring.gpg"}
if [ ! -d "$DATA" ]; then
    DATA="$(dirname "$0")"
    echo "WARNING: Falling back to DATA=$DATA" >&2
fi
SUITE=$1
ARCH=$2
CHROOT="${SUITE}-${ARCH}-sbuild"
DEVICE="$VG/$CHROOT"
FILE="$CHROOTDIR"/"$CHROOT".tar
[ $BZ2 -eq 1 ] && FILE="${FILE}.bz2"
SIZE=4G

exittrap() { :; }
for sig in 1 2 13 15; do trap "exit $(($sig + 128))" $sig; done
trap 'exittrap' EXIT

if fgrep -qxRs "[$CHROOT]" /etc/schroot/schroot.conf /etc/schroot/chroot.d; then
	echo "Chroot $CHROOT config already exists." >&2
	exit 1
fi
if [ "$TYPE" = "tar" ] && [ -e "$FILE" ]; then
	echo "Chroot tarball $FILE already exists." >&2
	exit 1
fi

if [ "$TYPE" = "overlayfs" ] && lvdisplay $DEVICE > /dev/null 2>&1; then
	echo "LV $DEVICE already exists." >&2
	exit 1
fi

if [ -d /etc/schroot/chroot.d ]; then
	CONF=/etc/schroot/chroot.d/$CHROOT
else
	CONF=/etc/schroot/schroot.conf
fi

if [ "$ARCH" = "i386" ]; then
	PERSONALITY=linux32
elif [ "$ARCH" = "amd64" ]; then
	PERSONALITY=linux
else
	echo "Unrecognized architecture $ARCH." >&2
	exit 1
fi

SOURCESD="$DATA/sources.list.d"
if [ -e "$SOURCESD/debian/$SUITE.list" ]; then
	SOURCES="$SOURCESD/debian/$SUITE.list"
	MIRROR="http://$MIRRORHOST/debian"
elif [ -e "$SOURCESD/ubuntu/$SUITE.list" ]; then
	SOURCES="$SOURCESD/ubuntu/$SUITE.list"
	MIRROR="http://$MIRRORHOST/ubuntu"
else
	echo "Unrecognized suite $SUITE. (Did you create the sources.list file?)" >&2
	exit 1
fi

if [ "$TYPE" = "overlayfs" ]; then
    lvcreate --size "$SIZE" --name "$CHROOT" "$VG"
    mkfs.ext3 "$DEVICE"
    tune2fs -c 0 -i 0 "$DEVICE"
fi

exittrap() { 
    if [ $DEBUG -ne 1 ]; then
	rm -rf "$TMPDIR" || :
    else
	echo "DEBUG MODE: Clean up $TMPDIR by hand!"
    fi
}
TMPDIR=$(mktemp -d /var/tmp/make-chroot.XXXXXX)
SCRIPTCFG="debathena/config"
if [ "$TYPE" = "overlayfs" ]; then
    TARGET="$TMPDIR"
    mount "$DEVICE" "$TARGET"
else
    TARGET="$TMPDIR/root"
fi
debootstrap --variant=buildd --include=apt,apt-utils,gnupg,build-essential,fakeroot --arch "$ARCH" "$SUITE" "$TARGET" "$MIRROR"
install -m a=rx,u+w "$DATA/policy-rc.d" "$TARGET/usr/sbin/"
mkdir -p "$TARGET/dev/pts"
# /dev/shm is a symlink to /run/shm on modern distros 
# So if it's not a symlink, then mkdir (and fail if it's something
# that's not a symlink or a directory) and we have to use an schroot 
# config that bind-mounts /run/shm instead of /dev/shm
if [ -L "$TARGET/dev/shm" ] &&
   [ "$(readlink "$TARGET/dev/shm")" = "/run/shm" ]; then
    SCRIPTCFG="debathena/config-slash-run"
else
    mkdir -p "$TARGET/dev/shm"
fi
mkdir -p "$TARGET/afs"
mkdir -p "$TARGET/mit"
if [ "$TYPE" = "overlayfs" ]; then
    umount "$TARGET"
    rmdir "$TARGET"
else
    TAROPTS="cf"
    [ $BZ2 -eq 1 ] && TAROPTS="cjf"
    (cd "$TMPDIR" && tar "$TAROPTS" "$FILE" --numeric-owner root)
    rm -rf "$TMPDIR"
fi
exittrap() { :; }

! [ -s "$CONF" ] || echo >> "$CONF"
if [ "$TYPE" = "overlayfs" ]; then
    cat >> "$CONF" <<EOF
[$CHROOT]
type=block-device
union-type=overlayfs
description=$CHROOT
groups=root,sbuild
root-groups=root,sbuild
source-groups=root
script-config=$SCRIPTCFG
device=$DEVICE
personality=$PERSONALITY
EOF
else
    cat >> "$CONF" <<EOF
[$CHROOT]
type=file
description=$CHROOT
groups=root,sbuild
root-groups=root,sbuild
source-groups=root
script-config=$SCRIPTCFG
file=$FILE
location=/root
personality=$PERSONALITY
EOF
fi

schroot --chroot="${CHROOT}-source" --directory=/ -- /bin/sh -xe - \
    8< "$SOURCES" \
    9< "$APTKEY" \
    <<EOF
#/debootstrap/debootstrap --second-stage
dpkg-divert --local --rename --add /sbin/initctl
ln -s /bin/true /sbin/initctl
debconf-set-selections <<SELECTIONS
debconf	debconf/frontend	select	Noninteractive
SELECTIONS
sed "s|MIRRORHOST|$MIRRORHOST|" <&8 > /etc/apt/sources.list
! type apt-key >/dev/null || apt-key add - <&9
apt-get -q -y update
apt-get -q -y dist-upgrade
EOF
echo "Done: $CHROOT created successfully."
exit 0