#!/bin/bash
## +----------------------------------------------------------------------+
## | InterWorx Hosting Control Panel                                      |
## +----------------------------------------------------------------------+
## | Copyright (c) 2000-2013 INTERWORX L.L.C., All Rights Reserved.       |
## +----------------------------------------------------------------------+
## | Redistribution and use in source form, with or without modification  |
## | is NOT permitted without consent from the copyright holder.          |
## |                                                                      |
## | THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND |
## | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,    |
## | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A          |
## | PARTICULAR PURPOSE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,    |
## | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  |
## | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR   |
## | PROFITS; OF BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY  |
## | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT         |
## | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE    |
## | USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH     |
## | DAMAGE.                                                              |
## +----------------------------------------------------------------------+
## | Authors: Paul Oehler <poehler@interworx.com>                         |
## |          Chris Wells <clwells@interworx.com>                         |
## +----------------------------------------------------------------------+
#

rpmhost=updates.interworx.com
force_install=0
force_killconflict=0
debug=0
srpmdir='/usr/src/redhat/SRPMS'
rpmdir='/usr/src/redhat/RPMS'
opsys=$(uname -o)
processor=$(uname -p)
arch=$(uname -i)
distro='unk'
release='Unknown Distribution'
target='unk'
yumupdate=0
headless=0
iworxrepo="release"
testrepo=""
iworxinstall=1
yumargs=''
jailsetup=1
resolv=0
verbose=0
dorpmcheck=0
phpvers="7.3"
mariavers="10.2"
mariadist="unk"

LOG='iworx-install.log'
LOG_REDIR='/dev/null'

rhe6x_conflicts='bind
                 redhat-config-bind
                 caching-nameserver
                 sendmail
                 postfix
                 exim
                 mutt
                 fetchmail
                 spamassassin
                 redhat-lsb
                 evolution
                 mod_python
                 mod_auth_mysql
                 mod_authz_ldap
                 mod_auth_pgsql
                 mod_auth_kerb
                 mod_perl
                 mdadm
                 dovecot
                 vsftpd
                 httpd-tools'

rhe7x_conflicts='bind
                 redhat-config-bind
                 caching-nameserver
                 sendmail
                 postfix
                 exim
                 mutt
                 fetchmail
                 spamassassin
                 redhat-lsb
                 evolution
                 mod_python
                 mod_auth_mysql
                 mod_authz_ldap
                 mod_auth_pgsql
                 mod_auth_kerb
                 mod_perl
                 mdadm
                 dovecot
                 vsftpd
                 httpd-tools'

cos6x_conflicts='bind
                 redhat-config-bind
                 caching-nameserver
                 sendmail
                 postfix
                 exim
                 mutt
                 fetchmail
                 spamassassin
                 redhat-lsb
                 evolution
                 mod_python
                 mod_auth_mysql
                 mod_authz_ldap
                 mod_auth_pgsql
                 mod_auth_kerb
                 mod_perl
                 mdadm
                 dovecot
                 vsftpd
                 httpd-tools'




##
# the main goiworx func
##


function control_c {
    trap - SIGINT
    killall -2 -g yum python tee > /dev/null 2>&1
    exit 1
}


trap control_c SIGINT

function goiworx {
    [ "$verbose" == "1" ] && LOG_REDIR=''
    [ "$debug" == "1" ] && LOG_REDIR=''
    distrocheck
    ifacecheck
    mariaverscheck
    phpverscheck
    banner

    if [ "$target" = "rhe7x" ]; then
        _rpms="iptables iptables-services"
        checkrpm $_rpms ||
        runyum -y install $_rpms
    fi

    status_print "Installing wget (if needed)"
    _rpms="wget"
    checkrpm $_rpms ||
    runyum -y install $_rpms

    status_print "Installing psmisc (if needed)"
    _rpms="psmisc"
    checkrpm $_rpms ||
    runyum -y install $_rpms

    status_print "Installing yum-utils (if needed)"
    _rpms="yum-utils"
    checkrpm $_rpms ||
    runyum -y install $_rpms

    gpgkeys
    basecheck

    [ -f "$LOG" ] && rm -f $LOG

    if [ $jailsetup -gt 0 ]; then
        setupjail
    fi

    yumconfig

    killconflicts
    distrofix
    mysqlinstall
    httpdinstall
    phpinstall

    if [ $yumupdate -gt 0 ]; then
        updatesystem
    fi

    if [ $iworxinstall -gt 0 ]; then
        iworxinstall
        upstartconfig
        relocatedirs
        status_print "Installing any available hotfixes"
        ~iworx/bin/hotfix.pex --install
    fi

    installextras
    openvznotice2
    runquota
    killservices
    updatetime

    footer

    return 0
}

function openvznotice1 {

  if [[ -e /proc/user_beancounters ]] || [[ -e /proc/vz/veinfo ]]; then
      echo
      header_print "ALERT: It appears this server is in a OpenVZ or Virtuzzo Environment."
      header_print "SECOND LEVEL QUOTAS MUST BE ENABLED for InterWorx to function properly!"
      header_print "If Second Level Quotas are not enabled, please hit Ctrl+C now, and enable"
      header_print "them, or ask your VPS provider to enable them for you, then re-run the"
      header_print "InterWorx install script."
      header_print  "see: http://download.swsoft.com/virtuozzo/virtuozzo4.0/docs/en/lin/VzLinuxUG/293.htm"
      sleep 7
  fi

}

function openvznotice2 {

  if [[ -e /proc/user_beancounters ]] || [[ -e /proc/vz/veinfo ]]; then
    if ! [[ -e /aquota.group ]]; then
        echo
        header_print "ALERT: It appears this server is in a OpenVZ or Virtuzzo Environment."
        header_print "It does NOT appear that second level quotas are enabled on this virtual machine"
        header_print "SECOND LEVEL QUOTAS MUST BE ENABLED for InterWorx to function properly!"
        header_print "Please hit Ctrl+C now, and enable them, or as your VPS provider to do so far you,"
        header_print "then re-run the InterWorx install script."
        header_print  "see: http://download.swsoft.com/virtuozzo/virtuozzo4.0/docs/en/lin/VzLinuxUG/293.htm"
        sleep 10
    fi
  fi

}

##
# add our mysql lib dir to the ldconfig path
##

function ldconfigfix {
    if [ `egrep -c interworx /etc/ld.so.conf` -eq 0 ]; then
        echo '/home/interworx/lib/mysql' >> /etc/ld.so.conf
        ldconfig
    fi
}

##
# install any extra packages iworx needs
##

function installextras {

    debug_print "Installing misc extra tools"
    status_print "Installing misc extra tools (errors are ok here)"
    _rpms="mdadm emacs-nox quota netpbm netpbm-devel netpbm-progs strace which ftp zip mailx vim-enhanced sysstat"
    checkrpm $_rpms ||
    runyum $yumargs install $_rpms
}

##
# setup the jailing if possible.
##

function setupjail {

    status_println "Setting up JAILED home/chroot dirs"

    if [ -L /home ]; then
        status_println "Looks like jailing is already setup"
        return 0
    fi

    if [ ! -d /home ]; then
        error_print "/home doesn't exist, can't setup JAIL"
        return 1
    fi

    # make sure /home isn't a mountable partition

    if [ `mount | egrep -c " \/home "` -eq 0 ]; then

        if [ ! -d /chroot ]; then
            status_println "Creating /chroot"
            mkdir /chroot
        fi

        if [[ -d /etc/systemd/system/multi-user.target.wants ]]; then
          for service in /etc/systemd/system/multi-user.target.wants/*.service; do
            grep -q ProtectHome $service &&
              service $(basename $service) stop &>/dev/null
            if [[ $(basename $service) == "NetworkManager.service" ]]; then
              killall -9 dhclient 2> /dev/null
            fi
          done
        fi

        status_println "Moving /home to /chroot/home"
        mv /home /chroot

        status_println "Symlinking /home -> /chroot/home"
        ln -fs /chroot/home /home

        status_println "Fixing JAIL permissions"
        chown root:root /chroot
        chmod 711 /chroot

        chown root:root /chroot/home
        chmod 711 /chroot/home

        if [[ -d /etc/systemd/system/multi-user.target.wants ]]; then
          for service in /etc/systemd/system/multi-user.target.wants/*.service; do
            grep -q ProtectHome $service &&
              service $(basename $service) start &>/dev/null
          done
        fi

    fi
}

##
# we need to configure  svscanboot to start on boot
# normally daemontools  RPM would do this
# but the "start" command fails inside the rpm scriptlet
# for some reason
##

function upstartconfig {
    if [ -d /etc/init ]; then
        debug_print_read "About to configure svscanboot with upstart (/etc/init)"
        echo 'start on runlevel [12345]
stop on runlevel [06]
respawn
exec /command/svscanboot
' > /etc/init/svscanboot.conf
        /sbin/start --quiet svscanboot > /dev/null 2>&1
    fi
    if [ -d /etc/systemd ]; then
        debug_print_read "About to configure svscanboot with systemd"
        systemctl enable svscanboot
        service svscanboot restart
    fi
}

##
# we need to move vpopmail and interworx
# from their /home locations for clustering
##

function relocatedirs {
    debug_print_read "About to relocate InterWorx-CP and Vpopmail"

    if [ -d /home/interworx ] && [ ! -L /home/interworx ]; then
        status_println "moving InterWorx-CP to /usr/local/interworx"
        service iworx stop > /dev/null 2>&1
        if [ -d /usr/local/interworx ]; then
            mv -f /home/interworx/* /usr/local/interworx/
            mv -f /home/interworx/.[^.]* /usr/local/interworx/
            rmdir /home/interworx/
        else
            mv -f /home/interworx /usr/local
        fi
        ln -fs /usr/local/interworx /home/interworx
        service iworx start > /dev/null 2>&1
    fi

    if [ -d /home/vpopmail ] && [ ! -L /home/vpopmail ]; then
        status_println "moving Vpopmail to /var/vpopmail"
        mv -f /home/vpopmail /var
        ln -fs /var/vpopmail /home/vpopmail
    fi
}

##
# see wtf distro we're running on
##

function distrocheck {
    status_println "Determining Linux distribution"

    ##
    # Figure out what platform we're on so we can build
    # RPMs accordingly.
    ##

    if [ -f /etc/redhat-release ]; then
        release=$(cat /etc/redhat-release)
    elif [ -f /etc/openna-release ]; then
        release=$(cat /etc/openna-release)
    elif [ -f /etc/system-release ]; then
        release=$(cat /etc/system-release)
    fi

    #
    # lowest common substring
    local cos6x1="CentOS Linux release 6"
    local cos6x2="CentOS release 6"
    local cos7x="CentOS Linux release 7"
    local cloud6x="CloudLinux Server release 6"
    local cloud7x="CloudLinux Server release 7"
    local rhe6x="Red Hat Enterprise Linux Server release 6"
    local rhe6x_scientific="Scientific Linux release 6"
    local rhe7x="Red Hat Enterprise Linux Server release 7"
    local rsel6x="Red Sleeve Enterprise Linux release 6"

    if [ `echo "$release" | egrep -c "$cos6x1"` -gt 0 ]; then
        target='rhe6x'
        distro='cos6x'
        mariadist='centos6'
    elif [ `echo "$release" | egrep -c "$cos6x2"` -gt 0 ]; then
        target='rhe6x'
        distro='cos6x'
        mariadist='centos6'
    elif [ `echo "$release" | egrep -c "$cos7x"` -gt 0 ]; then
        target='rhe7x'
        distro='cos7x'
        mariadist='centos7'
    elif [ `echo "$release" | egrep -c "$cloud6x"` -gt 0 ]; then
        target='rhe6x'
        distro='cloud6x'
    elif [ `echo "$release" | egrep -c "$cloud7x"` -gt 0 ]; then
        target='rhe7x'
        distro='cloud7x'
    elif [ `echo "$release" | egrep -c "$rhe6x"` -gt 0 ]; then
        target='rhe6x'
        distro='rhe6x'
        mariadist='rhel6'
    elif [ `echo "$release" | egrep -c "$rhe6x_scientific"` -gt 0 ]; then
        target='rhe6x'
        distro='rhe6x'
        mariadist='rhel6'
    elif [ `echo "$release" | egrep -c "$rhe7x"` -gt 0 ]; then
        target='rhe7x'
        distro='rhe7x'
        mariadist='rhel7'
    elif [ `echo "$release" | egrep -c "$rsel6x"` -gt 0 ]; then
        target='rhe6x'
        distro='rsel6x'
    fi

    ##
    # see if we can even install on this plat
    if [ "$target" = "unk" ]; then
        if [ $force_install -eq 0 ]; then
            error_print_die "$release not supported, override with -f"
        fi
    fi
}

function ifacecheck {
    status_println "Checking network interface names"
    for f in `ls /sys/class/net`
    do
            if [ "${#f}" -gt 10 ]; then
                    header_print "On some systems, network interface naming"
                    header_print "conventions can vary, leading to potential issues"
                    header_print "when InterWorx attempts to append identifiers to"
                    header_print "longer names."
                    header_print ""
                    header_print "It has been detected your system may be"
                    header_print "susceptible to this issue."
                    header_print ""
                    header_print "More info: https://www.interworx.com/support/faq/change-network-interface-centos-7/"
                    header_print ""
                    user_prompt_yn "Continue anyway? (Y/n): "
                    OK=$?
                    if [ $OK -eq 0 ]; then
                    header_print "Aborting InterWorx-CP install...."
                    exit;
                    fi
                    return
            fi
    done
}

function footer {
    echo -e ""
    echo -e "\033[0;40m\033[1;37m\033[1m-=-=-=-=-= Installation Complete! Next Step: License Activation! =-=-=-=-=-\033[0m"
    echo -e ""
    echo -e "\033[40m\033[001;033mTo activate your license, go to"
    echo -e "\033[40m\033[001;033mhttps://your-ip:2443/nodeworx/"
    echo -e "\033[40m\033[001;033mAlso, check out https://www.interworx.com for news, updates, and support!"
    echo -e ""
    echo -e "\033[0;40m\033[1;37m\033[1m-=-=-=-=-= THANK YOU FOR USING \033[0;40m\033[1m\033[4m\033[1;36mINTERWORX!\033[0;40m\033[1;37m\033[1m\033[0;40m\033[1;37m\033[1m =-=-=-=-=-\033[0m"
    echo -e ""
}

##
# show the usage
##

function usage {
    cat <<EOF

Usage: $0 [-s rpm/ks server hostname] [-s server] [-d] [-f] [-u] [-k] [-l] [-i] [-h]
    -s RPM server
       Specify a different rpm host to grab src.rpm/rpms from
       (default: updates.interworx.com).
    -d Turn debugging on (you'll have to hit enter sometimes.
       to keep things moving, output is halted so you can see it).
    -f FORCE installation even if the distro isn't supported.
    -u Perform a "yum update" prior to installation of
       InterWorx-CP.
    -k Force the removal of any conflicting packages that will
       interrupt the InterWorx-CP install.
    -l Run in headless mode.  No prompting will occur.
    -r Choose an interworx repository to enable. default: release.
       (release,alpha,beta,release-candidate,stable)
    -i Install all packages *except* InterWorx-CP itself.
    -m Maria DB version to use. Specify "system" to use the version available via yum
    -p PHP version to use. Specify "system" to use the version available via yum
    -v Verbose output.
    -h Show this help message."

EOF
}

#     -j setup the JAILED ssh dir structure if possible
##
# run through getopts
##

while getopts ":s:dbr:t:nyho:uklfijvm:p:" opt; do

    case $opt in
        s  ) rpmhost=$OPTARG ;;
        d  ) debug=1 ;;
        l  ) headless=1 ;;
        u  ) yumupdate=1 ;;
        j  ) jailsetup=1 ;;
        k  ) force_killconflict=1 ;;
        f  ) force_install=1 ;;
        i  ) iworxinstall=0 ;;
        r  ) iworxrepo=$OPTARG ;;
        t  ) testrepo=$OPTARG ;;
        m  ) mariavers=$OPTARG ;;
        p  ) phpvers=$OPTARG ;;
        v  ) verbose=1 ;;
        h  ) usage
            exit 1 ;;
        ?  ) usage
            exit 1 ;;
    esac
done

shift $(($OPTIND - 1))

##
# do some base checks to see if we can even run
##

function basecheck {
    ##
    # make sure we at leaset have rpm as we need it
    ##

    ls /bin/rpm > /dev/null 2>&1
    if [ $? -gt 0 ]; then
        error_print_die "$0 requires 'rpm' to be installed"
    fi

    qmailidfix
    qmailcheck
    selinuxcheck
    firewallcheck
}

##
# fix qmail u/gids
##
function qmailidfix {
    rpm --quiet -q qmail
    qmail_missing=$?


    baduids='101
             102
             103
             104
             105
             106
             107
             108'

    badgids='102
             103
             104'

    newid="200"
    for id in $baduids; do
        if [ `egrep -c "x:$id:[0-9]+" /etc/passwd` -gt 0 -a $qmail_missing -gt 0 ]; then
            while [ `egrep -c "x:$newid:[0-9]+" /etc/passwd` -gt 0 ]; do
                newid=`expr $newid + 1`
            done
            /usr/sbin/usermod -u $newid `egrep "x:$id:[0-9]+" /etc/passwd | sed 's|:| |g' | awk '{print $1}'`
        fi
    done

    newid="200"
    for id in $badgids; do
        if [ `egrep -c "x:$id" /etc/group` -gt 0 -a $qmail_missing -gt 0 ]; then
            while [ `egrep -c "x:$newid" /etc/group` -gt 0 ]; do
                newid=`expr $newid + 1`
            done
            /usr/sbin/groupmod -g $newid `egrep "x:$id" /etc/group | sed 's|:| |g' | awk '{print $1}'`
            if [ `egrep -c "x:[0-9]+:$id:" /etc/passwd` -gt 0 ]; then
                /usr/sbin/usermod -g $newid `egrep "x:[0-9]+:$id:" /etc/passwd | sed 's|:| |g' | awk '{print $1}'`
            fi
        fi
    done
}

##
# disable iptables (APF will replace)
##

function firewallcheck {
    chkconfig --level 012345 iptables off >/dev/null 2>&1
    service iptables stop > /dev/null 2>&1
    chkconfig --level 012345 firewalld off >/dev/null 2>&1
    service firewalld stop > /dev/null 2>&1

    # we are suppressing new network device naming conventions until further notice
    ln -s /dev/null /etc/udev/rules.d/80-net-name-slot.rules
}

##
# check for and possibly disable selinux
##

function selinuxcheck {
    selinux_config=""
    if [[ -f /etc/sysconfig/selinux ]]; then
        if [[ `egrep -c "SELINUX[:space:]*=[:space:]*disabled" /etc/sysconfig/selinux 2>/dev/null` -eq 0 ]]; then
            selinux_config="/etc/sysconfig/selinux"
        fi

    elif [[ -f /etc/selinux/config ]]; then
        if [ `egrep -c "SELINUX[:space:]*=[:space:]*disabled" /etc/selinux/config 2>/dev/null` -eq 0 ]; then
            selinux_config="/etc/selinux/config"
        fi

    fi

    if [[ "$selinux_config" != "" ]]; then

        echo -e ""
        header_print "SELINUX conflicts with some of InterWorx-CP's"
        header_print "functions and for this reason it must be disabled."
        header_print "If SELINUX must be enabled in your environment, press"
        header_print "ctrl-c now to exit the installation."

        sleep 5

        status_println "Disabing SELINUX for next boot"
        debug_print_read "About to edit selinux config"
        sed --in-place 's/SELINUX=.*/SELINUX=disabled/' /etc/sysconfig/selinux
        sed --in-place 's/SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
    fi

    status_println "Turning off SELINUX for current session"
    setenforce 0 2>/dev/null
    chkconfig --level 012345 setroubleshoot off 2>/dev/null
}

##
# see if qmail is installed with the correct UID/GID OR
# make sure that the UID/GIDs are available that we need.
##

function qmailcheck {
    ##
    # qmail uid/gid check
    ##

    rpm --quiet -q qmail
    qmail_missing=$?

    if [ `egrep -c "x:10[2-7]:[0-9]+" /etc/passwd` -gt 0 -a $qmail_missing -gt 0 ]; then
        error_print_die "$0 requires UIDs 102 -> 107 to be unused"
    fi

    if [ `egrep -c "x:10[2-3]:" /etc/group` -gt 0 -a $qmail_missing -gt 0 ]; then
        error_print_die "$0 requires GIDs 102 -> 103 to be unused"
    fi
}

##
# show the pretty banner
##

function banner {
    ##
    # barf out what we're doing
    ##

    echo
    echo -e "\033[0;40m\033[1;37m\033[1m-=-=-=-=-= Installing \033[0;40m\033[1m\033[4m\033[1;36mInterWorx-CP\033[0;40m\033[1;37m\033[1m =-=-=-=-=-\033[0m"
    echo
    header_print "This script will install InterWorx-CP on your system."
    header_print "Please make sure that you have backed up any critical"
    header_print "data!"
    echo
    header_print "This script may be run multiple times without any"
    header_print "problems.  This is helpful if you find an error"
    header_print "during installation, you can safely ctrl-c out of"
    header_print "this script, fix the error and re-start the script."
    echo
    header_print "Details of this installation will be logged in iworx-install.log"
    echo
    echo -e "\033[40m\033[001;031mTARGET     : \033[40m\033[001;033m$release\033[0m\033[0m"
    echo -e "\033[40m\033[001;031mPLATFORM   : \033[40m\033[001;033m$opsys\033[0m\033[0m"
    echo -e "\033[40m\033[001;031mPROCESSOR  : \033[40m\033[001;033m$processor\033[0m\033[0m"
    echo -e "\033[40m\033[001;031mRPM TARGET : \033[40m\033[001;033m$target\033[0m\033[0m"
    echo -e "\033[40m\033[001;031mRPM DISTRO : \033[40m\033[001;033m$distro\033[0m\033[0m"
    echo -e "\033[40m\033[001;031mRPM DIR    : \033[40m\033[001;033m$rpmdir\033[0m\033[0m"
    echo -e "\033[40m\033[001;031mSRPM DIR   : \033[40m\033[001;033m$srpmdir\033[0m\033[0m"
    echo -e "\033[40m\033[001;031mSRPM HOST  : \033[40m\033[001;033m$rpmhost\033[0m\033[0m"
    echo -e "\033[40m\033[001;031mIWORX REPO : \033[40m\033[001;033m$iworxrepo\033[0m\033[0m"
    echo -e "\033[40m\033[001;031mDEFAULT PHP: \033[40m\033[001;033mPHP $phpvers\033[0m\033[0m"
    echo -e "\033[40m\033[001;031mMYSQL      : \033[40m\033[001;033mMARIADB $mariavers\033[0m\033[0m"
    echo

    openvznotice1

    header_print "Press <enter> to begin the install..."
    [ $headless -eq 0 ] && read
}

##
# some distros needs some 'extra help' package wise
# so installed needed packages
##

function distrofix {

    ##
    # some platforms needs some special care
    ##

    status_print "Installing the LVS Load Balancer"
    _rpms="ipvsadm resource-agents ldirectord"

    checkrpm $_rpms ||
    runyum $yumargs install $_rpms

    chkconfig --level 345 ipvsadm off > /dev/null 2>&1

    # there's some dumb openssl install bug on
    # centos 4 that we need to do this now before
    # php is insatlled to subvert.
    status_print "Installing 32bit openssl to workaround a dependency bug"
    _rpms="openssl-devel.$arch openssl.$arch openssl097a.$arch"
    checkrpm $_rpms ||
    runyum $yumargs install $_rpms

    status_print "Installing openssl"
    _rpms="openssl-devel openssl"
    checkrpm $_rpms ||
    runyum $yumargs install $_rpms

    status_print "Installing openssl1097a"
    _rpms="openssl1097a"
    checkrpm $_rpms ||
    runyum $yumargs install $_rpms
}

##
# configure YUM
##

function yumconfig {
    status_println "Checking for YUM"

    rpm --quiet -q yum
    if [ $? -gt 0 ]; then
        status_println "Installing yum"
        rpm -ivh \
            https://$rpmhost/iworx/RPMS/noarch/yum-2.0.7-1.noarch.rpm
    fi

    status_print "Updating yum (if needed)"
    runyum -y update yum

    status_println "Installing InterWorx YUM repository"

    if [[ "$iworxrepo" == "alpha" ]]; then
        orig_repo="alpha"
        iworxrepo="beta"
    fi

    wget -O /etc/yum.repos.d/interworx.repo https://updates.interworx.com/iworx/yum/interworx.repo-$iworxrepo > /dev/null 2>&1
    if [[ "$orig_repo" == "alpha" ]]; then
        runyum -y install interworx-alpha-repo
    fi

    if [[ "$testrepo" != "" ]]; then
        wget -O /etc/yum.repos.d/iworx-build-test.repo $testrepo
    fi

    yumargs="-y"
#    if [ $debug -gt 0 ]; then
#       yumargs=''
#    fi

    # the extras and testing repositories are nothing but
    # trouble.
    if [ -d /etc/yum.repos.d ]; then
        rm -f /etc/yum.repos.d/*extras*
        rm -f /etc/yum.repos.d/*testing*
        rm -f /etc/yum.repos.d/*devel*
    fi

    # install remi & update, the one we distribute is older
    runyum -y install remi-release
    runyum -y update remi-release
    setupphprepo
    setupmariarepo
}

function mariaverscheck {
    case "$mariavers" in
        "10.1" | "10.2" | "10.3")

            ;;

        "10.4")
            # Validate we aren't EL6 - MariaDB 10.4+ isn't built for EL6
            if [ "$target" != "rhe7x"] ; then
                error_print_die "MariaDB $mariavers is not supported on $target-based systems"
            fi
            ;;

        "system")
            return 0
            ;;

        *)
            # Failboat
            error_print_die "Unknown or unsupported MariaDB version $mariavers"

    esac
}

function setupmariarepo {
    [[ "$mariavers" == "system" ]] && return

    mariaverscheck

    if [ "mariadist" = "unk" ] ; then
        error_print "Unable to resolve MariaDB yum repo for ${distro}"
        error_print "Using available system version instead"
        return
    fi

    mariaarch=x86

    if [ "$arch" = "x86_64" ] ; then
        mariaarch="amd64"
    fi

    echo "# MariaDB ${mariavers} repository
[mariadb-${mariavers}]
name=MariaDB ${mariavers}
baseurl=http://yum.mariadb.org/${mariavers}/${mariadist}-${mariaarch}
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
" > /etc/yum.repos.d/MariaDB.repo
}

function phpverscheck {
    case "$phpvers" in
        "7.1")
            phprepo=remi-php71 ;;

        "7.2")
            phprepo=remi-php72 ;;

        "7.3")
            phprepo=remi-php73 ;;

        "system")
            return 0
            ;;

        *)
            error_print_die "Unknown or unsupported php version $php"
    esac
}

function setupphprepo {
    [[ "$phpverscheck" == "system" ]] && return

    phpverscheck
    enablerepo $phprepo
}

function enablerepo {
    repo=$@
    # Yum config manager returns true even if the requested repo is bogus
    yum-config-manager --enable "$repo" | grep baseurl 2>&1 > /dev/null
    retval=$?

    if [ "$retval" != "0" ]; then
        echo "Unknown yum repo $repo"
    fi

    return $retval
}

##
# kill any conflicting RPMs from the base system
##

function killconflicts {

    if [ -f .killconflicts ]; then
        return 0
    fi

    #
    # see if we have any conflicts at all

    eval pack_var=\$${target}_conflicts

    header_print "InterWorx-CP needs to remove some packages that may conflict"
    header_print "The following packages will be removed (if they exist)"

    for pack in $pack_var; do
      status_println "- $pack"
    done

    OK=1

    if [ $force_killconflict -eq 0 ]; then
        user_prompt_yn "Is this ok? (Y/n): "
        OK=$?
    fi

    if [ $OK -eq 0 ]; then
        header_print "Aborting InterWorx-CP install...."
        exit;
    fi

    if [ `cat /etc/resolv.conf | egrep -c "nameserver 127.0.0.1"` -gt 0 ]; then
        cp /etc/resolv.conf /etc/resolv.conf.backup
        chmod 644 /etc/resolv.conf.backup
        sed -i 's|nameserver 127.0.0.1|nameserver 8.8.8.8|' /etc/resolv.conf
        resolv=1
    fi

    status_print "Removing conflicting packages"
    runyum $yumargs \
        remove      \
        $pack_var
    if [ $? -gt 0 ]; then
        error_print_die "YUM removed failed.  You may need to manually remove some packages (YUM should give output to aid you)"
    fi

    rpm -e --noscripts bind-chroot > /dev/null 2>&1

    touch .killconflicts
    status_println "Conflict resolution complete"
}

##
# Download and import a rpm gpg file.
##

function rpm_import {
    wget $@ -O - > .gpgtmp 2>/dev/null
    rpm --import .gpgtmp 2>/dev/null
    rm -f .gpgtmp 2>/dev/null
}

##
# grab the relavent gpg keys
##

function gpgkeys {
    status_println "Importing RPM GPG keys"

    gpghost="updates.interworx.com"

    ## always import these
    rpm_import https://$gpghost/iworx/RPM-GPG-KEY-NEXCESS 2> /dev/null
    rpm_import https://$gpghost/redhat/9/en/os/i386/RPM-GPG-KEY 2> /dev/null
}

##
# bring the system up to date
##

function updatesystem {
    ##
    # at this point we have our yum.conf and yum headers
    # installed for this OS, so we can *try* to do a
    # yum update on the rest of the stuff and if it's
    # there (and we have headers generated for it) then
    # it should all 'just work'
    ##

    debug_print_read "About to do a 'yum update' to sync the system"
    status_print "Performing a YUM update to bring the system up to date"
    runyum $yumargs update
    debug_print_read "^^^^ check above for YUM errors"
}

##
# install httpd
##

function httpdinstall {
    debug_print_read "About to install Apache"

    # make sure we backup their httpd.conf if there
    # is one and move it out of the way so that our
    # httpd.conf can be used instead

    # only do this if our httpd isn't already installed

    if [ `rpm -q httpd | egrep -c "iworx"` -eq 0 ]; then
        if [ -f /etc/httpd/conf/httpd.conf ]; then
            mv -f /etc/httpd/conf/httpd.conf \
                /etc/httpd/conf/httpd.conf.iworxsave
        fi
    fi

    # install httpd
    # rht90 has subversion issues since it includes apr
    status_print "Installing the Apache webserver"
    _rpms="httpd httpd-devel mod_ssl apr-devel apr-util-devel"
    checkrpm $_rpms ||
    runyum $yumargs           \
        --exclude httpd-iworx \
        --exclude subversion  \
        --exclude httpd-devel-2.2.3 \
        install               \
        $_rpms

    if [ $? -ne 0 ]; then
        error_print "Apache could not be installed."
        error_print "YUM may have given some reasonable errors and"
        error_print "you can try re-running the installer as it may"
        error_print_die "just be a network and/or update server problem"
    fi

    ##
    # startup apache
    ##
    service httpd stop >/dev/null 2>&1
    service httpd start >/dev/null 2>&1

    chkconfig --level 345 httpd on >/dev/null 2>&1

    # re-check qmail uid/gid (httpd does a useradd)
    qmailcheck
}

##
# install PHP
##

function phpinstall {
    debug_print_read "About to install PHP"

    # install php
    status_print "Installing PHP"
    _rpms="php php-mysql php-gd php-xml php-devel php-cli php-pdo php-mbstring php-xmlrpc php-mhash php-pear"
    checkrpm $_rpms ||
    runyum $yumargs install $_rpms

    if [ $? -ne 0 ]; then
        error_print "PHP could not be installed."
        error_print "YUM may have given some reasonable errors and"
        error_print "you can try re-running the installer as it may"
        error_print_die "just be a network and/or update server problem"
    fi

}

##
# install MySQL
##

function mysqlinstall {

    debug_print_read "About to install MySQL"

    ##
    # install mysql.  the naming scheme has been verified on all major distros.
    ##

    status_print "Installing MySQL server"

    if [ "$target" = "rhe7x" ]; then
        yum install -y mariadb mariadb-server mariadb-devel iptables iptables-services
    fi

    _rpms="mysql mysql-server mysql-devel"
    checkrpm $_rpms ||
    runyum $yumargs install $_rpms
    if [ $? -ne 0 ]; then
        error_print "MySQL could not be installed."
        error_print "YUM may have given some reasonable errors and"
        error_print "you can try re-running the installer as it may"
        error_print_die "just be a network and/or update server problem"
    fi

    ##
    # initialize the system mysql dbs &
    # make sure mysql is running for iworx
    ##
    if [[ -e /etc/init.d/mysql ]]; then
       sed -i '/Initializing MySQL database:/s/--initialize/&-insecure/' /etc/init.d/mysql
    fi
    if [ "$target" = "rhe7x" ]; then
        service mariadb stop >/dev/null 2>&1
        service mariadb start >/dev/null 2>&1
        chkconfig --level 345 mariadb on >/dev/null 2>&1
        ln -s /usr/lib/systemd/system/mariadb.service /usr/lib/systemd/system/mysqld.service
    else
        servicename=mysqld

        if [ -e /etc/init.d/mysql ]; then
            servicename=mysql
        fi

        service $servicename stop >/dev/null 2>&1
        service $servicename start >/dev/null 2>&1
        chkconfig --level 345 $servicename on >/dev/null 2>&1
    fi

    # re-check qmail uid/gid (mysql does a useradd)
    qmailcheck
}


##
# update the local clock and sync it to the
# BIOS clock (good for initial iworx lic activation)
##

function updatetime {
    # don't do on virtuozzo
    if [ ! -f /proc/user_beancounters ]; then

        debug_print_read "About to update the system time"
        rpm --quiet -q ntp
        if [ $? -gt 0 ]; then
            status_print "Installing NTP"
            _rpms="ntp"
            checkrpm $_rpms ||
            runyum $yumargs install $_rpms
        fi

        status_println "Setting server time / syncing BIOS"

        service ntpd stop > /dev/null 2>&1
        ntpdate ntp.interworx.com > /dev/null 2>&1
        hwclock --systohc > /dev/null 2>&1
        service ntpd start > /dev/null 2>&1

        chkconfig --level 345 ntpd on >/dev/null 2>&1
    fi
}

##
# helper functions
##

##
# print an error and die
##

function error_print_die {
    echo
    echo -e "\033[40m\033[001;031mERROR: $@\033[0m"
    echo
    [ -f $LOG ] && tail -n15 $LOG
    exit 1
}

##
# print an error
##

function error_print {
    echo -e "\033[40m\033[001;031mERROR: $@\033[0m"
}

##
# print a warning message
##

function warning_print {
    echo
    echo -e "\033[40m\033[001;033mWARNING: $@\033[0m"
    echo
    sleep 2
}

##
# print a status message
##

function status_println {
    echo -e "\033[40m\033[1m\033[1;35mSTATUS: $@\033[0m"
}

##
# print a status message without newline
##

function status_print {
    echo -e -n "\033[40m\033[1m\033[1;35mSTATUS: $@\033[0m"
}

##
# print a status message and hang out
# for input
##

function status_print_read {
    status_print $@
    [ $headless -eq 0 ] && read
}

##
# print a header (used for making
# things more visible
##

function header_print {
    echo -e "\033[0;40m\033[1;37m\033[1m$@\033[0m"
}

##
# prompt the user, return the result.
##

function user_prompt_yn {
    [ $headless -eq 1 ] && return 1

    echo -e -n "\033[0;40m\033[1;37m\033[1m$@\033[0m"
    read INPUT

    if [ "$INPUT" != 'y' -a "$INPUT" != 'Y' -a "$INPUT" != '' ]; then
        return 0;
    fi

    return 1;
}

##
# print a debug message
##

function debug_print {
    if [ $debug -gt 0 ]; then
        echo
        echo -e "\033[0;32mDEBUG: $@\033[0m"
        echo
    fi
}

##
# print a debug message and then
# chill for a keypress
##

function debug_print_read {
    if [ $debug -gt 0 ]; then
        echo
        echo -e "\033[0;32mDEBUG: $@\033[0m"
        echo -e -n "\033[0;32mDEBUG: Press --ENTER-- to continue... \033[0m"
        [ $headless -eq 0 ] && read
    fi
}

##
# Install the InterWorx-CP RPMs
#
# Use YUM here since otherwise we'd have to RPM
# each package in the correct order, and YUM is
# just better.
##

function iworxinstall {

    yum clean metadata

    ##
    # make sure qmail gets its uids
    ##

    debug_print_read "About to install the Qmail MTA"
    status_print "Installing Qmail"
    _rpms="qmail"
    checkrpm $_rpms ||
    runyum $yumargs install $_rpms

    status_print "Installing vpopmail"
    _rpms="vpopmail"
    checkrpm $_rpms ||
    runyum $yumargs install $_rpms

    status_print "Installing php-iworx, iworx-db-*, and httpd-iworx"
    _rpms="php-iworx iworx-db-* httpd-iworx"
    checkrpm $_rpms ||
    runyum $yumargs install $_rpms

    ldconfigfix

    debug_print_read "About to install the InterWorx-CP core packages"

    status_print "Installing InterWorx-CP"
    _rpms="interworx interworx-smarty interworx-squirrelmail interworx-roundcube interworx-phpmyadmin interworx-horde"
    checkrpm _rpms ||
    runyum $yumargs install $_rpms

    if [ $? -ne 0 ]; then
        error_print "InterWorx-CP could not be installed."
        error_print "YUM may have given some reasonable errors and"
        error_print "you can try re-running the installer as it may"
        error_print "just be a network and/or update server problem"
        error_print ""
        error_print "If after re-running the installer you still"
        error_print "receive an error please open a support ticket at:"
        error_print_die "https://www.interworx.com/support/helpdesk/"
    fi

#    debug_print_read "About to install the optional InterWorx-CP packages"

#    status_print "Installing InterWorx-CP CLI Tools"
#    runyum $yumargs interworx-cli
#
#    status_print "Installing InterWorx-CP Clustering Tools"
#    runyum $yumargs interworx-cluster

    if [ $resolv -eq 1 ]; then
        mv -f /etc/resolv.conf.backup /etc/resolv.conf 2>/dev/null
    fi

    service crond restart >/dev/null 2>&1

    return $?
}

##
# Fix up quota if necessary
#
# for now we only care about:
#
# /
# /home
# /var
#
# we may want to change this later
##

function runquota {

    debug_print_read "About to rebuild the system quotas"
    status_println "Rebuilding system disk quotas"

    cp /etc/fstab /etc/fstab.bak
    awk '$2 ~ /^\/(home|var|chroot)?$/ && $4 !~ /usrquota/ {sub ($4, $4",usrquota")};\
         $2 ~ /^\/(home|var|chroot)?$/ && $4 !~ /grpquota/ {sub ($4, $4",grpquota")};1' /etc/fstab.bak > /etc/fstab

    ##
    ## run quotacheck to re-make the quota files
    which quotaoff >/dev/null 2>&1 || error_print_die "Could not find quotaoff.  Quota tools not installed?"
    which quotacheck >/dev/null 2>&1 || error_print_die "Could not find quotacheck.  Quota tools not installed?"
    quotaoff -a >/dev/null 2>&1
    for part in / /home /var /chroot
      do
      grep -q $part /etc/fstab
      if [ $? = 0 ]; then
          mount -o remount $part 2>/dev/null
          if [ "$LOG_REDIR" = "" ]; then
              quotacheck -cvugmf -F vfsv0 $part 2>&1 | tee -a $LOG 2>&1
          else
              quotacheck -cvugmf -F vfsv0 $part 2>&1 | tee -a $LOG >$LOG_REDIR 2>&1
          fi
      fi
    done
    which quotaon >/dev/null 2>&1 || error_print_die "Could not find quotaon.  Quota tools not installed?"
    quotaon -a >/dev/null 2>&1
}


function spinner {
    local pid=$1
    local delay=0.25
    local spinstr='|/-\'
    while [ "$(ps a 2>/dev/null | awk '{print $1}' | grep $pid)" ]; do
        local temp=${spinstr#?}
        printf " [%c]  " "$spinstr"
        local spinstr=$temp${spinstr%"$temp"}
        sleep $delay
        printf "\b\b\b\b\b\b"
    done
    printf "    \b\b\b\b"
    wait $pid
    return $?
}

function checkrpm {
    if [[ "$dorpmcheck" == "0" ]]; then
        return 1
    fi
    rpm -q --quiet $@
    ret=$?
    if [[ "$ret" == "0" ]]; then
        echo
    fi
    return $ret
}

function runyum {
    if [[ "$debug" == "1" || "$verbose" == "1" ]]; then
        echo
        (yum $@ 2>&1 | tee -a $LOG ; exit ${PIPESTATUS[0]})
        ret=$?
    else
        (yum $@ 2>&1 | tee -a $LOG >$LOG_REDIR 2>&1; exit ${PIPESTATUS[0]}) &
        pid=$!
        spinner $pid
        ret=$?
        echo
    fi
    return $ret
}

##
# kill any unneeded services on the box
##

function killservices {
    [ -f /etc/init.d/yum ] && chkconfig --level 345 yum off >/dev/null 2>&1
    [ -f /etc/cron.daily/yum ] && chmod 000 /etc/cron.daily/yum10111
}

##
# we are so happy!!!
##

function happy {
    distrocheck

    cat <<EOF > /tmp/ili
goiworx install successful:

DISTRO: $release
OPSYS : $opsys
EOF
    mail -s "[GOIWORX] :D" info@interworx.com < /tmp/ili

    rm -f /tmp/ili
}

if [ "$1" = ":D" ]; then
    happy
    exit 0
fi

goiworx

# Copy the release file into release-install, which marks the version installed originally
cp /usr/local/interworx/etc/env/release /usr/local/interworx/etc/env/release-install
cp /usr/local/interworx/etc/env/build /usr/local/interworx/etc/env/build-install

# Archive the log file into interworx's log folder for posterity
cp ${LOG} /usr/local/interworx/var/log/
exit $?
