#!/bin/bash

declare -r fi_update_work="/opt/fiupdate"
declare fi_update_log=''
declare work_curPath=''
declare pro_info="NCE_info"
declare product_dir='/opt/fiupdate/NCE_info'
declare fiweb=''
declare mainOms=''
declare analyzer_scene=''
declare analyzer_scale=''
declare update_config=''
declare real_config=''
declare real_dir=''
declare root_pwd=''
declare admin_pwd=''
declare ossadm_pwd=''
declare mode=''
declare backupOms=''
declare ODAAEplugin=''
declare log_file="post_update.sh.log"
declare -r work_path="/opt/fiupdate"
task_file="post_update_task.log"
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 ossadm password:" ossadm_pwd
echo -e "\n"

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

root_pwd=$(perl -e 'print quotemeta shift(@ARGV)' "${root_pwd}")
ossadm_pwd=$(perl -e 'print quotemeta shift(@ARGV)' "${ossadm_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}`

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" "$@"
}

init_log()
{
    if [ ! -d "$fi_update_work/log" ]
    then
        mkdir "$fi_update_work/log"
    fi
    fi_update_log="$fi_update_work/log/$log_file"
    [ ! -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
}

testossadm()
{
    fi_login_ip=$1

    expect <<END
        spawn ssh -t ossadm@${fi_login_ip} "ifconfig > /dev/null 2>&1"
        expect {
        "*yes/no*" {send "yes\r";exp_continue}
        "assword:" {send "$ossadm_pwd\r"}
        }
        expect {
        "*ermission denie*" {send_user "'ERROR' fi login ossadm password verify failed.\n"
            exit 2}
    }
        set timeout 20
        expect eof
END


    if [[ "$?" == "2" ]]
    then
        return 1
    fi
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] ossadm password is right. "
    log_info "${LINENO}" "ossadm password is right. "
    return 0
}

testroot()
{
    fi_login_ip=$1

    expect <<END
        spawn ssh -t ossadm@${fi_login_ip} "su - root -c 'ifconfig > /dev/null 2>&1'"
        expect {
        "*yes/no*" {send "yes\r";exp_continue}
        "assword:" {send "$ossadm_pwd\r"}
        }
        expect {
        "*yes/no*" {send "yes\r";exp_continue}
        "*assword:" {send "$root_pwd\r"}
        }
        expect {
        "*ermission den*" {send_user "'ERROR' fi login root password verify failed.\n"
            exit 2}
    }
        set timeout 20
        expect eof
END

    if [[ "$?" == "2" ]]
    then
        return 1
    fi
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] root password is right. "
    log_info "${LINENO}" "root password is right. "
    return 0
}

function pdAdmin()
{
    fi_access_ip=$1
    product_name=$2
    rm -rf ${work_path}/ODAESwiftDeployPlugin >/dev/null 2>&1
    ODAEpluginfile=`find ${work_path}/package/ -name "ODAESwiftDeployPlugin*.zip" -type f`
    unzip ${ODAEpluginfile} -d ${work_path}/ODAESwiftDeployPlugin >/dev/null 2>&1
    bash ${work_path}/ODAESwiftDeployPlugin/ODAEDeployTool/lbin/env_profile.sh ${work_path}/ODAESwiftDeployPlugin/ODAEDeployTool >/dev/null 2>&1
    chmod -R 500 ${work_path}/ODAESwiftDeployPlugin/ODAEDeployTool/rtsp/python/bin >/dev/null 2>&1
    chown -R ossadm:ossgroup ${work_path}/ODAESwiftDeployPlugin >/dev/null 2>&1
    cd ${work_path}/py_work
    loginpy=${work_path}/py_work/login_fi.pyc
    if [ -f ${work_path}/py_work/login_fi.py ]
    then
        loginpy=${work_path}/py_work/login_fi.py
    fi
    pythonCmd=${work_path}/ODAESwiftDeployPlugin/ODAEDeployTool/rtsp/python/bin/python

    expect <<END
        spawn su ossadm -c "${pythonCmd} ${loginpy} $fi_access_ip $product_name"
        expect {
        "*assword:" {send "$admin_pwd\r"}
        }
        set timeout 100
        expect eof
END

}

function testAdmin()
{
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] start to check FI web admin password"
    log_info "${LINENO}" "start to check FI web admin password"
    cd /opt
    pdAdmin $1 $2 > ${work_path}/log/TestPd.log

    if [ ! -f "${work_path}/log/TestPd.log" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] test passwd log file not exists,can not check passwd is right or not"
        log_error "${LINENO}" " test passwd log file not exists,can not check passwd is right or not"
        return 1
    fi
    
    admin_result=`cat ${work_path}/log/TestPd.log|grep "Test to login FI success,password is right"`
    if [ -z "${admin_result}" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] FI web admin password is wrong ,please enter the right password"
        log_error "${LINENO}" " FI web admin password is wrong ,please enter the right password "
        return 1
    fi
    
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] FI web admin password is right"
    log_info "${LINENO}" "FI web admin password is right"
    
    if [ -f "/tmp/CheckPd.log" ]
    then
        rm -f /tmp/CheckPd.log
    fi    
    return 0
}

function set_premeters()
{
    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
    mainOms=`cat /opt/fiupdate/NCE_info/nodes_${product_name}.ini |grep mainOms= |sed 's/mainOms=//g'`
    analyzer_scene=`cat /opt/fiupdate/NCE_info/nodes_${product_name}.ini|grep feature |sed 's/feature=//g'|awk -F ';' '{print $1}'`
    analyzer_scene=`echo $analyzer_scene | tr A-Z a-z`
    analyzer_scale=`cat /opt/fiupdate/NCE_info/nodes_${product_name}.ini|grep feature |sed 's/feature=//g'|awk -F ';' '{print $2}'`
    analyzer_scale=`echo $analyzer_scale | tr A-Z a-z`
    fiweb=`cat /opt/fiupdate/NCE_info/nodes_${product_name}.ini|grep fiweb | sed  's/fiweb=//g'`
    mode=`cat /opt/fiupdate/NCE_info/nodes_${product_name}.ini |grep mode= |sed 's/mode=//g'`
    
    if [ "$mode" == "double" ]
    then
        backupOms=`cat /opt/fiupdate/NCE_info/nodes_${product_name}.ini |grep backupOms= |sed 's/backupOms=//g'`
    fi
    return 0
     
}

isprocess()
{
    # check the commit log.
    expect <<END
            spawn ssh -t root@${mainOms} "ps -ef | grep commit_fi_update.sh | grep -v 'grep' > /opt/fiupdate/log/checkcommit.txt"
            expect {
            "*yes/no*" {send "yes\r";exp_continue}
            "assword:" {send "$root_pwd\r"}
            }
            set timeout 60
            expect eof
END

    expect <<END
            spawn scp -p root@${mainOms}:/opt/fiupdate/log/checkcommit.txt /opt/fiupdate/log/
            expect {
            "*yes/no*" {send "yes\r";exp_continue}
            "assword:" {send "$root_pwd\r"}
            }
            set timeout 60
            expect eof
END

    if [ ! -f "/opt/fiupdate/log/checkcommit.txt" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] checkcommit not exists. "
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] checkcommit not exists. " >> $fi_update_log
        return 1
    fi
    checkcommit=`cat /opt/fiupdate/log/checkcommit.txt | grep 'commit_fi_update.sh'`
    if [ ! -n "$checkcommit" ]
    then
        log_info "${LINENO}" "check commit process not exists.: try again. "
        return 1
    fi
    return 0

}

excCommit()
{
    expect <<END
        set timeout 30
        log_user 0
        spawn ssh root@${mainOms}
        expect {
            "*yes/no*" {send "yes\r";exp_continue}
            "*assword*" {send "$root_pwd\r"}
        }
        expect {
            "*#*" {send "(echo '$admin_pwd') | $do_work\r"}
        }
        expect {
            "*#*" {send "exit\r"}
        }
END

}

DoCommit()
{
    docommit_result=`cat ${fi_update_log} | grep "commit update FI success"`
    if [ "x${docommit_result}" != "x" ]
    then
        return 0
    fi
    mainOms=$1
    fiweb=$2
    do_work="nohup bash /opt/fiupdate/tools/commit_fi_update.sh $fiweb &"
    excCommit
    sleep 5
    isprocess
    excCommitresult=$?
    for ((j=1;j<=60;j++))
    do
        if [ $excCommitresult -ne 0 ]
        then
            echo "[`date '+%Y-%m-%d %H:%M:%S'`]---check commit process not exists, sleep 5s then retry..." >> $fi_update_log
            excCommit
            sleep 5
            isprocess >> $fi_update_log
            excCommitresult=$?
        else
            break
        fi
    done

    for ((i=1;i<=1440;i++))
    do
        sleep 5
        expect <<END
            set timeout 30
            spawn ssh -t ossadm@${mainOms} "tail -1 /tmp/fiupdate/fiupdate.log"
            expect {
                "*assword*" {send "$ossadm_pwd\r"}
            }
            expect {
                "*FI update commit success*" {exit 0}
                "*FI update commit failed*" {exit 1}
            }
            exit 2
END
        ret=$?
        if [ $ret -eq 2 ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] commit fi update is running..."
            continue
        fi
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] commit fi update is finished, ret is $ret"
        return $ret
    done
    
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] commit fi update is timeout."
    return 1
}

locksafe()
{
    product_name=$1
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name : all FI nodes need to restore safe mode "
    log_info "${LINENO}" " $product_name : all FI nodes need to restore safe mode "
    if [ ! -f "/opt/fiupdate/safelock.sh" ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name : restore safe mode script not exists"
        log_error "${LINENO}" " $product_name : restore safe mode script not exists "
        return 1
    fi
    
    cd /opt/fiupdate
    expect <<END
    spawn  bash safelock.sh
    expect "*assword:"
    send "$root_pwd\r"
    set timeout -1
    expect eof
END
   
    return 0
}

function CheckPwd()
{

    if [[ $root_pwd =~ " " ]]
    then
        echo "[`date '+%Y-%m-%d %H:%M:%S'`] the root password you input is valid" 
        return 1
    fi
    if [[ $ossadm_pwd =~ " " ]]
    then
        echo "[`date '+%Y-%m-%d %H:%M:%S'`] the ossadm password you input is valid"
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] the ossadm password you input is valid" >> $fi_update_log
        return 1
    fi
    
       
    return 0
    
}

function CheckUser()
{
    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"
        log_error "${LINENO}" "run user must be root"
        return 1
    fi
    return 0
}


function runpost()
{
    runpost_result=`cat ${fi_update_log} | grep "Postwork Run Success"`
    if [ "x${runpost_result}" != "x" ]
    then
        return 0
    fi
    product_name=$1
    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_name : run ODAE post script in ${mainOms}"
    log_info "${LINENO}" " $product_name : run ODAE post script in ${mainOms}"
    expect <<END
        spawn ssh -t root@${mainOms} " cd /opt/fiupdate;bash post_update_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 -1
        expect eof
END

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

function Unlock()
{
    cd /opt/fiupdate
    expect <<END
    spawn bash safeunlock.sh
    expect {
        "please input ossadm password:" {send "$ossadm_pwd\r"}
    }
    expect {
        "please input root password:" {send "$root_pwd\r"}
    }
    expect {
        "please input FI admin password:" {send "$admin_pwd\r"}
    }
    set timeout -1
    expect "*#"
    exit
END
}

function unset_parameters()
{
    unset admin_pwd
    unset root_pwd
    unset fiweb
}

function ClearPackage()
{
    if [ -d ${fi_update_work} ]
    then
        cd /opt
        rm -rf ${fi_update_work}
    fi
}

Main()
{
    log_info "${LINENO}" "post work for update fi to 8.0.2.1"
    CheckUser
    if [ $? -ne 0 ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] check run user failed"
        log_error "${LINENO}" "check run user failed"
        return 1
    fi
    
    CheckPwd    
    if [ $? -ne 0 ]
    then
        echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] check input password failed"
        log_error "${LINENO}" "check input password failed"
        return 1
    fi
    product_all=`find $product_dir/ -name "node*.ini" -type f`
    for product_ini in ${product_all}
    do
    {
        product_one=$(basename $product_ini .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 $product_ini|grep 'postwork=0'`
        if [ -n "${break_out}" ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] config show $product_one product break postwork stage"
            log_info "${LINENO}" " config show $product_one product break postwork stage"
            continue
        else
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] config show $product_one product not break postwork stage"
            log_info "${LINENO}" " config show $product_one product not break postwork stage"
        fi
        set_premeters $product_one
        if [ $? -ne 0 ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_one: postwork set parameters failed"
            log_error "${LINENO}" "postwork set parameters failed"
            return 1
        fi
        testossadm $mainOms
        if [ $? -ne 0 ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] \033[41;37m ERROR: ossadm password is wrong ,please enter the right password. \033[0m "
            log_error "${LINENO}" "ERROR: ossadm password is wrong ,please enter the right password. "
            return 1
        else
            testroot $mainOms
            if [ $? -ne 0 ]
            then
                echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] \033[41;37m ERROR: root password is wrong ,please enter the right password. \033[0m "
                log_error "${LINENO}" "ERROR: root password is wrong ,please enter the right password. "
                return 1                
            fi
        fi
        testAdmin ${fiweb} ${product_one}
        if [ $? -ne 0 ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] \033[41;37m ${product_one} FI web admin password check failed, please input the right FI web admin password\033[0m"
            log_error "${LINENO}" "FI web admin password check failed "
            return 1
        fi
        # 如果和NCE并行升级，有可能FI升级期间root又被禁止登录了，重新启用root登录来修改FI参数
        Unlock
        unlockResult=`cat ${fi_update_work}/log/unlock_safe.log | grep "script in stage unlock all FI nodes success"`
        if [ "x${unlockResult}" == "x" ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] \033[41;30m Safe unlock is failed. \033[0m"
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] Safe unlock is failed." >> $fi_update_log
            return 1
        else
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] \033[42;34m Safe unlock is success. \033[0m"
        fi
        DoCommit $mainOms $fiweb
        if [ $? -ne 0 ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] commit update FI failed with NCE product $product_one, mainOms is $mainOms"
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] commit update FI failed with NCE product $product_one, mainOms is $mainOms" >> ${fi_update_log}
            return 1
        else
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] commit update FI success with NCE product $product_one, mainOms is $mainOms"
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] commit update FI success with NCE product $product_one, mainOms is $mainOms" >> ${fi_update_log}
        fi

        runpost  $product_one
        if [ $? -ne 0 ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] $product_one: postwork run odae confirm script failed"
            log_error "${LINENO}" " $product_one: postwork run odae confirm script failed"
            return 1
        fi

        rm -rf iptmp.conf > /dev/null 2>&1
        cat /opt/fiupdate/NCE_info/nodes_${product_one}.ini |grep finode= |sed 's/finode=//g' >>./iptmp.conf
        cat /opt/fiupdate/NCE_info/nodes_${product_one}.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 -1
                expect eof
END

        expect <<END
                spawn ssh -t root@${fi_node} "cd /opt/ ; bash pre_config.sh postclear ; rm -rf /opt/pre_config.sh > /dev/null 2>&1"
                expect {
                "*yes/no*" {send "yes\r";exp_continue}
                "assword:" {send "$root_pwd\r"}
                }
                set timeout -1
                expect eof
END
    
        done
        rm -rf iptmp.conf > /dev/null 2>&1
    }
    done

    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"
        locksafe $product_one
        if [ $? -ne 0 ]
        then
            echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`]  $product_one: postwork lock all FI nodes failed"
            log_error "${LINENO}" " $product_one: postwork lock all FI nodes failed"
            return 1
        fi
    }
    done    

    echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] \033[42;34m Postwork run success \033[0m"
    log_info "${LINENO}" "postwork run success"
    
    ClearPackage
    
    return 0

}


get_cur_path
cd "${work_curPath}"
init_log || return $?

echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] Start to post upgrade FusionInsight..."
echo -e "\n[`date '+%Y-%m-%d %H:%M:%S'`] Start to post upgrade FusionInsight..." >> $fi_update_log

Main
mainresult=$?
unset_parameters
exit $mainresult
