#!/bin/sh

# autopkgtest-build-qemu is part of autopkgtest
# autopkgtest is a tool for testing Debian binary packages
#
# Copyright (C) Antonio Terceiro <terceiro@debian.org>.
#
# Build a QEMU image for using with autopkgtest
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# See the file CREDITS for a full list of credits information (often
# installed as /usr/share/doc/autopkgtest/CREDITS).

set -eu

apt_proxy=
architecture=
mirror=
user_script=
size=

usage () {
  echo "usage: $0 [<options...>] <release> <image> [<mirror>] [<architecture>] [<script>] [<size>]"
  echo ""
  echo "--apt-proxy=http://PROXY:PORT     Set apt proxy [default: auto]"
  echo "--arch=ARCH, --architecture=ARCH  Set architecture, e.g. i386"
  echo "                                  [default: $(dpkg --print-architecture)]"
  echo "--mirror=URL                      Set apt mirror [default:"
  echo "                                  http://deb.debian.org/debian]"
  echo "--script=SCRIPT                   Run an extra customization script"
  echo "--size=SIZE                       Set image size [default: 25G]"
  exit "${1-1}"
}

if getopt_temp="$(
  getopt -o '' \
  --long 'apt-proxy:,arch:,architecture:,help,mirror:,script:,size:' \
  -n "$0" -- "$@"
)"; then
  eval set -- "$getopt_temp"
else
  echo ""
  usage $?
fi

while true; do
  case "$1" in
    (--arch|--architecture)
      architecture="$2"
      shift 2
      ;;

    (--apt-proxy)
      apt_proxy="$2"
      shift 2
      ;;

    (--help)
      usage 0
      ;;

    (--mirror)
      mirror="$2"
      shift 2
      ;;

    (--script)
      user_script="$2"
      shift 2
      ;;

    (--size)
      size="$2"
      shift 2
      ;;

    (--)
      shift
      break
      ;;

    (-*)
      echo "E: Option '$1' not understood"
      exit 2
      ;;

    (*)
      break
      ;;
  esac
done

if [ $# -lt 2 -o $# -gt 6 ]; then
    usage 1
fi

if ! which vmdb2 > /dev/null; then
  echo "E: vmdb2 not found. This script requires vmdb2 to be installed"
  exit 2
fi

release="$1"
image="$2"

if [ $# -ge 3 ]; then
  if [ -n "$mirror" ]; then
    echo "E: --mirror and 3rd positional argument cannot both be specified"
    usage 2
  fi
  mirror="$3"
elif [ -z "$mirror" ]; then
  mirror="http://deb.debian.org/debian"
fi

if [ $# -ge 4 ]; then
  if [ -n "$architecture" ]; then
    echo "E: --arch and 4th positional argument cannot both be specified"
    usage 2
  fi
  architecture="$4"
elif [ -z "$architecture" ]; then
  architecture=$(dpkg --print-architecture)
fi

if [ $# -ge 5 ]; then
  if [ -n "$user_script" ]; then
    echo "E: --script and 5th positional argument cannot both be specified"
    usage 2
  fi
  user_script="$5"
elif [ -z "$user_script" ]; then
  user_script="/bin/true"
fi

if [ $# -ge 6 ]; then
  if [ -n "$size" ]; then
    echo "E: --size and 6th positional argument cannot both be specified"
    usage 2
  fi
  size="$6"
elif [ -z "$size" ]; then
  size="25G"
fi

# detect apt proxy
# support backwards compatible env var too
AUTOPKGTEST_APT_PROXY=${apt_proxy:-${AUTOPKGTEST_APT_PROXY:-${ADT_APT_PROXY:-}}}
if [ -z "$AUTOPKGTEST_APT_PROXY" ]; then
    RES=`apt-config shell proxy Acquire::http::Proxy`
    if [ -n "$RES" ]; then
        eval $RES
    else
        RES=`apt-config shell proxy_cmd Acquire::http::Proxy-Auto-Detect`
        eval $RES
        if [ -n "${proxy_cmd:-}" ]; then
            proxy=`$proxy_cmd`
        fi
    fi
    if echo "${proxy:-}" | egrep -q '(localhost|127\.0\.0\.[0-9]*)'; then
        # set http_proxy for the initial debootstrap
        export http_proxy="$proxy"

        # translate proxy address to one that can be accessed from the
        # running VM
        AUTOPKGTEST_APT_PROXY=$(echo "$proxy" | sed -r "s#localhost|127\.0\.0\.[0-9]*#10.0.2.2#")
        if [ -n "$AUTOPKGTEST_APT_PROXY" ]; then
            echo "Detected local apt proxy, using $AUTOPKGTEST_APT_PROXY as virtual machine proxy"
        fi
    elif [ -n "${proxy:-}" ]; then
        AUTOPKGTEST_APT_PROXY="$proxy"
        echo "Using $AUTOPKGTEST_APT_PROXY as container proxy"
        # set http_proxy for the initial debootstrap
        export http_proxy="$proxy"
    fi
fi
export AUTOPKGTEST_APT_PROXY


script=/bin/true
for s in $(dirname $(dirname "$0"))/setup-commands/setup-testbed \
              /usr/share/autopkgtest/setup-commands/setup-testbed; do
    if [ -r "$s" ]; then
        script="$s"
        break
    fi
done

if [ "$user_script" != "/bin/true" ]; then
  echo "Using customization script $user_script ..."
fi


case "$mirror" in
  *ubuntu*)
    kernel=linux-image-virtual
    ;;
  *)
    case "$architecture" in
      (armhf)
        kernel=linux-image-armmp
        ;;
      (hppa)
        kernel=linux-image-parisc
        ;;
      (i386)
        case "$release" in
          (jessie)
            kernel=linux-image-586
            ;;
          (*)
            kernel=linux-image-686
            ;;
        esac
        ;;
      (ppc64)
        kernel=linux-image-powerpc64
        ;;
      (*)
        kernel="linux-image-$architecture"
        ;;
    esac
    ;;
esac

vmdb2_config=$(mktemp)
trap "rm -rf $vmdb2_config" INT TERM EXIT
cat > "$vmdb2_config" <<EOF
steps:
  - mkimg: "{{ image }}"
    size: $size

  - mklabel: msdos
    device: "{{ image }}"

  - mkpart: primary
    device: "{{ image }}"
    start: 0%
    end: 100%
    tag: root

  - kpartx: "{{ image }}"

  - mkfs: ext4
    partition: root

  - mount: root

  - debootstrap: $release
    mirror: $mirror
    target: root

  - apt: install
    packages:
      - $kernel
      - ifupdown
    tag: root

  - grub: bios
    tag: root
    console: serial

  - chroot: root
    shell: |
      passwd --delete root
      useradd --home-dir /home/user --create-home user
      passwd --delete user
      echo host > /etc/hostname

  - shell: |
      rootdev=\$(ls -1 /dev/mapper/loop* | sort | tail -1)
      uuid=\$(blkid -c /dev/null -o value -s UUID \$rootdev)
      echo "UUID=\$uuid / ext4 errors=remount-ro 0 1" > \$ROOT/etc/fstab
    root-fs: root

  - shell: '$script \$ROOT'
    root-fs: root

  - shell: '$user_script \$ROOT'
    root-fs: root

EOF

vmdb2 \
    --verbose \
    --image="$image".raw \
    "$vmdb2_config"

qemu-img convert -O qcow2 "$image".raw  "$image".new

rm -f "$image".raw

# replace a potentially existing image as atomically as possible
mv "$image".new "$image"
