#!/bin/bash

show_help() {
  c="  `basename $0`"
  echo "Usage:"
  echo "$c help				# this help"
  echo "$c restart name			# restart"
  echo "$c shutdown name		# shutdown and sync"
  echo "$c start name			# sync and start"
  echo "$c rename name newname		# rename guest"
  echo "$c migrate name host [--live]	# live migrate to host"
  echo "$c move name host [newname]	# offline move guest"
  echo "$c list [--all]			# list guests"
  echo "$c edit name			# edit guest"
  echo "$c console|con|c name		# console for guest"
  exit 0
}

shutdown_and_restart() {
  set -x
  virsh shutdown $1
  virsh console $1

  sleep 1s
  sync
  echo 3 > /proc/sys/vm/drop_caches
  sync

  if [ "$2" = "restart" ]; then
    sleep 3s
    virsh start $1 --console
    exit 0
  fi

  sleep 5s
  sync
  echo 3 > /proc/sys/vm/drop_caches
}

start_guest() {
  set -x
  sync
  echo 3 > /proc/sys/vm/drop_caches
  sync
  sleep 1s
  
  virsh start $1 --console
}

rename_guest() {
  TMP=`mktemp`
  virsh dumpxml $1 > $TMP
  sed -i "s|<name>$1</name>|<name>$2</name>|" $TMP
  virsh undefine $1
  virsh define $TMP
  rm -f $TMP
}

move_guest() {
  virsh shutdown $1
  virsh console $1
  echo 3 > /proc/sys/vm/drop_caches
  sync
  if [ "$3" ]; then
    M="$3"
  else
    M="$1"
  fi
  ssh root@$2 virsh start $M --console
}

virsh_list() {
  DOM_IDS=`virsh list $1 | awk '/^ *[0-9-]/ { print $2 }'`
  for domain in $DOM_IDS; do
    virsh dumpxml $domain
  done | awk -F"[<>]" '
    BEGIN {
      sum_memory = 0;
      sum_current = 0;
      printf("%-20s  %16s  %16s  %7s  %9s\n",
             "Name", "Memory", "Current Memory", "Running", "Autostart")
    }
    /^<domain / { running = "no" }
    /^<domain .* id=/ { running = "YES" }
    /^ +<name>/ {
      name = $3;
      fn = "/etc/libvirt/qemu/autostart/" name ".xml";
      astart = "";
      getline astart <fn;
      if (astart!="") {
        autostart = "YES";
      } else {
        autostart = "no";
      }
    }
    /^ +<memory>/ { memory = $3; sum_memory += $3 }
    /^ +<currentMemory>/ {
      current = $3;
      sum_current += $3;
      printf("%-20s %14.2f MB %14.2f MB  %7s  %9s\n",
             name, memory/1024, current/1024, running, autostart)
    }
    END {
      printf("----------------------------------------------------------------------------\n");
      printf("%-20s %14.2f MB %14.2f MB\n",
             "TOTAL:", sum_memory/1024, sum_current/1024)
    }'
}

if [ "${1::2}" == "--" ]; then
  CMD="${1:2}"
else
  CMD="$1"
fi

if [ "$CMD" = "list" ]; then
  virsh_list "$2"
elif [ -z "$2" ]; then
  show_help
elif [ "$CMD" = "restart" -o "$CMD" = "reboot" ]; then
  shutdown_and_restart $2 restart
elif [ "$CMD" = "shutdown" ]; then
  shutdown_and_restart $2
elif [ "$CMD" = "start" ]; then
  start_guest $2
elif [ "$CMD" = "rename" ]; then
  shift
  rename_guest "$@"
elif [ "$CMD" = "move" ]; then
  move_guest "$@"  
elif [ "$CMD" = "migrate" ]; then
  virsh migrate $4 $2 qemu+ssh://root@$3/system
elif [ "$CMD" = "edit" ]; then
  shift
  virsh edit "$@"
elif [ "$CMD" = "console" -o "$CMD" = "con" -o "$CMD" = "c" ]; then
  shift
  virsh console "$@"
else
  show_help
fi
