#!/bin/bash

root_dir="$(dirname $(readlink -f $(dirname $0)))"
rpm_dir="$root_dir/repo"
os_version=$(uname -r | cut -d - -f 1)
#生产安装标准路径，不能随意修改
LOG_PATH="/var/log/pangea_internal_upgrade/"
LOG_FILE="/var/log/pangea_internal_upgrade/base_upgrade.log"
build_os_type="Euler"
function log()
{
    if [ ! -d "$LOG_PATH" ]; then
        mkdir "$LOG_PATH"
    fi

    if [ ! -f "$LOG_FILE" ]; then
        touch "$LOG_FILE"
    fi

    chmod 640 "$LOG_FILE"
    echo "$(date +"[%Y-%m-%d %H:%M:%S,%N]") [$0:${BASH_LINENO}] [$1]: [PCIEINF] $2" >> ${LOG_FILE}
}

#设置升级进度:覆盖写
function set_process()
{
    cd $root_dir/action
    if [ ! -e "process.txt" ]; then
        echo "$1%" > process.txt
    fi
    chmod 640 process.txt
    echo "$1%" > process.txt
    log "INFO" "install rpm current process $1."
}
#获取升级状态
function get_upgradestatus()
{
    cd $root_dir/action
    if [ ! -e "process.txt" ]; then
        log "ERR" "process.txt not exist"
        echo "failure"
        return 1
    fi
	#增加重试:smartkit升级时，升级脚本转后台操作时，记录升级文件进度和查询进度同时进行，可能会导致process.txt里的文件内容不完整
    #策略对齐:当读取内容不是对应关键字就重试,每次sleep 1s,超时时间10s
    for((i=1;i<=10;i++)); do
        STATUS=`cat process.txt`
        if [ "$STATUS"x = "success%"x ] ||  [ "$STATUS"x = "failure%"x ] || [[ "$STATUS"x = upgrading*%x ]]; then
            #删除%输出,STATUS变量值不变
            echo "${STATUS/\%}"
            log "INFO" "cur upgrade status $STATUS"
            return 0
        fi
        log "INFO" "get progress retry index: $i"
        sleep 1
    done

    echo "failure"
    log "ERR" "get upgrade status failed"
    return 1
}
#1.判断os类型
function CheckOsType()
{
    current_os_type="Euler"
    # 先判断uvp文件是否存在,存在才能获取内容,否则屏显会打印文件不存在,smartkit工具识别不了
    if [ -f "/etc/uvp_version" ];then
        if [ $(cat /etc/uvp_version |wc -l) -ne 0 ];then
            current_os_type="Uvp"
        fi
    fi
    if [ "$build_os_type" != "$current_os_type" ]; then
        log "ERR" "Current os type is $current_os_type, build os type is $build_os_type, not match."
        #打印到屏显,便于现网定位
        echo "failure"
        echo "reason: Current os type is $current_os_type, build os type is $build_os_type, not match."
        exit 1
    fi
}
#2.判断内核版本
function CheckKernelVersion() {
    cd ${rpm_dir}
    log "INFO" "Check base rpms kerner version start."
    cur_kernel_ver=$(uname -r)

    rpms_list=$(ls | grep rpm)
    for rpm_pkg in $rpms_list; do
        # 提取包含内核版本信息的行
        kernel_info_line=$(rpm -qi $rpm_pkg | grep kernel)

        # 检查是否是v2r9版本, v2r9的h版本之间不兼容，需要细分
        if [[ $kernel_info_line == *".eulerosv2r9."* ]]; then
            # 获取形如 h171.eulerosv2r9.aarch64 的版本号
            rpm_pkg_kernel=$(echo $kernel_info_line | awk '{print $8}' | awk -F '.' '{print $(NF-2)"."$(NF-1)"."$NF}')
        else
            # 获取形如 eulerosv2r12.aarch64 的版本号
            rpm_pkg_kernel=$(echo $kernel_info_line | awk '{print $8}' | awk -F '.' '{print $(NF-1)"."$NF}')
        fi

        # 检查版本号是否匹配
        if [[ "$cur_kernel_ver" != *"$rpm_pkg_kernel"* ]]; then
            rpm_name=$(echo $rpm_pkg | cut -d '-' -f 2)
            log "ERR" "Current kernel version is $cur_kernel_ver, $rpm_name rpm kernel ver is $rpm_pkg_kernel, not match."
            log "ERR" "IF YOU INSTALL IT, THE OS WILL CRASH !!!!!!!!"
            # 打印到屏显,便于现网定位
            echo "failure"
            echo "reason: Current kernel version is $cur_kernel_ver, $rpm_name rpm kernel ver is $rpm_pkg_kernel, not match."
            exit 1
        fi
    done
    log "INFO" "Check base rpms kerner version end."
    return 0
}
# 脚本入口处理
case $1 in
    "UpgradeVersion")
        ## os type check
        CheckOsType
        ## kernel version check
        CheckKernelVersion
        ##update
        cd $root_dir/action
        #升级动作转后台后返回sucess后就会来查询升级状态,此时process.txt可能在后台还未创建,就会返回失败
        set_process "upgrading 0"
        setsid sh update_knl.sh 1>/dev/null 2>&1 &
        if [ $? -ne 0 ]; then
            echo "failure"
        else
            echo "success"
        fi
        ;;
    "GetUpgradeStatus")
        get_upgradestatus
        ;;
    *)
    echo "Usage: $0 {UpgradeVersion|GetUpgradeStatus}"
    exit 1
    ;;
esac
