{
    "name"  : "N18K数据库泄漏检测",
    "precondition" : ["isFix"],
    "problems" : {
        "upload_yes" : {
            "desc"      : "",
            "advice"    : "【建议】问题已经自动修复，可连接到设备上确认是否修复成功"
        },
        "upload_no" : {
            "desc"      : "【问题】N18K版本存在数据库泄漏问题",
            "advice"    : "【建议】修复数据库泄漏问题"
        },
        "upload_skip" : {
            "desc"      : "",
            "advice"    : "【提示】N18K版本不存在问题"
        },
        "upload_fail" : {
            "desc"      : "【问题】N18K数据库泄漏检测-主从管理板切换失败",
            "advice"    : "【建议】检查手动切换主从管理板能否成功，再重新修复"
        },
        "start_fail" : {
            "desc"      : "【问题】N18K数据库泄漏检测-启动进程失败",
            "advice"    : "【建议】请查看/sbin/pgsql_daily是否存在，若不存在请确认是否tipc主从管理板传输文件失败"
        },
        "tftp_fail" : {
            "desc"      : "【问题】N18K数据库泄漏检测-tftp从工具传输文件到设备失败",
            "advice"    : "【建议】请检查tftp端口(69)是否防火墙被禁用或者被其他tftp软件占用！或其他原因可手动tftp本地文件到设备查看具体失败原因"
        },
        "getversion_fail" : {
            "desc"      : "【问题】N18K数据库泄漏检测-获取版本号失败",
            "advice"    : "【建议】手动show version detail查看版本号是否存在"
        },
        "file_fail" : {
            "desc"      : "【问题】N18K数据库泄漏检测-/data/pgsql_daily文件不存在",
            "advice"    : "【建议】请检查从主管理板拷贝到从管理板/data/pgsql_daily失败原因"
        }
    }
}
---------------------------code-------------------------------
#极简数据库泄漏问题影响版本
versionList = ['N18000_RGOS 11.5(1)B2','N18000_RGOS 11.5(1)B2T1','N18000_RGOS 11.5(1)B2T2','N18000_RGOS 11.5(1)B2T3','N18000_RGOS 11.0(1)B2T12','N18000_RGOS 11.0(1)B3','N18000_RGOS 11.0(1)B3T1','N18000_RGOS 11.0(1)B3T2','N18000_RGOS 11.0(4)B12T1','N18000_RGOS 11.0(1)B4','N18000_RGOS 11.0(1)B5']

precondition_result = 'pass'
precondition_message = ''
precondition_message_advice = ''

#要加载的定期清理的脚本名
file_name = 'pgsql_daily'

#执行log
log_version = cli('show version detail')
log_versionList = log_version.split('\r\n')
log_slot = cli('show version slot')
log_slotList = log_slot.split('\r\n')

#用户不同意检查
isFixed = precondition('isFix')
if !isFixed || isFixed == undefined :
	precondition_result = 'fail'
	precondition_message = '用户只检查是否是数据库泄漏版本！'
	precondition_message_advice = '用户只检查是否是数据库泄漏版本！'
	set_share_value('precondition_result',precondition_result)
	set_share_value('precondition_message',precondition_message)
	set_share_value('precondition_message_advice',precondition_message_advice)
    #检测到是数据库泄漏版本
    if isPgsqlLeakVersion():
        add_problem('upload_no')
        change_title('检测出是N18K数据库泄漏版本')
        return 'warn'
    else:
        add_problem('upload_skip')
        change_title('检测出非故障版本')
        return 'warn'
    end
end

#判断是否数据库泄漏版本
if !isPgsqlLeakVersion():
    precondition_result = 'fail'
	precondition_message = '检测出非数据库泄漏版本'
	precondition_message_advice = '检测出非数据库泄漏版本'
	set_share_value('precondition_result',precondition_result)
	set_share_value('precondition_message',precondition_message)
	set_share_value('precondition_message_advice',precondition_message_advice)
	add_problem('upload_skip')
    change_title('检测出非故障版本')
    return 'warn'
end

#循环加载每个主管理板和每个从管理板的脚本
if isTipcCopySucc():
    all_start = 1
    reg_cm = /(\d+)\s+(M\d+)\s+\d+/
    foreach card in log_slotList:
        if card.indexOf('master') != -1 || card.indexOf('candidate') != -1 || card.indexOf('backup') != -1:
            r = card.match(reg_cm)
            if r != null:
                dev = r[1]
                slot = r[2]
                #进入从管理板
                if card.indexOf('master') == -1:
                    cmd_cm = ''
                    if isVsu(log_slotList):
                        cmd_cm = 'session device ' + dev + ' slot ' + slot
                    else:
                        cmd_cm = 'session slot ' + slot
                    end
                    session_res = cli(cmd_cm,'>')
                    if !isSessionSucc(session_res):
                        add_problem('upload_fail')
                        change_title('问题未修复')
                        return 'warn'
                    end
                    cli('enable')
                end
                #进入shell模式，执行命令
                cli('run-system-shell')
                #判断脚本是否改变
                if isShellChange():
                    cli('killall pgsql_daily')
                end

                mv_log = cli('mv /data/pgsql_daily /sbin/pgsql_daily')
                if !mvSucc(mv_log):
                    add_problem('file_fail')
                    change_title('问题未修复')
                    return 'warn'
                end
                cli('chmod +x /sbin/pgsql_daily')
                cli('echo "pgsql_daily 0400 &" > /etc/rc.d/rc3.d/S991_pgsql_daily')
                cli('chmod +x /etc/rc.d/rc3.d/S991_pgsql_daily')
                cli('sync')
                cli('/etc/rc.d/rc3.d/S991_pgsql_daily start')
                #是否start成功
                if !startSucc():
                    all_start = 0
                end
                cli('exit')
                if card.indexOf('master') == -1:
                    cli('exit')
                end
            end
        end
    end

    #主从管理板进程都起来了
    if all_start == 1:
        add_problem('upload_yes')
        change_title('问题已修复')
        return 'warn'
    else:
        add_problem('start_fail')
        change_title('问题未修复')
        return 'warn'
    end
else:
    precondition_result = 'fail'
    precondition_message = '管理板-文件传输失败'
    precondition_message_advice = '请检查tftp端口(69)是否防火墙被禁用或者已经被其他tftp软件占用！'
    set_share_value('precondition_result',precondition_result)
    set_share_value('precondition_message',precondition_message)
    set_share_value('precondition_message_advice',precondition_message_advice)
    add_problem('tftp_fail')
    change_title('问题未修复')
    return 'warn'
end

#从主板卡拷贝到从板卡
def isTipcCopySucc():
    result = 0
    #tftp拷贝脚本到主板卡
    if isTftpCopySucc():
        cli('run-system-shell')
        #从主板卡拷贝到从板卡
        reg_cm = /(\d+)\s+(M\d+)\s+\d+/
        foreach card in log_slotList:
            if card.indexOf('candidate') != -1 || card.indexOf('backup') != -1:
                r = card.match(reg_cm)
                if r != null:
                    dev = r[1]
                    slot = r[2]
                    slot_id = getSlotID(card)
                    master_tipcid = getTipcId(slot_id,0,dev);
                    tipc_cmd = 'tftp_tipc_client_elf '+master_tipcid+' /data/pgsql_daily /data/pgsql_daily 2'
                    cli(tipc_cmd)
                end
            end
        end
        result = 1
        cli('exit')
    end
    return result
end

#判断是否数据库泄漏版本
def isPgsqlLeakVersion():
	result = 0
    #库函数
    version = get_device_softvesion()
    if version == null || version == '':
        add_problem('getversion_fail')
        change_title('获取版本号失败')
        return 'warn'
    end
    #不是release
    if version.indexOf("Release") == -1:
    	foreach data in versionList:
    		if version == data :
    			result = 1
    			break
    		end
    	end
    else:
        foreach data in versionList:
            data1 = data+" "
            data2 = data+","
            data3 = data+"Release"
            if version.indexOf(data) != -1 && (version.indexOf(data1) != -1 || version.indexOf(data2) != -1 || version.indexOf(data3) != -1):
                result = 1
                break
            end
        end
    end
	return result
end

#判断是否VSU
def isVsu(strList):
	result = 0
	reg = /(\d+)\s+\w+\s+\d+/
	foreach data in strList:
		r = data.match(reg)
		if r != null:
			dev = r[1]
			if dev == 2:
				result = 1
				break
			end
		end
	end
	return result
end

def isTftpCopySucc():
    result = 0
	local_ip = getLocalIp()
	patch_path = getHotfixStoreFolder()
	if isMgmt():
		cmd_tftp_cm = 'copy oob_tftp://' + local_ip + patch_path + file_name + ' flash:' + file_name
	else:
		cmd_tftp_cm = 'copy tftp://' + local_ip + patch_path + file_name + ' flash:' + file_name
	end
    tftp_log = cli(cmd_tftp_cm)
    print '======tftp_log:'+tftp_log
    #给3次机会传输
    times = 3
    while times>0:
        if !isTransfer(file_name):
            tftp_log = cli(cmd_tftp_cm)
            print '======tftp_log:'+tftp_log
        else:
            result = 1
            break
        end
        times = times - 1
    end
	return result
end

#判断是否mgmt口
def isMgmt():
	result = 0
	ip = getDeviceIp()
	cmd = 'show ip interface brief | include ' + ip
	log_ip_intf = cli(cmd)
	log_ip_intfList = log_ip_intf.split('\r\n')
	foreach data in log_ip_intfList:
		if data.indexOf('Mgmt') != -1 && data.indexOf('up') != -1:
			result = 1
		end
	end
	return result
end

#判断tftp上传版本是否成功
def isTransfer(str):
	result = 0
	log_dir = cli('dir')
	if log_dir.indexOf(str) != -1:
		result = 1
	end
	return result
end


#根据板卡类型和槽位，返回对应登录的id值
def getSlotID(str):
	myID = 0
	reg = /\d+\s+(\w+)\s+\d+/
	r = str.match(reg)
	if r != null:
		slotID = r[1]
		if slotID.indexOf('M') != -1:
			if slotID == 'M1':
				myID = 30
			else:
				myID = 31
			end
		else if slotID.indexOf('FE') != -1:
			if slotID == 'FE1':
				myID = 22
			else if slotID == 'FE2':
				myID = 23
			else if slotID == 'FE3':
				myID = 24
			else:
				myID = 25
			end
		else:
			myID = slotID
		end
	end
	return myID
end

#获取tipcid
def getTipcId(slotId, cpuId, deviceId):
    return 640 + (deviceId - 1) * 160 + slotId * 5 + cpuId;
end

#判断脚本是否改变
def isShellChange():
    result = 0
    log_data = cli('md5sum /data/pgsql_daily')
    log_sbin = cli('md5sum /sbin/pgsql_daily')
    log_data = log_data.split(/\r?\n/)
    log_data = log_data[1]
    log_sbin = log_sbin.split(/\r?\n/)
    log_sbin = log_sbin[1]
    log_data = log_data.split(/\s+/)
    log_data = log_data[0]
    log_sbin = log_sbin.split(/\s+/)
    log_sbin = log_sbin[0]
    if log_sbin.indexOf( 'md5sum') == -1 && log_data != log_sbin:
        #cli('kill pgsql_daily')
        result = 1
    end
    return result
end

#判断进去从管理板是否成功
def isSessionSucc(session_res):
    result = 1
    if session_res.indexOf('Destination unreachable') != -1 || session_res.indexOf('Unrecognized host or address') != -1:
        result = 0
    end
    return result
end

#判断进程启动是否成功
def startSucc():
    result = 0
    times = 5
    while times>0:
        sleep(1000)
        if psSucc():
            result = 1
            break
        end
        times = times - 1
    end
    return result
end
#启动进程log
def psSucc():
    result = 0
    ps_log = cli('ps -ef | grep daily')
    ps_logList = ps_log.split(/\r?\n/)
    foreach ps in ps_logList:
        if ps.indexOf('/sbin/pgsql_daily') != -1:
            result = 1
            break
        end
    end
    return result
end

def mvSucc(mv_log):
    result = 1
    if mv_log.indexOf('No such file or directory') != -1:
        result = 0
    end
    return result
end