#!/bin/bash
# Function:
# - Control KVM Virtual Machine setup
#
# Usage
# - See help text
#
# Notes
# -
#
# TODO
# -
#
#  (c) 2021 Robert Lange (sd2k9@sethdepot.org)
#  GNU General Public Licence applies
#
#  Project URL: https://github.com/sd2k9/documentation

# ------------------------------------------------------------------------------

# *** Settings and Variables ***
# Treat uninitialised variable as error and exit script
set -u
# Test mode: True when defined (only echo commands)
declare TESTMODE
# Program name
readonly PRGNAME=${0##*/}
# VM for starting etc.
readonly VMNAME="Windows_10"
# Mode, selected from command line
declare mode=""
# Function return value
declare RETURNVAL

# ------------------------------------------------------------------------------

# *** Functions ***
# Load shared functions
readonly EXEC_DO_NO_ABORT_ON_ERROR=false
source ${BASH_SOURCE[0]%/*}/public/bash-functions

# *** Help Text
function help_text() {
cat<<EOF
Prepare or Stop VM service

Usage: $PRGNAME [opts] mode
Mode
  start: Start services, network and firewall local routing
  startnet: Same as start with internet routing
  localnet: Reconfigure firewall for local routing
  internet: Reconfigure firewall for internet routing
  stop: Stop services, network and firehol routing

  netup: Connect network cable on virtual machine
  netdown: Disconnect network cable from virtual machine

  vmstart: Start and display VM $VMNAME

Options
  -t, --test, --dry-run: Dry run, only echo commands
  -V|--version: Program version
  -h, --help, -?: Help text

Notes:
- A lot of stuff is hardcoded in the script or settings


EOF
}

# *** Print Versionstring
function versionstring () {
declare -r VER=0.1.0
cat<<EOF
$PRGNAME version $VER
(c) by Robert Lange (sd2k9@sethdepot.org)
Licensed under the GNU General Public License

EOF
}

# *** Return running domain name - error when not one
function domain_running() {
    # Domain names
    declare -a domains
    # True: Found at least one domain
    local found=0
    while IFS='\n' read -r lin; do
	# Ignore empty lines, otherwise add to array
	if [[ -n "$lin" ]]; then
	    found=1
	    domains+=("$lin")
	fi
    done < <(virsh --connect=qemu:///system list --name --state-running)
    if [[ $found -eq 0 ]] ; then
       echo "No running domain found!"
       exit 1
    elif [[ ${#domains[@]} -ne 1 ]]; then
       echo "Expected one running domain, got ${#domains[@]} (${domains[@]})!"
       exit 1
    fi
    RETURNVAL="${domains[0]}"
}

# ------------------------------------------------------------------------------

# *** Command line parsing
get_options() {
  local opt

  while [ -n "$*" ] ; do
      opt="$1"
      shift
      case $opt in
          -t|--test|--dry-run)
          # Test Mode
       	  TESTMODE=1
      	  ;;
          -V|--version)
          # Version output
          versionstring
          exit 0
          ;;
          -h|--help|'-?')
          # Hilfetext
          versionstring
	  help_text
          exit 0
        ;;
        start|startnet|localnet|internet|stop|netup|netdown|vmstart)
	  if [[ -n $mode ]]; then
  	     echo "Multiple mode statements! See help text for usage"
   	     exit 1
	  fi
	  mode="$opt"
        ;;
        *)
           # Unknown Argument
  	   echo "Unknown argument \"$opt\"! See help text for usage"
   	   exit 1
  	;;
      esac
  done
}


# *** Call Command Line Parsing and Program execution
# When no options supplied then call help
if [ -z "${1:-}" ]; then
    get_options "--help"
else
    get_options "$@"
fi


# ------------------------------------------------------------------------------

# *** Now execute actions, or done above
case $mode in
  start|startnet)
      echo "Starting KVM Services and Virsh Network"
      exec_tool sudo /usr/local/sbin/kvm_services start
      exec_tool virsh --connect=qemu:///system net-start default
      if [[ "$mode" == "start" ]]; then
	  echo "Reconfigure firewall for local routing"
	  exec_tool sudo /usr/local/sbin/kvm_services localnet
      else
	  echo "Reconfigure firewall for internet routing"
	  exec_tool sudo /usr/local/sbin/kvm_services internet
      fi
  ;;
  localnet|internet)
      echo "Reconfigure firewall for $mode"
      exec_tool sudo /usr/local/sbin/kvm_services $mode
  ;;
  stop)
      echo "Stopping KVM Services, Virsh Network and Firewall "
      exec_tool virsh --connect=qemu:///system net-destroy default
      exec_tool sudo /usr/local/sbin/kvm_services stop
      exec_tool sudo /usr/local/sbin/kvm_services stopnet
  ;;
  netup|netdown)
      netmode=${mode#net}
      echo "Network cable $netmode (up: Plug cable, down: Pull cable)"
      domain_running    # Get running domain in variable RETURNVAL
      exec_tool virsh --connect=qemu:///system domif-setlink \
		"$RETURNVAL" vnet0 $netmode
      unset netmode
  ;;
  vmstart)
      echo "Start and display VM $VMNAME"
      exec_tool virsh --connect=qemu:///system start \"${VMNAME}\"
      exec_tool virt-manager --connect=qemu:///system  --show-domain-console \"${VMNAME}\"
  ;;
  *)
      # No mode
      echo "No mode selected! See help text for usage"
      exit 1
  ;;
esac


# *** Do whatever you should do
# All done already above


# *** Done
echo
echo "Done"
