#!/bin/bash

PATH=/usr/local/bin:/usr/local/sbin:/opt/local/bin:/usr/bin:/usr/sbin:/bin:/sbin
SHELL=/bin/bash

_TODAY=`date +%y%m%d`
_NOW=`date +%y%m%d-%H%M`
_CHECK_HOST=`uname -n`
_LOG_DIR="/var/backups/reports/up/$(basename "$0")/$_TODAY"
_UP_CONTRIB_PID="$_LOG_DIR/$(basename "$0")-contrib-up.pid"
_L_VMFAMILY=XEN
_L_VM_TEST=`uname -a 2>&1`
if [[ "$_L_VM_TEST" =~ beng ]] ; then
  _L_VMFAMILY="VS"
fi

send_report ()
{
  if [ -e "/root/.barracuda.cnf" ] ; then
    source /root/.barracuda.cnf
    if [ -e "/root/.host8.cnf" ] || [[ "$_CHECK_HOST" =~ ".host8." ]] || [ "$_L_VMFAMILY" = "VS" ] ; then
      _MY_EMAIL="$(basename "$0")@omega8.cc"
    fi
    if [ ! -z "$_MY_EMAIL" ] ; then
      cat $_UP_LOG | mail -e -s "REPORT: Successful Octopus upgrade for $_THIS_HM_USER on $_CHECK_HOST at $_NOW" $_MY_EMAIL
      echo "REPORT: Successful Octopus upgrade for $_THIS_HM_USER on $_CHECK_HOST sent to $_MY_EMAIL"
    fi
  fi
}

send_alert ()
{
  if [ -e "/root/.barracuda.cnf" ] ; then
    source /root/.barracuda.cnf
    if [ -e "/root/.host8.cnf" ] || [[ "$_CHECK_HOST" =~ ".host8." ]] || [ "$_L_VMFAMILY" = "VS" ] ; then
      _MY_EMAIL="$(basename "$0")@omega8.cc"
    fi
    if [ ! -z "$_MY_EMAIL" ] ; then
      cat $_UP_LOG | mail -e -s "ALERT: Failed Octopus upgrade for $_THIS_HM_USER on $_CHECK_HOST at $_NOW" $_MY_EMAIL
      echo "ALERT: Failed Octopus upgrade for $_THIS_HM_USER on $_CHECK_HOST sent to $_MY_EMAIL"
    fi
  fi
}

check_report ()
{
  _SEND_ALERT=NO
  _RESULT_BYE=$(grep "BYE" $_UP_LOG)
  if [[ "$_RESULT_BYE" =~ "BYE" ]] ; then
    _DO_NOTHING=YES
  else
    _SEND_ALERT=YES
  fi
  _RESULT_ALRT=$(grep "ALRT:" $_UP_LOG)
  if [[ "$_RESULT_ALRT" =~ "ALRT:" ]] ; then
    _SEND_ALERT=YES
  fi
  _RESULT_ABORTING=$(grep "Aborting" $_UP_LOG)
  if [[ "$_RESULT_ABORTING" =~ "Aborting" ]] ; then
    _SEND_ALERT=YES
  fi
  _RESULT_ALREADY=$(grep "This Aegir Instance is already up to date" $_UP_LOG)
  if [[ "$_RESULT_ALREADY" =~ "This Aegir Instance is already up to date" ]] ; then
    _SEND_ALERT=NO
  fi
  if [ "$_SEND_ALERT" = "YES" ] ; then
    send_alert
  else
    send_report
  fi
}

up_mode ()
{
  if [ "$mcmode" = "aegir" ] ; then
    sed -i "s/^_HM_ONLY=NO/_HM_ONLY=YES/g" /var/backups/OCTOPUS.sh.$_THIS_HM_USER &> /dev/null
    bash /var/backups/OCTOPUS.sh.$_THIS_HM_USER
    touch $User/log/up-$_TODAY
  elif [ "$mcmode" = "platforms" ] ; then
    sed -i "s/^_PLATFORMS_ONLY=NO/_PLATFORMS_ONLY=YES/g" /var/backups/OCTOPUS.sh.$_THIS_HM_USER &> /dev/null
    bash /var/backups/OCTOPUS.sh.$_THIS_HM_USER
    touch $User/log/up-$_TODAY
  elif [ "$mcmode" = "both" ] ; then
    sed -i "s/^_HM_ONLY=YES/_HM_ONLY=NO/g" /var/backups/OCTOPUS.sh.$_THIS_HM_USER &> /dev/null
    sed -i "s/^_HM_ONLY=YES/_HM_ONLY=NO/g" /root/.$_THIS_HM_USER.octopus.cnf &> /dev/null
    sed -i "s/^_PLATFORMS_ONLY=YES/_PLATFORMS_ONLY=NO/g" /var/backups/OCTOPUS.sh.$_THIS_HM_USER &> /dev/null
    sed -i "s/^_PLATFORMS_ONLY=YES/_PLATFORMS_ONLY=NO/g" /root/.$_THIS_HM_USER.octopus.cnf &> /dev/null
    bash /var/backups/OCTOPUS.sh.$_THIS_HM_USER
    touch $User/log/up-$_TODAY
  else
    bash /var/backups/OCTOPUS.sh.$_THIS_HM_USER
    touch $User/log/up-$_TODAY
  fi
}

up_one ()
{
  if [ -e "/var/backups/OCTOPUS.sh.txt" ] ; then
    cp -af /var/backups/OCTOPUS.sh.txt                   /var/backups/OCTOPUS.sh.$_THIS_HM_USER
    sed -i "s/^_AUTOPILOT=NO/_AUTOPILOT=YES/g"           /var/backups/OCTOPUS.sh.$_THIS_HM_USER &> /dev/null
    sed -i "s/^_DNS_SETUP_TEST=YES/_DNS_SETUP_TEST=NO/g" /var/backups/OCTOPUS.sh.$_THIS_HM_USER &> /dev/null
    sed -i "s/^_USER=o1/_USER=$_THIS_HM_USER/g"          /var/backups/OCTOPUS.sh.$_THIS_HM_USER &> /dev/null
    if [ -e "/root/.host8.cnf" ] || [[ "$_CHECK_HOST" =~ ".host8." ]] || [ "$_L_VMFAMILY" = "VS" ] ; then
      if [[ "$_CHECK_HOST" =~ ".o8.io" ]] ; then
        _DO_NOTHING=YES
      else
        sed -i "s/^_STRONG_PASSWORDS=NO/_STRONG_PASSWORDS=YES/g" /var/backups/OCTOPUS.sh.$_THIS_HM_USER &> /dev/null
        sed -i "s/D7P D7S D7D D6P D6S D6D OAM/ALL/g"             /var/backups/OCTOPUS.sh.$_THIS_HM_USER &> /dev/null
        sed -i "s/D7P D7S D7D D6P D6S D6D OAM/ALL/g"             /root/.$_THIS_HM_USER.octopus.cnf &> /dev/null
        sed -i "s/^_AUTOPILOT=NO/_AUTOPILOT=YES/g"               /root/.$_THIS_HM_USER.octopus.cnf &> /dev/null
        sed -i "s/^_DNS_SETUP_TEST=YES/_DNS_SETUP_TEST=NO/g"     /root/.$_THIS_HM_USER.octopus.cnf &> /dev/null
        sed -i "s/^_STRONG_PASSWORDS=NO/_STRONG_PASSWORDS=YES/g" /root/.$_THIS_HM_USER.octopus.cnf &> /dev/null
      fi
    fi
    if [ ! -e "$_UP_CONTRIB_PID" ] ; then
      sed -i "s/^_O_CONTRIB_UP=NO/_O_CONTRIB_UP=YES/g" /var/backups/OCTOPUS.sh.$_THIS_HM_USER &> /dev/null
      sed -i "s/^_O_CONTRIB_UP=NO/_O_CONTRIB_UP=YES/g" /root/.$_THIS_HM_USER.octopus.cnf &> /dev/null
    else
      sed -i "s/^_O_CONTRIB_UP=YES/_O_CONTRIB_UP=NO/g" /var/backups/OCTOPUS.sh.$_THIS_HM_USER &> /dev/null
      sed -i "s/^_O_CONTRIB_UP=YES/_O_CONTRIB_UP=NO/g" /root/.$_THIS_HM_USER.octopus.cnf &> /dev/null
    fi
    if [ -e "/var/backups/OCTOPUS.sh.$_THIS_HM_USER" ] ; then
      _IS_OLD=`find $User/.drush/sys/provision/ -maxdepth 1 -mindepth 1 -mtime +1 -type d | grep platform`
      if [ -z "$_IS_OLD" ] && [ -z "$mcmode" ] && [ -e "$User/.drush/sys/provision" ] ; then
        echo
        echo "This Aegir Instance is already up to date!"
        echo "If you wish to run/force the upgrade again,"
        echo "please specify desired upgrade mode:"
        echo "aegir, platforms or both - as shown below"
        echo
        echo "Usage: $(basename "$0") $cmmand $second {aegir|platforms|both}"
        echo
      else
        if [ -e "$User/.drush/sys/provision" ] ; then
          up_mode
        elif [ -e "$User/.drush/provision" ] ; then
          up_mode
        else
          echo "$User/.drush/sys/provision does not exist!"
        fi
      fi
      if [ -e "$User/log/cores.txt" ] && [ ! -e "$User/log/CANCELLED" ] ; then
        if [ -e "$User/.drush/bm.patch" ] && [ ! -e "$User/.drush/sys/bm.patch" ] && [ -e "$User/.drush/sys" ] ; then
          mv -f $User/.drush/bm.patch $User/.drush/sys/bm.patch
        fi
        if [ -e "$User/.drush/sys/bm.patch" ] ; then
          cd $User/.drush/sys
          patch -p1 < bm.patch &> /dev/null
        fi
        if [ -e "$User/.drush/custom.patch" ] && [ ! -e "$User/.drush/sys/custom.patch" ] && [ -e "$User/.drush/sys" ] ; then
          mv -f $User/.drush/custom.patch $User/.drush/sys/custom.patch
        fi
        if [ -e "$User/.drush/sys/custom.patch" ] ; then
          cd $User/.drush/sys
          patch -p1 < custom.patch &> /dev/null
        fi
        if [ -e "$User/.drush/uberdrupal.patch" ] && [ ! -e "$User/.drush/sys/uberdrupal.patch" ] && [ -e "$User/.drush/sys" ] ; then
          mv -f $User/.drush/uberdrupal.patch $User/.drush/sys/uberdrupal.patch
        fi
        if [ -e "$User/.drush/sys/uberdrupal.patch" ] ; then
          cd $User/.drush/sys
          patch -p1 < uberdrupal.patch &> /dev/null
        fi
        cd /var/backups
      fi
    else
      echo "OCTOPUS.sh.txt installer not available - try again"
      exit 1
    fi
  fi
}

count_cpu()
{
  _CPU_INFO=$(grep -c processor /proc/cpuinfo)
  _CPU_INFO=${_CPU_INFO//[^0-9]/}
  _NPROC_TEST=$(which nproc)
  if [ -z "$_NPROC_TEST" ] ; then
    _CPU_NR="$_CPU_INFO"
  else
    _CPU_NR=`nproc`
  fi
  _CPU_NR=${_CPU_NR//[^0-9]/}
  if [ ! -z "$_CPU_NR" ] && [ ! -z "$_CPU_INFO" ] && [ "$_CPU_NR" -gt "$_CPU_INFO" ] && [ "$_CPU_INFO" -gt "0" ] ; then
    _CPU_NR="$_CPU_INFO"
  fi
  if [ -z "$_CPU_NR" ] || [ "$_CPU_NR" -lt "1" ] ; then
    _CPU_NR=1
  fi
}

load_control()
{
  if [ -e "/root/.barracuda.cnf" ] ; then
    source /root/.barracuda.cnf
    _CPU_MAX_RATIO=${_CPU_MAX_RATIO//[^0-9]/}
  fi
  if [ -z "$_CPU_MAX_RATIO" ] ; then
    _CPU_MAX_RATIO=6
  fi
  _O_LOAD=`awk '{print $1*100}' /proc/loadavg`
  let "_O_LOAD = (($_O_LOAD / $_CPU_NR))"
  let "_O_LOAD_MAX = ((100 * $_CPU_MAX_RATIO))"
}

up_action_all ()
{
  for User in `find /data/disk/ -maxdepth 1 | sort`
  do
    count_cpu
    load_control
    if [ -d "$User/config/server_master/nginx/vhost.d" ] && [ -e "$User/log/cores.txt" ] && [ ! -e "$User/log/CANCELLED" ] ; then
      if [ $_O_LOAD -lt $_O_LOAD_MAX ] ; then
        _THIS_HM_USER=`echo $User | cut -d'/' -f4 | awk '{ print $1}'`
        echo load is $_O_LOAD while maxload is $_O_LOAD_MAX
        echo Octopus upgrade for User $User
        n=$((RANDOM%9+2))
        echo Waiting $n seconds...
        sleep $n
        if [ "$silent" = "log" ] ; then
          _UP_LOG="$_LOG_DIR/$(basename "$0")-up-$_THIS_HM_USER-$_NOW.log"
          echo
          echo "Preparing the upgrade in silent mode..."
          echo
          echo "NOTE: There will be no progress displayed in the console"
          echo "but you will receive an e-mail once the upgrade is complete"
          echo
          sleep 5
          echo "You could watch the progress in another window with command:"
          echo "  tail -f $_UP_LOG"
          echo "or wait until you will see the line: OCTOPUS upgrade completed"
          echo
          echo "Starting the upgrade in silent mode now..."
          echo
          sed -i "s/^_SPINNER=YES/_SPINNER=NO/g" /var/backups/OCTOPUS.sh.txt &> /dev/null
          up_one >>$_UP_LOG 2>&1
          check_report
        else
          up_one
        fi
        n=$((RANDOM%9+2))
        echo Waiting $n seconds...
        sleep $n
        rm -f /var/backups/OCTOPUS.sh.$_THIS_HM_USER
        echo Done for $User
        if [ ! -e "$_UP_CONTRIB_PID" ] ; then
          touch $_UP_CONTRIB_PID
        fi
      else
        echo load is $_O_LOAD while maxload is $_O_LOAD_MAX
        echo ...we have to wait...
      fi
      echo
      echo
    fi
  done
}

up_action_one ()
{
  User="/data/disk/$second"
  count_cpu
  load_control
  if [ -d "$User/config/server_master/nginx/vhost.d" ] && [ -e "$User/log/cores.txt" ] && [ ! -e "$User/log/CANCELLED" ] ; then
    if [ $_O_LOAD -lt $_O_LOAD_MAX ] ; then
      _THIS_HM_USER=`echo $User | cut -d'/' -f4 | awk '{ print $1}'`
      echo load is $_O_LOAD while maxload is $_O_LOAD_MAX
      echo Octopus upgrade for User $User
      sleep 3
      if [ "$silent" = "log" ] ; then
        _UP_LOG="$_LOG_DIR/$(basename "$0")-up-$_THIS_HM_USER-$_NOW.log"
        echo
        echo "Preparing the upgrade in silent mode..."
        echo
        echo "NOTE: There will be no progress displayed in the console"
        echo "but you will receive an e-mail once the upgrade is complete"
        echo
        sleep 5
        echo "You could watch the progress in another window with command:"
        echo "  tail -f $_UP_LOG"
        echo "or wait until you will see the line: OCTOPUS upgrade completed"
        echo
        echo "Starting the upgrade in silent mode now..."
        echo
        sed -i "s/^_SPINNER=YES/_SPINNER=NO/g" /var/backups/OCTOPUS.sh.txt &> /dev/null
        up_one >>$_UP_LOG 2>&1
        check_report
      else
        up_one
      fi
      sleep 3
      rm -f /var/backups/OCTOPUS.sh.$_THIS_HM_USER
      echo Done for $User
      if [ ! -e "$_UP_CONTRIB_PID" ] ; then
        touch $_UP_CONTRIB_PID
      fi
    else
      echo load is $_O_LOAD while maxload is $_O_LOAD_MAX
      echo try again later
    fi
    echo
    echo
  fi
}

up_start ()
{
  if [ -e "/var/run/boa_run.pid" ] ; then
    echo Another BOA installer is running probably - /var/run/boa_run.pid exists
    exit 1
  elif [ -e "/var/run/boa_wait.pid" ] ; then
    echo Some important system task is running probably - /var/run/boa_wait.pid exists
    exit 1
  else
    touch /var/run/boa_run.pid
    touch /var/run/boa_wait.pid
    mkdir -p $_LOG_DIR
    cd /var/backups
    rm -f /var/backups/OCTOPUS.sh*
  fi
  if [ "$cmmode" = "log" ] ; then
    silent="$cmmode"
  fi
  if [ ! -z "$cmmode" ] && [ "$cmmode" != "log" ] ; then
    mcmode="$cmmode"
  fi
  if [ -e "/opt/local/bin/php" ] || [ -e "/usr/local/bin/php" ] ; then
    rm -f /opt/local/bin/php
    rm -f /usr/local/bin/php
  fi
  if [ -d "/opt/local/bin" ] ; then
    if [ -x "/opt/php53/bin/php" ] ; then
      ln -s /opt/php53/bin/php /opt/local/bin/php
    elif [ -x "/opt/php54/bin/php" ] ; then
      ln -s /opt/php54/bin/php /opt/local/bin/php
    elif [ -x "/opt/php55/bin/php" ] ; then
      ln -s /opt/php55/bin/php /opt/local/bin/php
    else
      ln -s /opt/php53/bin/php /opt/local/bin/php &> /dev/null
    fi
  fi
}

up_finish ()
{
  rm -f /var/run/boa_run.pid
  rm -f /var/run/boa_wait.pid
  rm -f /var/backups/OCTOPUS.sh*
  rm -f /root/BOA.sh*
  if [ -e "/opt/local/bin/php" ] || [ -e "/usr/local/bin/php" ] ; then
    rm -f /opt/local/bin/php
    rm -f /usr/local/bin/php
  fi
  echo
  echo OCTOPUS upgrade completed
  echo Bye
  echo
  if [ "$_NEEDS_UPDATE" = "YES" ] ; then
    rm -f /var/backups/BOA.sh.txt-*
    curl -L --max-redirs 10 -k -s --retry 10 --retry-delay 5 -A iCab "http://files.aegir.cc/BOA.sh.txt" -o /var/backups/BOA.sh.txt-$_NOW
    exec bash /var/backups/BOA.sh.txt-$_NOW &> /dev/null
    rm -f /var/backups/BOA.sh.txt-$_NOW
  fi
  exit 0
}

up_stable ()
{
  up_start
  curl -L --max-redirs 10 -k -s --retry 10 --retry-delay 5 -A iCab "http://files.aegir.cc/versions/stable/txt/OCTOPUS.sh.txt" -o OCTOPUS.sh.txt
  if [ "$second" = "all" ] ; then
    up_action_all
  else
    up_action_one
  fi
  up_finish
}

up_head ()
{
  up_start
  curl -L --max-redirs 10 -k -s --retry 10 --retry-delay 5 -A iCab "https://raw.githubusercontent.com/omega8cc/boa/master/OCTOPUS.sh.txt" -o OCTOPUS.sh.txt
  if [ "$second" = "all" ] ; then
    up_action_all
  else
    up_action_one
  fi
  up_finish
}

up_legacy ()
{
  up_start
  curl -L --max-redirs 10 -k -s --retry 10 --retry-delay 5 -A iCab "http://files.aegir.cc/versions/legacy/txt/OCTOPUS.sh.txt" -o OCTOPUS.sh.txt
  if [ "$second" = "all" ] ; then
    up_action_all
  else
    up_action_one
  fi
  up_finish
}

download_wrapper ()
{
  if [ ! -e "$_THIS_FILE" ] ; then
    echo "I can not connect to files.aegir.cc at the moment"
    echo "I will try again in 15 seconds, please wait..."
    sleep 15
    curl -L --max-redirs 10 -k -s --retry 10 --retry-delay 5 -A iCab "http://files.aegir.cc/versions/master/aegir/tools/bin/$(basename "$0")" -o $_THIS_FILE
  fi
}

check_wrapper ()
{
  mkdir -p /var/backups
  rm -f /var/backups/$(basename "$0")-now-*
  _THIS_FILE="/var/backups/$(basename "$0")-now-$_NOW"
  curl -L --max-redirs 10 -k -s --retry 10 --retry-delay 5 -A iCab "http://files.aegir.cc/versions/master/aegir/tools/bin/$(basename "$0")" -o $_THIS_FILE
  if [ ! -e "$_THIS_FILE" ] ; then
    download_wrapper
    if [ ! -e "$_THIS_FILE" ] ; then
      download_wrapper
      if [ ! -e "$_THIS_FILE" ] ; then
        download_wrapper
        if [ ! -e "$_THIS_FILE" ] ; then
          echo "Sorry, I gave up."
          echo "Please check http://stats.pingdom.com/x0s6yrbopal6/801243 and try again later."
          exit 1
        fi
      fi
    fi
  fi
  _BIN_FILE="/usr/local/bin/$(basename "$0")"
  _DATE_TEST=$(grep "### $_TODAY ###" $_THIS_FILE)
  if [[ "$_DATE_TEST" =~ "### $_TODAY ###" ]] ; then
    _NEEDS_UPDATE=NO
  else
    _NEEDS_UPDATE=YES
  fi
}

check_dns_curl ()
{
  if [ ! -e "/etc/resolv.conf" ] ; then
    echo "nameserver 8.8.8.8" >/etc/resolv.conf
    echo "nameserver 8.8.4.4" >>/etc/resolv.conf
  else
    _RESOLV_TEST=$(grep "nameserver" /etc/resolv.conf)
    if [[ "$_RESOLV_TEST" =~ "nameserver" ]] ; then
      _DO_NOTHING=YES
    else
      rm -f /etc/resolv.conf
      echo "nameserver 8.8.8.8" >/etc/resolv.conf
      echo "nameserver 8.8.4.4" >>/etc/resolv.conf
    fi
  fi
  _CURL_TEST=$(curl -L --max-redirs 10 -k -s -I "http://files.aegir.cc" 2> /dev/null)
  if [[ "$_CURL_TEST" =~ "200 OK" ]] ; then
    _DO_NOTHING=YES
  else
    apt-get clean -qq &> /dev/null
    apt-get update -qq &> /dev/null
    apt-get install curl -y --force-yes --reinstall &> /dev/null
  fi
}

check_root ()
{
  if [ `whoami` = "root" ] ; then
    chmod a+w /dev/null
    if [ ! -e "/dev/fd" ] ; then
      if [ -e "/proc/self/fd" ] ; then
        rm -rf /dev/fd
        ln -s /proc/self/fd /dev/fd
      fi
    fi
    sed -i "s/.*173.231.133.190.*//g" /etc/hosts
    sed -i "s/^127.0.0.1.*/127.0.0.1 localhost/g" /etc/hosts
    sed -i "/^$/d" /etc/hosts
  else
    echo "ERROR: This script should be ran as a root user - please `sudo -i` first"
    exit 1
  fi
  _DF_TEST=$(df -kTh / -l | grep '/'| sed 's/\%//g'| awk '{print $6}' 2> /dev/null)
  _DF_TEST=${_DF_TEST//[^0-9]/}
  if [ ! -z "$_DF_TEST" ] && [ "$_DF_TEST" -gt "90" ] ; then
    echo "ERROR: Your disk space is almost full - we can not proceed until it is below 90/100"
    exit 1
  fi
}

case "$1" in
  up-stable) cmmand="$1"
             second="$2"
             cmmode="$3"
             silent="$4"
             check_root
             check_dns_curl
             check_wrapper
             up_stable
  ;;
  up-head)   cmmand="$1"
             second="$2"
             cmmode="$3"
             silent="$4"
             check_root
             check_dns_curl
             check_wrapper
             up_head
  ;;
  up-legacy) cmmand="$1"
             second="$2"
             cmmode="$3"
             silent="$4"
             check_root
             check_dns_curl
             check_wrapper
             up_legacy
  ;;
  *)         echo
             echo "Usage: $(basename "$0") {up-stable|up-head|up-legacy} {all|o1} {aegir|platforms|both}"
             echo
             exit 1
  ;;
esac
