#!/bin/bash

declare -r fi_update_work="/opt/fiupdate"
declare fi_update_log=''
declare work_curPath=''
declare product_dir='/opt/fiupdate/NCE_info'
declare root_pwd=''
declare admin_pwd=''
declare mainoms=''
declare ODAAEplugin=''
declare SysVer
declare cpu
declare fi_version=''

TMOUT=0
User_ID=`/usr/bin/id -u`
if [ $User_ID -ne 0 ] 
then
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] run user must be root"
    exit 1
fi

read -s -p "please input root password:" root_pwd
echo -e "\n"

read -s -p "please input admin password:" admin_pwd
echo -e "\n"

root_pwd=$(perl -e 'print quotemeta shift(@ARGV)' "${root_pwd}")
admin_pwd=$(perl -e 'print quotemeta shift(@ARGV)' "${admin_pwd}")

ODAAEpluginfile=`find ${fi_update_work}/package/ -name "ODAESwiftDeployPlugin*.zip" -type f`
ODAAEplugin=`basename ${ODAAEpluginfile}`
SysVerInfo=`cat /etc/os-release`
if [[ "$SysVerInfo" =~ "SLES" ]]; then
    echo "[`date '+%Y-%m-%d %H:%M:%S'`] system is SUSE"
    SysVer="SUSE"
elif [[ "$SysVerInfo" =~ "EulerOS" ]]; then
    echo "[`date '+%Y-%m-%d %H:%M:%S'`] system is EulerOS"
    SysVer="EulerOS"
else
    echo "[`date '+%Y-%m-%d %H:%M:%S'`] system is not SUSE,is not EulerOS"
    echo "[`date '+%Y-%m-%d %H:%M:%S'`] FI cannot update"
    exit 1
fi
cpu=`uname -a`
if [[ "$cpu" =~ "aarch64" ]]; then
    cpu="ARM"
else
    cpu="x86"
fi

function get_cur_path()
{
    cd "$(dirname "${BASH_SOURCE-$0}")"
    work_curPath="${PWD}"
    fi_scriptName="$(basename "${BASH_SOURCE-$0}")"
    cd - >/dev/null
}

logDef()
{
    local funcName="$1"; shift
    local logLevel="$1"; shift
    local lineNO="$1"; shift

    local logTime="$(date -d today +'%Y-%m-%d %H:%M:%S')"
    printf "[${logTime}] ${logLevel} $* [${g_scriptName}(${funcName}):${lineNO}]($$)\n" \
        >> "${fi_update_log}" 2>&1
}

log_error()
{
    logDef "${FUNCNAME[1]}" "ERROR" "$@"
}

log_info()
{
    logDef "${FUNCNAME[1]}" "INFO" "$@"
}

function init_log()
{
    if [ ! -d "$fi_update_work/log/" ]
    then
        mkdir "$fi_update_work/log/"
    fi
    
    fi_update_log="$fi_update_work/log/precheck_sizelicense_work.log"
    [ ! -f "${fi_update_log}" ] && touch "${fi_update_log}"
    chmod 600 "${fi_update_log}"
    echo > ${fi_update_log}
    
}

trap 'onCtrlC' INT
function onCtrlC () {
    echo 'exit program'
    exit 1
}

function check_fi_license()
{
    cd ${fi_update_work}/py_work
    pyCmd=${fi_update_work}/ODAESwiftDeployPlugin/ODAEDeployTool/rtsp/python/bin/python
    check_license_path=${fi_update_work}/py_work/check_license.pyc
    if [ -f "${fi_update_work}/py_work/check_license.py" ];then
        check_license_path=${fi_update_work}/py_work/check_license.py
    fi
    
    expect <<END
                spawn su - ossadm -c "${pyCmd} ${check_license_path} $fi_access_ip"
                expect {
                "*assword:" {send "$admin_pwd\r"}
    }
                set timeout 120
                expect eof
                catch wait ret
                set exit_status [lindex \$ret 3]
                exit \$exit_status
END
}

function runcheck()
{
    product_name=$1

    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name:  start to do FI syscheck work "
    log_info "${LINENO}" "$product_name: start to do FI syscheck work "
    expect <<END
            spawn ssh -t root@${mainOms} "cd /opt/fiupdate ; bash sys_check_fi.sh"
            expect {
            "*yes/no*" {send "yes\r";exp_continue}
            "assword:" {send "$root_pwd\r"}
            }
            expect "*assword:"
            send "$root_pwd\r"
            expect "*assword:"
            send "$admin_pwd\r"
            set timeout 1800
            expect eof
END

    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name: start to get FI syscheck result "
    log_info "${LINENO}" "$product_name: start to get FI syscheck result "
    expect <<END
            spawn scp -p root@${mainOms}:/opt/fiupdate/log/syscheck_fi.log  /opt/fiupdate/log/
            expect {
            "*yes/no*" {send "yes\r";exp_continue}
            "assword:" {send "$root_pwd\r"}
            }
            set timeout 180
            expect eof
END
    
    if [ ! -f "/opt/fiupdate/log/syscheck_fi.log" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name: FI SysCheck Run Failed "
        log_error "${LINENO}" "$product_name: FI SysCheck Run Failed "
        return 1
    fi
    
    runresult=`cat /opt/fiupdate/log/syscheck_fi.log | grep 'run syscheck script success'`
    
    if [ ! -n "$runresult" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name: FI SysCheck Run Failed "
        log_error "${LINENO}" "$product_name: FI SysCheck Run Failed "
        return 1
    fi
    
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name: FI SysCheck Run Success "
    log_info "${LINENO}" "$product_name: FI SysCheck Run Success "

    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name: start to check fi license status."
    log_info "${LINENO}" "$product_name: start to check fi license status."

    check_fi_license > ${fi_update_work}/log/check_fi_license.log

    return 0

}

function scpfile()
{
    product_name=$1
    if [ ! -f "/opt/fiupdate/NCE_info/nodes_${product_name}.ini" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name: FI nodes config file not exists,please check"
        log_error "${LINENO}" "$product_name: platform nodelist json not exists,please check"
        return 1
    fi
    
    if [ ! -f "${fi_update_work}/package/${ODAAEplugin}" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name: ODAAE plugin package not exists,please check"
        log_error "${LINENO}" "$product_name: ODAAE plugin package not exists,please check"
        return 1
    fi
    

    
    mainOms=`cat /opt/fiupdate/NCE_info/nodes_${product_name}.ini |grep mainOms= |sed 's/mainOms=//g'`
    fi_access_ip=`cat /opt/fiupdate/NCE_info/nodes_${product_name}.ini |grep fiweb|sed 's/fiweb=//g'`
    fi_version=`cat /opt/fiupdate/NCE_info/nodes_${product_name}.ini |grep fi_version= |sed 's/fi_version=//g'`
    
    if [ "${fi_version}" != "6512" ] && [ "${fi_version}" != "6516" ] && [ "${fi_version}" != "6517" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name: FI version is not 6.5.1.2 or 6.5.1.6 or 6.5.1.7"
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] \033[41;37m ${product_name} : FI version is not 6.5.1.2 or 6.5.1.6 or 6.5.1.7\033[0m"
        log_info "${LINENO}" "$product_name: FI version is not 6.5.1.2 or 6.5.1.6 or 6.5.1.7" 
        return 1        
    fi
    FI_Version=`echo ${fi_version} | sed -r 's/^(.{1})(.{1})(.{1})(.{1})$/\1.\2.\3.\4/g'`
    
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name: FI version is ${FI_Version} ,need to install patch to FI version 8.0.2.1"
    log_info "${LINENO}" "$product_name: FI version is ${FI_Version} ,need to install patch to FI version 8.0.2.1" 
    expect <<END
    spawn ssh -t root@${mainOms} "rm -rf /opt/fiupdate > /dev/null 2>&1 ; rm -rf /opt/fiupgrade > /dev/null 2>&1"
    expect {
    "*yes/no*" {send "yes\r";exp_continue}
    "assword:" {send "$root_pwd\r"}
    }
    set timeout -1
    expect eof
END
    
    expect <<END
    spawn scp -p -r /opt/fiupdate/ root@${mainOms}:/opt
    expect {
    "*yes/no*" {send "yes\r";exp_continue}
    "assword:" {send "$root_pwd\r"}
    }
    set timeout -1
    expect eof
END
    
    expect <<END
    spawn scp -p /opt/fiupdate/NCE_info/nodes_${product_name}.ini root@${mainOms}:/opt/fiupdate/conf/nodes.ini
    expect {
    "*yes/no*" {send "yes\r";exp_continue}
    "assword:" {send "$root_pwd\r"}
    }
    set timeout -1
    expect eof
END

    expect <<END
    spawn ssh -t root@${mainOms} "chown -R ossadm:ossgroup /opt/fiupdate"
    expect {
    "*yes/no*" {send "yes\r";exp_continue}
    "assword:" {send "$root_pwd\r"}
    }
    set timeout -1
    expect eof
END

    return 0
}

function precheck_size()
{
    product_name=$1
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name:  start to check disk size. "
    log_info "${LINENO}" "$product_name: start to check disk size. "

    rm -rf iptmp.conf > /dev/null 2>&1
    rm -rf /opt/fiupdate/log/checksize.log > /dev/null 2>&1
    cat /opt/fiupdate/NCE_info/nodes_${product_name}.ini |grep finode= |sed 's/finode=//g' >>./iptmp.conf
    cat /opt/fiupdate/NCE_info/nodes_${product_name}.ini |grep Analyzer_Calc_Storage | awk -F "=" {'print $2'} >>./iptmp.conf
    fi_nodes=`sort -u iptmp.conf`
    for fi_node in ${fi_nodes}
    do
        expect <<END
                spawn scp -p /opt/fiupdate/pre_config.sh root@${fi_node}:/opt
                expect {
                "*yes/no*" {send "yes\r";exp_continue}
                "assword:" {send "$root_pwd\r"}
                }
                set timeout 180
                expect eof
END
    
        expect <<END
                spawn ssh -t root@${fi_node} "cd /opt/ ; bash pre_config.sh checkoptsize"
                expect {
                "*yes/no*" {send "yes\r";exp_continue}
                "assword:" {send "$root_pwd\r"}
                }
                expect {
                    "*opt is not enough*" {exit 3}
                }
                exit 2
END

        checkoptresult=$?

        expect <<END
                spawn ssh -t root@${fi_node} "cd /opt/ ; bash pre_config.sh checktmpsize ; rm -rf /opt/pre_config.sh > /dev/null 2>&1"
                expect {
                "*yes/no*" {send "yes\r";exp_continue}
                "assword:" {send "$root_pwd\r"}
                }
                expect {
                    "*tmp is not enough*" {exit 6}
                }
                exit 2
END

        checktmpresult=$?
        if [ $checkoptresult -eq 3 -a $checktmpresult -eq 6 ]
        then
            echo -e "$product_name: The /opt size is not enough 40G and the /tmp size is not enough 8.5G on node ${fi_node}." >> /opt/fiupdate/log/checksize.log
        elif [ $checkoptresult -eq 3 -a $checktmpresult -ne 6 ]
        then
            echo -e "$product_name: The /opt size is not enough 40G on node ${fi_node}." >> /opt/fiupdate/log/checksize.log
        elif [ $checkoptresult -ne 3 -a $checktmpresult -eq 6 ]
        then
            echo -e "$product_name: The /tmp size is not enough 8.5G on node ${fi_node}." >> /opt/fiupdate/log/checksize.log
        fi
    done
    if [ -f /opt/fiupdate/log/checksize.log ]
    then
        checksizeresult=`cat /opt/fiupdate/log/checksize.log | grep 'not enough'`
        if [ -n "$checksizeresult" ]
        then
            log_error "${LINENO}" "$product_name precheck the disk size is abnormal, please check in /opt/fiupdate/log/checksize.log."
            return 1
        fi
    fi
    rm -rf iptmp.conf > /dev/null 2>&1
    log_info "${LINENO}" "$product_name precheck the disk size is normal."
    return 0

}

function unset_parameters()
{
    unset root_pwd
    unset admin_pwd
}


function Main()
{
    log_info "${LINENO}" "start to update fi to 8.0.2.1"
    log_info "${LINENO}" "start to output product info"
    if [ ! -d "$product_dir" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] product conf dir not exists ,please run safeunlock.sh"
        log_error "${LINENO}" "product conf dir not exists ,please run safeunlock.sh"
        return 1
    fi
    product_all=`find $product_dir/ -name "node*.ini" -type f`
    for i in ${product_all}
    do
    {
        product_one=$(basename $i .ini|sed 's/nodes_//g')
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] Start to do $product_one product"
        log_info "${LINENO}" "Start to do $product_one product"
        break_out=`cat $i|grep 'syscheck=0'`
        if [ -n "${break_out}" ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] config show $product_one product break syscheck stage"
            log_info "${LINENO}" " config show $product_one product break syscheck stage"
            continue
        else
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] config show $product_one product not break syscheck stage"
            log_info "${LINENO}" " config show $product_one product not break syscheck stage"
        fi

        scpfile $product_one
        if [ $? -ne 0 ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_one: syscheck scp files failed"
            log_error "${LINENO}" " $product_one: syscheck scp files failed"
            return 1
        fi
        precheck_size $product_one
        if [ $? -ne 0 ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`]  $product_one: precheck the disk sizes are not enough, please check."
            log_error "${LINENO}" " $product_one: precheck the disk sizes are not enough, please check."
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`]  $product_one: The FI nodes disk size is abnormal, please check in /opt/fiupdate/log/checksize.log."
            log_error "${LINENO}" " $product_one: The FI nodes disk size is abnormal, please check in /opt/fiupdate/log/checksize.log."
        fi
        runcheck $product_one
        if [ $? -ne 0 ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`]  $product_one: FI check disk size and license failed"
            log_error "${LINENO}" " $product_one: FI check disk size and license failed"
            return 1
        fi
    chown -R ossadm:ossgroup ${fi_update_work}/log/
    }
    done
    
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] script in stage Checkdisklicense all FI system success"
    log_info "${LINENO}" "script in stage Checkdisklicense all FI system success"
    
    return 0
}



get_cur_path
cd "${work_curPath}"

init_log || return $?

Main
mainresult=$?
unset_parameters
exit $mainresult



