#!/bin/bash
#
# Script to update network-disconnected templates via an update-vm in a big batch
#



# Set the default VM for downloading updates

DEFAULT_UPDATEVM=$"update-vm"


# Set VM for downloading updates

if [ "$1" == "" ]; then
  UPDATEVM=$DEFAULT_UPDATEVM

else
  UPDATEVM=$1

fi


# Get a list of all templates (or just Debian, or just minimal, etc.)

TEMPLATES=$(qvm-ls | grep Tpl | awk {'print $1'} | cut -d[ -f2 | cut -d] -f1)

#TEMPLATES=$(qvm-ls | grep debian | grep Tpl | awk {'print $1'} | cut -d[ -f2 | cut -d] -f1)
#TEMPLATES=$(qvm-ls | grep minimal | grep Tpl | awk {'print $1'} | cut -d[ -f2 | cut -d] -f1)


usage()
{
cat << EOF
usage: $0 <VM-name>

This script will perform software updates on all supported network-disconnected template images using a separate VM for retrieving updates.

If no VM is specified, then $DEFAULT_UPDATEVM will be used.

Currently only Fedora and Debian-based templates are supported.

Whonix templates, although Debian-based, are not supported,
because there is the chance that Tor is not connected yet.

Windows templates are also not supported at this time.
EOF
}


# Parse arguments

while getopts ":h" OPTION
do
  case $OPTION in
    h)
      usage
      exit
      ;;
    ?)
      usage
      exit 1
      ;;
  esac
done


echo "   ***   Using this VM as the VM for retrieving updates: $UPDATEVM"


# Get the UPDATEVM's original template (for dom0 updates)

UPDATEVM_ORIGTEMP=$(qvm-ls | grep $UPDATEVM | awk {'print $8'} | cut -d[ -f2 | cut -d] -f1)

# Get the UPDATEVM's original template (for dom0 updates) if VM is running

if [ $UPDATEVM_ORIGTEMP == "|" ]; then
  UPDATEVM_ORIGTEMP=$(qvm-ls | grep $UPDATEVM | awk {'print $9'} | cut -d[ -f2 | cut -d] -f1)
fi

echo "   ***   Reading $UPDATEVM's original template: $UPDATEVM_ORIGTEMP"


for template in ${TEMPLATES[@]}; do
  echo "   ***   Attempting to update the $template template via $UPDATEVM..."

  # Check if the template is a Whonix template (assuming default naming scheme)

  if [[ $template == *"whonix"* ]]; then
    echo "   ***   Skipping $template.  Please update Whonix templates manually."

  # Check if the template is a Windows template (assuming generic naming scheme)

  elif [[ $template == *"win7"* ]]; then
    echo "   ***   Skipping $template.  Please update Windows templates manually."

  elif [[ $template == *"win8"* ]]; then
    echo "   ***   Skipping $template.  Please update Windows templates manually."

  elif [[ $template == *"windows"* ]]; then
    echo "   ***   Skipping $template.  Please update Windows templates manually."

  else

# to prevent starting each template if naming scheme is default
#   # Attempt to detect whether this is a Debian system
#   qvm-run -u root -a --nogui -p $template "test -f /etc/debian_version"
#   if [ $? -eq 0 ]; then

    if [[ $template == *"debian"* ]]; then

     # Debian

      qvm-prefs -s $UPDATEVM template $template
      qvm-start $UPDATEVM
      qvm-run -u root -a --nogui -p $UPDATEVM "apt-get update --download-only; DEBIAN_FRONTEND=noninteractive apt-get -y dist-upgrade --download-only"

      # Check if updates were downloaded

      UPDATES=$(qvm-run -u root -a --nogui -p $UPDATEVM "find /var/cache/apt/archives/ -type f -name "*.deb"")

      # If updates were downloaded, then move to the template and install

      if [[ -n $UPDATES ]]; then
        qvm-run -u root -a --nogui -p $UPDATEVM "qvm-move-to-vm $template /var/cache/apt/archives/*.deb; apt-get clean"
        qvm-run -u root -a --nogui -p $template "dpkg -i /home/user/QubesIncoming/$UPDATEVM/*.deb;rm -rf /home/userQubesIncoming/"

        qvm-shutdown $template

      # If updates were not downloaded, then output a message

      else
        echo "   ***   No new packages were downloaded for $template."

      fi

    else

     # Fedora

      qvm-prefs -s $UPDATEVM template $template

      qvm-run -u root -a --nogui -p $UPDATEVM "yum -y upgrade --downloadonly --downloaddir=/home/user/updates"

      # Check if updates were downloaded

      UPDATES=$(qvm-run -u root -a --nogui -p $UPDATEVM "find /home/user/updates/ -type f -name "*.rpm"")

      # If updates were downloaded, check signatures

      if [[ -n $UPDATES ]]; then
        SIGS=$(qvm-run -u root -a --nogui -p $UPDATEVM "rpm -K /home/user/updates/*.rpm | grep NOT")

        # If signatures match, then move to the template and install

        if [[ $SIGS == "" ]]; then
          qvm-run -u root -a --nogui -p $UPDATEVM "qvm-move-to-vm $template /home/user/updates/*"
          qvm-run -u root -a --nogui -p $template "yum upgrade -y /home/user/QubesIncoming/$UPDATEVM/*;rm -rf /home/user/QubesIncoming"
        qvm-shutdown $template

        # If signatures don't match, then output an error

        else
          echo "   *!*   ATTENTION: Signatures did not match!  Please check and update $template manually."
          sleep 3

        fi

      # If updates were not downloaded, then output a message

      else
        echo "   ***   No new packages were downloaded for $template."

      fi

    qvm-run -u root -a --nogui -p $UPDATEVM "yum clean all"

    fi

    qvm-shutdown $UPDATEVM
    sleep 2

  fi
done

# Restore the UPDATEVM's original template (for dom0 updates)

echo "   ***   Restoring $UPDATEVM's original template..."
qvm-prefs -s $UPDATEVM template $UPDATEVM_ORIGTEMP
echo "   ***   Done."
