#!/bin/sh
# adt-setup-vm is part of autopkgtest
# autopkgtest is a tool for testing Debian binary packages
#
# autopkgtest is Copyright (C) 2006-2014 Canonical Ltd.
#
# Setup script for e. g. vmdebootstrap or generic Debian/Ubuntu VM images to
# start a root serial console on ttyS1, set up networking for ethernet, configure
# apt sources, install/clean up packages, etc.
# See adt-virt-qemu(1) for details.
#
# You can set $ADT_APT_PROXY; if set, it will be configured in apt in
# /etc/apt/apt.conf.d/01proxy. If apt-cacher-ng is running on localhost, this
# will be used automatically, unless $ADT_APT_PROXY is set.

set -eu

# Created files should be readable by user adt (this script is called as root)
umask 0022

if [ "${1:-}" = "--help" ]; then
    echo "Usage: $0 [chroot dir]"
    echo "if chroot dir is not given, run on the main system (for running in VMs)"
    exit 0
fi

root=${1:-/}

# set up init script for root shell on ttyS1; necessary for adt-virt-qemu local
# images
cat <<EOF > "$root/etc/init.d/autopkgtest"
#!/bin/sh
### BEGIN INIT INFO
# Provides:          autopkgtest
# Required-Start:    \$all
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:
### END INIT INFO

if [ "\$1" = start ]; then
    echo "Starting root shell on ttyS1 for autopkgtest"
    (setsid sh </dev/ttyS1 >/dev/ttyS1 2>&1) &
fi
EOF

chmod 755 "$root/etc/init.d/autopkgtest"
chroot "$root" update-rc.d autopkgtest defaults

# set up serial console on upstart systems
if [ -e "$root/etc/init/tty2.conf" -a ! -e "$root/etc/init/ttyS0.conf" ]; then
    sed 's/tty2/ttyS0/g; s! *exec.*$!exec /sbin/getty -L ttyS0 115200 vt102!' \
        "$root/etc/init/tty2.conf" > "$root/etc/init/ttyS0.conf"
fi

# serial console for systemd
# bump vmalloc on i386, necessary for tests like udisks2
if chroot "$root" which update-grub >/dev/null 2>&1; then
    mkdir -p "$root/etc/default/grub.d/"
    if [ "$(chroot "$root" dpkg --print-architecture)" = "i386" ]; then
        echo 'GRUB_CMDLINE_LINUX_DEFAULT="console=ttyS0 vmalloc=512M"' > \
            "$root/etc/default/grub.d/90-autopkgtest.cfg"
    else
        echo 'GRUB_CMDLINE_LINUX_DEFAULT="console=ttyS0"' > \
            "$root/etc/default/grub.d/90-autopkgtest.cfg"
    fi
    chroot "$root" update-grub || echo "WARNING: update-grub failed!"
fi

# set up apt sources
mirror_rel=`awk '/^deb .*(debian|ubuntu)/ { print $2,$3; exit }' "$root/etc/apt/sources.list"`
if [ "${mirror_rel%ubuntu*}" != "$mirror_rel" ]; then
    cat << EOF > "$root/etc/apt/sources.list"
deb     $mirror_rel main restricted universe multiverse
deb     ${mirror_rel}-updates main restricted universe multiverse
deb-src $mirror_rel main restricted universe multiverse
deb-src ${mirror_rel}-updates main restricted universe multiverse
EOF
else
    cat << EOF > "$root/etc/apt/sources.list"
deb $mirror_rel main contrib non-free
deb-src $mirror_rel main contrib non-free
EOF
fi
# prevent subsequent cloud-init runs from modifying the apt sources again
if [ -e "$root/etc/cloud/cloud.cfg" ]; then
    mkdir -p "$root/etc/cloud/cloud.cfg.d"
    echo 'apt_preserve_sources_list: true' >> "$root/etc/cloud/cloud.cfg.d/01_autopkgtest.cfg"
fi

# work around https://bugs.debian.org/788792
if ! grep -q 'source.*interfaces.d' "$root/etc/network/interfaces"; then
    echo "Applying local fix for vmdebootstrap bug https://bugs.debian.org/788792..."
    printf "\nsource-directory /etc/network/interfaces.d\n" >> "$root/etc/network/interfaces"
fi

# set up networking
IFACE=""
if [ "$root" = / ] ; then
    # we are already in a VM, so figure out our network
    # device
    if OUT="$(cd /sys/class/net; ls -d e* 2>/dev/null)"; then
        IFACE="${OUT# *}"
    fi
else
    # the kernel will choose eth0 as the interface name, so
    # keep that (and tell udev to not rename the interface,
    # we won't know how it will be called)
    IFACE="eth0"
    if ! [ -e "$root/etc/udev/rules.d/80-net-setup-link.rules" ] ; then
        ln -s /dev/null "$root/etc/udev/rules.d/80-net-setup-link.rules"
    fi
fi
if [ -n "$IFACE" ] ; then
    mkdir -p "$root/etc/network/interfaces.d"
    if ! grep -h -r '^[[:space:]]*auto' "$root/etc/network/interfaces" "$root/etc/network/interfaces.d" | grep -qv 'auto[[:space:]]*lo'; then
        printf "auto $IFACE\niface $IFACE inet dhcp\n" >> "$root/etc/network/interfaces.d/$IFACE"
    fi
fi

# go-faster apt/dpkg
echo "Acquire::Languages \"none\";" > "$root"/etc/apt/apt.conf.d/90nolanguages
echo 'force-unsafe-io' > "$root"/etc/dpkg/dpkg.cfg.d/autopkgtest

# auto-detect apt-cacher-ng
if [ -z "${ADT_APT_PROXY:-}" ]; then
    RES=`apt-config shell proxy Acquire::http::Proxy`
    if [ -n "$RES" ]; then
        eval $RES
        if echo "$proxy" | egrep -q '(localhost|127\.0\.0\.[0-9]*):3142'; then
            ADT_APT_PROXY="http://10.0.2.2:3142"
            # set http_proxy for the initial apt-get update
            export http_proxy="$proxy"
        fi
    fi
fi

# upgrade, install some necessary packages
chroot "$root" apt-get update
[ "${ADT_SETUP_VM_UPGRADE:-}" = false ] || DEBIAN_FRONTEND=noninteractive chroot "$root" apt-get -y dist-upgrade

if [ "${mirror_rel%ubuntu*}" != "$mirror_rel" ]; then
    # provides kmods like scsi_debug or mac80211_hwsim
    chroot "$root" apt-get install -y linux-generic
fi
# some tests use a lot of /dev/random, avoid hangs
chroot "$root" apt-get install -y haveged

# we need Python to run the auxverb helper
if ! chroot "$root" sh -c 'type python3 >/dev/null 2>&1 || type python >/dev/null 2>&1'; then
    chroot "$root" apt-get install -y --no-install-recommends python3-minimal
fi

# clean up some unnecessary packages
for p in accountsservice apt-xapian-index cryptsetup landscape-client \
    landscape-common open-vm-tools w3m vim-runtime aptitude-common \
    command-not-found-data manpages ntfs-3g sosreport \
    ubuntu-release-upgrader-core libcpan-changes-perl git \
    cgmanager lxd-client; do
    chroot "$root" apt-get --auto-remove -y purge $p || true
done

# run post-install commands
if [ -n "${ADT_SETUP_VM_POST_COMMAND:-}" ]; then
    chroot "$root" sh -ec "$ADT_SETUP_VM_POST_COMMAND"
fi

chroot "$root" apt-get clean

# set up apt proxy, if given (this might be an IP which only works in the VM,
# so don't run the previous apt-get with that already)
if [ -n "${ADT_APT_PROXY:-}" ]; then
    echo "Acquire::http { Proxy \"$ADT_APT_PROXY\"; };" > "$root"/etc/apt/apt.conf.d/01proxy
fi
