#!/bin/sh
#
# Copyright (C) 2007-2009 Canonical, Ltd.
# Author: Jamie Strandboge <jamie@canonical.com>
# License: GPLv3
#
# Simple starter script for when virt-manager won't do
#
set -e

ustconf="$HOME/.uqt-vm-tools.conf"
if [ -s "$ustconf" ]; then
    . "$ustconf"
else
    echo "Could not find '$ustconf'"
    exit 1
fi

. $UQT_VM_TOOLS/libvm.sh
abort_if_root

help() {
    cat << EOM
Usage:	vm-stop [-f] <vm1> <vm2>
	vm-stop [-u] <vm1> <vm2>
	vm-stop [-f] -p PREFIX [-a ARCH]
	vm-stop [-u] -p PREFIX [-a ARCH]

 -f	destroy rather than gracefully shutdown (removes snapshots)
 -u	update the snapshots (implies graceful shutdown)

Using vm-stop without '-f' performs a graceful shutdown and leaves any
existing snapshots intact.
EOM
}

stop_machine() {
    command="$1"
    machine="$2"
    if ! vm_exists $machine ; then
        echo "'$i' does not exist"
        return
    fi

    if ! vm_running $machine ; then
        echo "'$machine' is not running"
        return
    fi

    virsh --connect ${vm_connect} $command "$machine" || return
    sent="yes"

    disks=`get_disks $machine`
    if [ -z "$disks" ]; then
        echo "WARN: Could not find any disks" >&2
        return
    fi

    for d in $disks; do
        real=`readlink -f "$d"`
        dir=`dirname "$real"`
        bn=`basename "$real" .qcow2`
        pristine="$dir/$bn.pristine.qcow2"

        if ! echo "$real" | egrep -q '.qcow2$' ; then
            #echo "DEBUG: File extension for '$real' is not 'qcow2'. Skipping" >&2
            continue
        fi
        if echo "$real" | egrep -q '.pristine.qcow2$' ; then
            echo "Skipping '$real'" >&2
            continue
        fi
        if [ -e "$pristine" ] && [ -e "$real" ]; then
            if [ "$command" = "destroy" ]; then
                rm -f "$real"
            elif [ "$update_snapshots" = "yes" ]; then
                if vm_can_snapshot $machine ; then
                    count=0
                    do_commit="no"
                    echo "INFO: waiting for '$machine' to shutdown" >&2
                    while [ "$count" -lt "$timeout" ]; do
                        if vm_running "$machine" ; then
                            sleep 1
                            count=$(( $count + 1 ))
                            continue
                        else
                            do_commit="yes"
                            break
                        fi
                    done
                    if [ "$do_commit" = "yes" ]; then
                        echo "INFO: committing changes to '$pristine'" >&2
                        qemu-img commit "$real"
                        echo "INFO: removing '$real'" >&2
                        rm -f "$real"
                    else
                        echo "Could not perform commit ('$machine' didn't shutdown)" >&2
                        echo "Please commit snapshot for all disks manually. Eg:" >&2
                        echo "  qemu-img commit \"$real\"" >&2
                        echo "" >&2
                    fi
                else
                    echo "Cannot update snapshots. Skipping commit" >&2
                fi
            fi
        else
            #echo "DEBUG: One of '$pristine' or '$real' is missing. Skipping" >&2
            continue
        fi
    done
}

sent=
command="shutdown"
arch=
prefix=
update_snapshots="no"
timeout=90
while getopts "hfua:p:" opt
do
    case "$opt" in
        a) arch="$OPTARG";;
        f) command="destroy";;
        p) prefix="$OPTARG";;
        u) update_snapshots="yes";;
        ?|h) help
           exit 1
           ;;
    esac
done
shift $(($OPTIND - 1))

if [ "$command" = "destroy" ] && [ "$update_snapshots" = "yes" ]; then
    echo "'-f' and '-u' are mutually exclusive" >&2
    help
    exit 1
fi

if [ -z "$prefix" ]; then
    if [ -z "$1" ]; then
        help
        exit 1
    fi

    for i in "$@" ; do
        stop_machine $command "$i"
    done
else
    archs="$vm_archs"
    if [ ! -z "$arch" ]; then
        archs="$arch"
    fi

    for a in $archs ; do
        for m in `vm_get_machines_by_prefix "${prefix}" "$a"` ; do
            stop_machine $command "$m"
        done
    done
fi

if [ "$sent" = "yes" ] && [ "$command" = "shutdown" ]; then
    echo ""
    echo "Note: if virtual machine has a user that is logged into a desktop,"
    echo "the desktop user may need to confirm the shutdown operation."
fi

exit 0
