
{
    "name"  : "0PJ11热补丁",
    "problems" : {
        "patch_fail" : {
            "desc"      : "【问题】当前版本未检测到使用补丁进行过修复，工具尝试修复，但修复失败，请再次尝试。",
            "advice"    : "【建议】对当前版本进行热补丁升级，升级补丁过程不断网。"
        },
		"patch_ok" : {
            "desc"      : "【问题】当前版本未检测到使用补丁进行过修复，工具尝试修复，已经修复成功。",
            "advice"    : "【建议】再次检测看是否有热补丁问题。"
        }
    }
}

---------------------------code-------------------------------
result_precondition = get_share_value('precondition_result')
if result_precondition == 'fail':
	return 'skip'
end

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')
key_version = get_bin_file(log_version)

bin_file_lc = getHotfixFileName(key_version)

lc_result = 'pass'
lc_message = ''

if bin_file_lc == null:
	lc_result = 'fail'
	lc_message = '线卡-版本不匹配，没做升级动作，有疑问请联系后台处理！'
	set_share_value('lc_result',lc_result)
	set_share_value('lc_message',lc_message)
	return 'skip'
end

if !isPatched():
	if isPatchedEver():
		file_handle()
	end
	local_ip = getLocalIp()
	patch_path = getHotfixStoreFolder()
	if isMgmt():
		cmd_tftp_lc = 'copy oob_tftp://' + local_ip + patch_path + bin_file_lc + ' flash:' + bin_file_lc
	else:
		cmd_tftp_lc = 'copy tftp://' + local_ip + patch_path + bin_file_lc + ' flash:' + bin_file_lc
	end
	transferResult = 'pass'
	
	#线卡
	if !isTransfer(bin_file_lc):
		#tftp三次传输不成功，则返回失败
		cli(cmd_tftp_lc)
		times = 3
		trans_success = 'fail'
		while times>0:
			transferResult = 'pass'
			if !isTransfer(bin_file_lc):
				transferResult = 'fail'
				cli(cmd_tftp_lc)
			else:
				trans_success = 'success'
				break
			end
			times = times - 1
		end
		if trans_success == 'fail':
			lc_result = 'fail'
			lc_message = '线卡-文件传输失败，请检查tftp端口(69)是否防火墙被禁用或者已经被其他tftp软件占用！'
			set_share_value('lc_result',lc_result)
			set_share_value('lc_message',lc_message)
			return 'skip'
		end
	end
	
	
	cmd_upgrade_lc = format('upgrade flash:%s force',bin_file_lc)
    cli(cmd_upgrade_lc)
	#5秒检测一次lc是否upgrade成功，最多等待5分钟
	times = 59
	up_success = 'fail'
	while times>0:
		sleep(5000)
		cpuHandle()
		if isUpgreadSuccess('lc'):
			up_success = 'pass'
			break
		end
		times = times - 1
	end
	
	times = 3
	while times > 0:
		cpuHandle()
		sleep(5000)
		times = times -1
	end
	if up_success == 'pass' :
		cli('patch active slot all')
		cli('patch running slot all')
	else:
		lc_result = 'fail'
		lc_message = '线卡-upgrade失败，若状态显示为upgrading，请等待upgrade状态为timeout后再做操作！'
		set_share_value('lc_result',lc_result)
		set_share_value('lc_message',lc_message)
		return 'skip'
	end
else:
	set_share_value('lc_result',lc_result)
	set_share_value('lc_message',lc_message)
	return 'skip'
end

sleep(5000)
result='pass'
times = 3
while times>0:
	sleep(20000)
	result = 'pass'
	if !isPatched():
		result = 'fail'
	else:
		break
	end
	times = times - 1
end
if result == 'fail':
	lc_result = 'fail'
	lc_message = '线卡-检测到热补丁问题，尝试过修复，但修复不成功'
else:
	lc_result = 'fail'
	lc_message = '线卡-检测到热补丁问题，已经修复成功'
end

set_share_value('lc_result',lc_result)
set_share_value('lc_message',lc_message)

return 'skip'

#判断补丁是不是成功打进
def isPatched():
	result = 1
	cli('run-system-shell')
	foreach card in log_slotList:
		if card.indexOf('ok') != -1 && card.indexOf('FE') == -1:
			slotID = getSlotID(card)
			slot_cmd = 'debug-ssa ' + slotID
			cli(slot_cmd,'>')
			log_cat = cli('getreg CMIC_CMC0_CH1_COS_CTRL_RX_0','>')
			if log_cat.indexOf('=0x107') == -1:
				result = 0
				cli('@ctrl+]','e exit telnet')
				cli('e')
				break
			end
			if card.indexOf('M18000-16XS2QXS-ED') != -1 || card.indexOf('M18000-24QXS-DB') != -1:
				cli('1:','>')
				log_cat2 = cli('getreg CMIC_CMC0_CH1_COS_CTRL_RX_0','>')
				cli('0:','>')
				if log_cat2.indexOf('=0x107') == -1:
					result = 0
					cli('@ctrl+]','e exit telnet')
					cli('e')
					break
				end
			end			
			cli('sh')
			log_cpsp = cli('ls sbin | grep cpsp')
			log_Szzs_ssa_cpsp_patch = cli('ls /etc/rc.d/rc3.d/ | grep cpsp')
			cli('exit','>')
			cli('@ctrl+]','e exit telnet')
			cli('e')
			if log_cpsp.indexOf('ssa_cpsp_patch.sh') == -1 || log_cpsp.indexOf('Szzs_ssa_cpsp_patch') == -1:
				result = 0
				break
			end
			if log_Szzs_ssa_cpsp_patch.indexOf('Szzs_ssa_cpsp_patch') == -1:
				result = 0
				break
			end
				
		end
	end
	cli('exit')
	return result
end

#判断是否有做过打补丁操作
def isPatchedEver():
	result = 0
	cli('run-system-shell')
	foreach card in log_slotList:
		if card.indexOf('ok') != -1 && card.indexOf('FE') == -1:
			slotID = getSlotID(card)
			slot_cmd = 'debug-ssa ' + slotID
			cli(slot_cmd,'>')
			cli('sh')
			log_cpsp = cli('ls sbin | grep cpsp')
			log_Szzs_ssa_cpsp_patch = cli('ls /etc/rc.d/rc3.d/ | grep cpsp')
			cli('exit','>')
			cli('@ctrl+]','e exit telnet')
			cli('e')
			if log_cpsp.indexOf('ssa_cpsp_patch.sh') != -1 || log_cpsp.indexOf('Szzs_ssa_cpsp_patch') != -1 :
				result = 1
				break
			end
			if log_Szzs_ssa_cpsp_patch.indexOf('Szzs_ssa_cpsp_patch') != -1:
				result = 1
				break
			end
		end
	end
	cli('exit')
	return result
end

#判断是否有文件残留并删除
def file_handle():
	netType = isVsu(log_slotList)
	cmd_deactive = format('patch deactive slot all')
	cmd_delete = format('patch delete slot all')
	cli(cmd_deactive)
	cli(cmd_delete)
	sleep(5000)
	foreach card in log_slotList:
		if card.indexOf('ok') != -1 :
			slot = getSlot(card,netType)
			slotID = getSlotID(card)
			cli('run-system-shell')
			slot_cmd = 'debug-ssa ' + slotID
			cli(slot_cmd,'>')
			cli('sh')
			response = cli('ls /rootfs/pkgmgmt/patch_install/')
			response_1 = ('ls /etc/ | grep patch_config')
			cli('rm -rf /sbin/Szzs_ssa_cpsp_patch')
			cli('rm -rf /sbin/ssa_cpsp_patch.sh')
			if response.indexOf('0_patch_utils') != -1:
				cli('rm -rf /rootfs/pkgmgmt/patch_install/0_patch_utils')
			end
			if response_1.indexOf('patch_config') != -1:
				cli('rm -rf /etc/patch_config')
			end
			if card.indexOf('1   M1') == -1:
				cli('@ctrl+]','e exit telnet')
				cli('e')
			end
			cli('exit')
		end
	end
end

#获取槽位号
def getSlot(str,netType):
	slot = ''
	reg = /(\d+)\s+(\w+)\s+\d+/
	r = str.match(reg)
	if r != null:
		dev = r[1]
		slotID = r[2]
		if netType == 1:
			slot = dev + '/' + slotID
		else:
			slot = slotID
		end
	end
	return slot
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

#根据板卡类型和槽位，返回对应登录的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

#匹配补丁版本-线卡
def get_bin_file(str):
	file_name = ''
	version = ''
	reg_ver = /\w+_RGOS\s+([^,^\r\n]+)/
	r = str.match(reg_ver)
	if r != null:
		version = r[1]
	end
	type = 'octeon'
	card = 'lc'
	date = get_date_version(str)
	if version != '':
		file_name = version + '-' + type + '-' + card
	end
	#PJ8-05102016
	if date == '05052016' && version == '11.0(4)B3':
		file_name = file_name + '-SP2'
	end
	return file_name
end

def get_date_version(str):
	date = ''
	strList = str.split('\r\n')
	reg = /System software number\s+:\s+\w{1}\d{6}(\d{8})/
	foreach data in strList:
		r = data.match(reg)
		if r != null:
			date = r[1]
			break
		end
	end
	return date
end



#判断tftp上传版本是否成功
def isTransfer(str):
	result = 0
	log_dir = cli('dir')
	if log_dir.indexOf(str) != -1:
		result = 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

#判断是否upgrade成功
def isUpgreadSuccess(cardType):
	isSuccess = 1
	log_upgrade_sta = cli('show upgrade status')
	log_upgrade_staList = log_upgrade_sta.split('\r\n')
	reg = /(\[Slot\s+[^ ]+\])/
	foreach data in log_upgrade_staList:
		r = data.match(reg)
		if r != null:
			slot = r[1]
			if cardType == 'cm':
				if slot.indexOf('M1')!= -1 || slot.indexOf('M2') != -1:
					logstr = getStaLog(data,log_upgrade_staList)
					if logstr.indexOf('success') == -1 && logstr.indexOf('skipped') == -1:
						isSuccess = 0
					end
				end
			else if cardType == 'lc':
				if slot.indexOf('M1')== -1 && slot.indexOf('M2') == -1:
					logstr = getStaLog(data,log_upgrade_staList)
					if logstr.indexOf('success') == -1 && logstr.indexOf('skipped') == -1:
						isSuccess = 0
					end
				end
			end
		end
	end
	return isSuccess
end

#截取管理板的升级状态信息
def getStaLog(slot,strList):
	str = ""
	isAdd = 0
	foreach data in strList:
		if data == slot:
			isAdd = 1
		end
		if data.indexOf('Slot') != -1 && data != slot:
			isAdd = 0
		end
		if isAdd:
			str = str + data + '\r\n'
		end
	end
	return str
end

def str_to_num(str):
	num = ''
	strList = str.split(",")
	foreach data in strList:
		num = num+data
	end
	return num
end

def cpuHandle():
	log_cpu = cli('show cpu | inc rg-upgr')
	log_cpuList = log_cpu.split('\r\n')
	reg =  /\d+\s+([^ ]+)%\s+[^ ]+%\s+[^ ]+%\s+rg-upgrade/
	foreach data in log_cpuList:
		r = data.match(reg)
		if r != null:
			cpu = r[1]
			if cpu > 90:
				cli('run-system-shell')
				cli('pkill -9 rg-upgrade')
				cli('exit')
			end
		end
	end
end