#!/bin/sh

# (C) Copyright Canonical 2011,2012

# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.

# This library 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
# Lesser General Public License for more details.

# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

set -e

usage() {
    echo "usage: lxc-shutdown -n name [-w] [-r]"
    echo "  Cleanly shut down a container."
    echo "  -w: wait for shutdown to complete."
    echo "  -r: reboot (ignore -w)."
    echo "  -t timeout: wait at most timeout seconds (implies -w), then kill"
    echo "              the container."
}

alarm() {
    trap 'exit 0' TERM
    pid=$1
    timeout=$2
    sleep $timeout
    kill $pid
}

dolxcstop()
{
    echo "Calling lxc-stop on $lxc_name"
    lxc-stop -n $lxc_name
    exit 0
}

usage_err() {
    [ -n "$1" ] && echo "$1" >&2
    usage
    exit 1
}

optarg_check() {
    [ -n "$2" ] || usage_err "option '$1' requires an argument"
}

timeout="-1"

reboot=0
dowait=0

while [ $# -gt 0 ]; do
    opt="$1"
    shift
    case "$opt" in
    -h|--help)
        usage
        exit 0
        ;;
    -n|--name)
        optarg_check $opt "$1"
        lxc_name=$1
        shift
        ;;
    -w|--wait)
        dowait=1
        ;;
    -r|--reboot)
        reboot=1
        ;;
    -t|--timeout)
        optarg_check $opt "$1"
        timeout=$1
        dowait=1
        shift
        ;;
    --)
        break;;
    -?)
        usage_err "unknown option '$opt'"
        ;;
    -*)
        # split opts -abc into -a -b -c
        set -- $(echo "${opt#-}" | sed 's/\(.\)/ -\1/g') "$@"
        ;;
    *)
        usage_err "unknown option '$opt'"
        exit 1
        ;;
    esac
done

if [ -z "$lxc_name" ]; then
    echo "no container name specified"
    usage
    exit 1
fi

if [ "$(id -u)" != "0" ]; then
   echo "This command has to be run as root"
   exit 1
fi

which lxc-info > /dev/null 2>&1 || { echo "lxc-info not found."; exit 1; }
which lxc-wait > /dev/null 2>&1 || { echo "lxc-wait not found."; exit 1; }

pid=`lxc-info -n $lxc_name -p 2>/dev/null | awk '{ print $2 }'`
if [ "$pid" = "-1" ]; then
    echo "$lxc_name is not running"
    exit 1
fi

if [ $reboot -eq 1 ]; then
    kill -s INT $pid
    exit 0
else
    kill -s PWR $pid
fi

if [ $dowait -eq 0 ]; then
    exit 0
fi

if [ $timeout != "-1" ]; then
    trap dolxcstop EXIT
    alarm $$ $timeout 2>/dev/null &
    alarmpid=$!
fi

while ! lxc-info -n $lxc_name --state-is STOPPED; do
    sleep 1
done

if [ $timeout != "-1" ]; then
    trap - EXIT
    # include subprocesses; otherwise, we may have to wait until sleep completes
    # if called from a non-interactive context
    kill $alarmpid $(ps --no-headers --ppid $alarmpid -o pid) 2>/dev/null || :
fi

echo "Container $lxc_name has shut down"

exit 0
