网络自动化之ZTP自动装机(H3C)

1、H3C的ZTP脚本

华三
#!usr/bin/python

import comware
from time import strftime,gmtime,sleep
import signal
import os
import string
import commands
import hashlib

#U can use 2 modes to obtain the config file
#- 'python_static'
#- 'python_serial_number'
python_config_file_mode = "python_serial_number"

#Required space to copy config kickstart and system image in KB
required_space = 150000

#Enable IRF function
#- True
#- False
irf = True

#transfer information,TFTP传输的用户名密码,可以默认匿名登陆,只下载不上传
username="1"
password="123456"
hostname = "192.168.1.100"
protocol = "http" #可以使用FTP协议
vrf = ""
config_timeout = 120
irf_timeout = 120 #没有irf可以不用写??
image_timeout = 2100

#Server File Path,服务器目录信息
server_path = ""  #

#Loacl File path,本地目录信息
local_path = "flash:/"

#cfg file path
cfg_dir = ""

#Local config name,配置文件本地存放名称
config_local_name = "config.cfg"

#Server config name,配置文件服务器存放名称
config_server_name = "config.cfg"

#Local boot name,版本启动文件本地存放名称
boot_local_name = ""

#Server boot name,版本文件服务器存放名称
boot_server_name = ""

#Local patch name,补丁启动文件本地存放名称
patch_local_name = ""

#Server patch name,补丁文件服务器存放名称
patch_server_name = ""

#Local irf name,SN文件信息本地存放名称,用于配置IRF member ID
irf_local_name = "sn.txt"

#Server irf name,SN文件信息服务器存放名称,用于IRF member ID
irf_server_name = "sn.txt"
#脚本文件执行日志存放位置。
python_log_name = ""

#device type
device = ""

#Local devcie version
local_version = ""

#Server target version
server_version = ""

#device infomation
device_list = {
    "S6800-54QF":{
        "version":"Release 2432P01",
        "version_file":"S6800-CMW710-R2432P01.ipe",
        "patch_list":[
            "S6800-CMW710-SYSTEM-R2432P01H11.bin",
            "S6800-CMW710-SYSTEM-WEAK-R2432P01H16.bin"
        ],
        "cfg_dir":"",
        "irf_server_name":"",
        "irf":False
    },
    "S6820-56HF":{  
        "version":"Feature 6207",
        "version_file":"S6820-CMW710-F6207.ipe",
        "patch_list":[
        ],
        "cfg_dir":"cfg/",
        "irf_server_name":"",
        "irf":False
    },
    "S5820V2-54QS-GE":{ 
        "version":"Feature 6207",
        "version_file":"",
        "patch_list":[
        ],
        "cfg_dir":"",
        "irf_server_name":"sn.txt",
        "irf":False
    }
}

#Write Log File
def write2Log(info):
  global python_log_name, local_path
  if python_log_name == "":
    try:
      python_log_name = "%spython_%s" %(local_path, "ztp.log")
    except Exception as inst:
      print inst
  fd = open(python_log_name, "a")
  fd.write(info)
  fd.flush()
  fd.close()
  
#get device infomation
  
def get_version():
    cmd_output = comware.CLI("display version",False).get_output()
    for line in cmd_output:
        if "Comware Software" in line:
            version = line.split(",")[-1].strip()
            return version
    write2Log("\nGet version failure.")
    print "\n###Get version failure.###"
    return False
    
def check_patch(patch):
    cmd_output = comware.CLI("display install active",False).get_output()
    for cmd_line in cmd_output:
        if (patch.upper() in cmd_line) or (patch.lower() in cmd_line):
            return True
    return False

def get_device():
    cmd_output = comware.CLI("display version",False).get_output()
    for line in cmd_output:
        if "uptime" in line:
            device = line.split(" ")[1].strip()
            print device
            return device
    write2Log("\nGet device type failure.") 
    print "\n###Get device type failure###"
    return False

def get_device_info():
    global device,local_version,server_version,boot_local_name,boot_server_name
    global patch_server_name,irf,cfg_dir,irf_server_name
    local_version = get_version()
    if local_version == False:
        return False
    device = get_device()
    if device == False :
        write2Log("\nThe %s is not in the list!" %device) 
        print "\n###The %s is not in the list!###" %device
        return False
    if device_list.get(device) != None:
        device_dic = device_list.get(device)
        server_version = device_dic.get("version")
        boot_local_name = device_dic.get("version_file")
        boot_server_name = device_dic.get("version_file")
        patch_server_name = device_dic.get("patch_list")
        cfg_dir = device_dic.get("cfg_dir")
        irf_server_name = device_dic.get("irf_server_name")
        irf = device_dic.get("irf")
    else:
        write2Log("\nThe %s is not in the list!" %device) 
        print "\n###The %s is not in the list!###" %device
        return False
    return True

def check_version():
    if boot_server_name == "":
        print "\n###boot_server_name is None,No nedd Check Version###"boot_local_name
        return True
    if local_version == server_version:
        write2Log("\nThe version is consistent.")
        print "\n###The version is consistent.###"
        return True
    write2Log("\nThe version is different,Please download later.Target version %s" %server_version)
    print "\n###The version is different,Please download later.Target version %s###" %server_version
    return False
########################################################################################################
# get path according to the Chassis and Slot,貌似在获取交换机上的目录
def getPath(chassisID, slotID):
  global local_path
  path = ""
  obj = comware.get_self_slot()
  if (obj[0] == chassisID) and (obj[1] == slotID):
    return local_path
  if chassisID != -1:
    path = "chassis%d#" % chassisID
  if slotID != -1:
    path = "%sslot%d#%s" %(path, slotID, local_path)
  return path

#Remove File,移动文件夹
def removeFile(filename):
  try:
    os.remove(filename)
  except os.error:
    pass

#Cleanup one device temp files,清除设备配置文件、版本文件、补丁、MD5文件
def cleanDeviceFiles(str, oDevNode):
  global config_local_name, boot_local_name, irf_local_name
  sFilePath = getPath(oDevNode[0], oDevNode[1])
  if str == "error":
    if config_local_name != "":
      removeFile("%s%s" %(sFilePath, config_local_name))
    for patch in  patch_server_name:
      removeFile("%s%s" %(sFilePath, patch))
  if boot_local_name != "":
    removeFile("%s%s" %(sFilePath, boot_local_name))
  if irf_local_name != "":
    removeFile("%s%s" %(sFilePath, irf_local_name))
  removeFile("%s%s.md5" %(sFilePath, config_local_name))
  removeFile("%s%s.md5" %(sFilePath, boot_local_name))
  removeFile("%s%s.md5" %(sFilePath, irf_local_name))
  for patch in  patch_server_name:
    removeFile("%s%s.md5" %(sFilePath, patch))
  write2Log("\ndelete %s all files\n" %sFilePath) 
  print "\n###INFO:\ndelete %s all files###" %sFilePath

#Cleanup files,清除文件信息,主/备slot的文件信息清楚
def cleanupFiles(str):
  aSlotRange = []
  if ("get_standby_slot" in dir(comware)):
    aSlotRange = aSlotRange + comware.get_standby_slot()
  	
  aSlotRange.append(comware.get_self_slot())
  i = 0
  while i < len(aSlotRange):
    if(aSlotRange[i] != None):
      cleanDeviceFiles(str, aSlotRange[i])
    i = i + 1

#Verify if free space is available to download config, boot-loader image,检查剩余空间是否足够
def verifyfreespace(path):
  global required_space
  try:
    s = os.statvfs(path)
    freespace = (s.f_bavail * s.f_frsize) /1024
    write2Log("\nthe %s free space is %s" %(path, freespace))
    print "\n###the %s free space is %s KB###" %(path, freespace)
    if required_space > freespace:
      write2Log("\nthe %s space is not enough" % path)
      print "\n####the %s space is not enough####" % path
      return False
  except Exception as inst:
    write2Log("\nverify %s free space exception: %s" % (path, inst))
    print "\n###verify %s free space exception: %s###" % (path, inst)
    return False
  return True

#verify device freespace,确认设备剩余空间
def verifyDeviceFree(obj):
  path = getPath(obj[0], obj[1])
  if True != verifyfreespace(path):
    return False
  return True
  
#check all mpu free space,检查所有的slot空间
def verifyAllFreeSpace():
  aSlotRange = []
  if ("get_standby_slot" in dir(comware)):
    aSlotRange = aSlotRange + comware.get_standby_slot()
  	
  aSlotRange.append(comware.get_self_slot())
  bAllEnough = True
  i = 0
  while i < len(aSlotRange):
    if(aSlotRange[i] != None) and (True != verifyDeviceFree(aSlotRange[i])):
      bAllEnough = False
    i = i + 1
  return bAllEnough
#确认脚本是否正常,正常则清除所有文件,不包括版本和补丁;error的话则清除所有
def doExit(str):
  if str == "success":
    write2Log("\nThe script is running success!")
    print "\n#### The script is running success! ####"  
    cleanupFiles("success")
    comd = "reboot force"
    comware.CLI(comd, False)  
    exit(0)
  if str == "error":
    write2Log("\nThe script is running failed!")
    print "\n#### The script is running failed! ####"
    cleanupFiles("error")
    exit(1)
  else:
    exit(0)

#get Chassis and Slot,获取主控板的槽位号
def getChassisSlot(style):
  if style == "master":
    obj = comware.get_self_slot()
  if len(obj) <= 0:
    write2Log("\nget %s chassis and slot failed" % style)
    print "\n####get %s chassis and slot failed####" % style
    return None
  return obj

#获取启动软件包发生错误返回的信息
#signal terminal handler function
def sig_handler_no_exit(signum, function):
  write2Log("\nSIGTERM Handler while configuring boot-loader variables")
  print "\n####SIGTERM Handler while configuring boot-loader variables####"

#软件升级过程发生错误时返回的信息
#signal terminal handler
def sigterm_handler(signum, function):
  write2Log("\nSIGTERM Handler")
  print "\n####SIGTERM Handler####"
  cleanupFiles("error")
  doExit("error")
 
 #从HTTP服务器上下载文件(后续用TFTP服务器)
#transfer file
def doCopyFile(src = "", des = "", login_timeout = 10):
  global username, password, hostname, protocol, vrf
  print "\n###INFO: Starting Copy of %s###" % src
  try:
    removeFile(des)
    obj = comware.Transfer(protocol, hostname, src, des, vrf, login_timeout, username, password)
    if obj.get_error() != None:
      write2Log("\ncopy %s failed: %s" % (src, obj.get_error()))
      print "\n####copy %s failed: %s####" % (src, obj.get_error())
      return False
  except Exception as inst:
    write2Log("\ncopy %s exception: %s" % (src, inst))
    print "\n####copy %s exception: %s####" % (src, inst)
    return False
  write2Log("\ncopy file %s to %s success" % (src, des))
  print "\n###INFO: Completed Copy of %s###" % src
  return True

#Get MD5SUM from md5ConfigFile,获取MDESUM
def getMD5SumGiven(keyword, filename):
  try:
    file = open(filename, "r")
    line = file.readline()
    while "" != line:
      if not string.find(line, keyword, 0, len(keyword)):
        line = line.split("=")
        line = line[1]
        line = line.strip()
        file.close()
        return line
      line = file.readline() 
    file.close()
  except Exception as inst:
    write2Log("\nget %s md5 exception: %s" % (filename, inst))
    print "\n####get %s mz'sd5 exception: %s####" % (filename, inst)
  return ""   

#verify MD5SUM of the file,MD5校验,计算出文件的md5值和给的md5进行对比
def verifyMD5sumofFile(md5sumgiven, filename):
  if md5sumgiven == "":
    write2Log("\nverify %s md5 error: the %s md5 file is error" %(filename, filename))
    print "\n####verify %s md5 error: the %s md5 file is error####" %(filename, filename)
    return False
  try:
    m = hashlib.md5()
    f = open(filename, 'rb')
    buffer = 8192
    while 1:
      chunk = f.read(buffer)
      if not chunk:
        break
      m.update(chunk)
    f.close()
    md5calculated = m.hexdigest()
  except Exception as inst:
    write2Log("\nverify %s md5 exception: %s" % (filename, inst))
    print "\n####verify %s md5 exception: %s####" % (filename, inst)
    return False
  if md5sumgiven == md5calculated:
    return True
  write2Log("\nverify %s md5 error: md5sumgiven is %s filemd5 is %s" %(filename, md5sumgiven, md5calculated))
  print "\n####verify %s md5 error: md5sumgiven is %s filemd5 is %s####" %(filename, md5sumgiven, md5calculated)
  return False

#Check MD5 file,检查MD5文件,这是要下载md5文件了吧?
def checkFile(src, dest):
  src = "%s.md5" % src
  destmd5 = "%s.md5" % dest
  bFlag = doCopyFile(src, destmd5, 120)
  if (True == bFlag) and (True == verifyMD5sumofFile(getMD5SumGiven("md5sum", destmd5), dest)):
    write2Log("\ncheckFile success: %s" % destmd5)
    print "\n####checkFile success: %s####" % destmd5
    return True
  elif (True != bFlag):
    write2Log("\n%s is not exist! Don't verify the MD5 file!" % destmd5)
    print "\n###INFO: %s is not exist! Don't verify the MD5 file!###" % destmd5     
    return True
  return False 

#Get config file according to the mode,取到设备配置文件名称
def getCfgFileName():
  global config_server_name
  if (python_config_file_mode == "python_serial_number") and (os.environ.has_key('DEV_SERIAL')):    
    config_server_name = "%sconf_%s.cfg" % (cfg_dir,os.environ['DEV_SERIAL'])
    return config_server_name
  else:
    return config_server_name

#copy file to all standby slot,将文件copy到备的板卡上
def syncFileToStandby(sSrcFile, sFileName):
  try:
    aSlotRange = []
    if ("get_standby_slot" in dir(comware)):
      aSlotRange = aSlotRange + comware.get_standby_slot()
  		
    i = 0
    while i < len(aSlotRange):
      if(aSlotRange[i] != None):
        sDestFile = "%s%s" %(getPath(aSlotRange[i][0], aSlotRange[i][1]), sFileName)
        removeFile(sDestFile)
        open(sDestFile,"wb").write(open(sSrcFile,"rb").read())
        write2Log("\nsync file to standby %s" % (sDestFile))
        print "\n####sync file to standby %s####" % (sDestFile)
      i = i + 1
  except Exception as inst:
    write2Log("\nsync file to standby %s exception: %s" % (sSrcFile, inst))
    print "\n####sync file to standby %s exception: %s####" % (sSrcFile, inst)
 
#Procedure to copy config file using global information
#根据脚本开始处定义的全局变量,下载启动软件包、配置文件、sn文件等
def copyAndCheckFile(src, dest, timeout):
  global server_path, local_path
  srcTmp = "%s%s" % (server_path, src)
  sDestFile = "%s%s" % (local_path, dest)
  if (True == doCopyFile(srcTmp, sDestFile, timeout)) and (True == checkFile(srcTmp, sDestFile)):
    syncFileToStandby(sDestFile, dest)
    return True
  else:
    srcTmp = "%sdefault_%s" %(server_path, src)
    if (True == doCopyFile(srcTmp, sDestFile, timeout)) and (True == checkFile(srcTmp, sDestFile)):
      syncFileToStandby(dest)
      return True
  return False

# split the Chassis and Slot,整合chassis_slot
def splitChassisSlot(chassisID, slotID):
  chassis_slot = ""
  if chassisID != -1:
    chassis_slot = " chassis %d"  % chassisID
  if slotID != -1:
    chassis_slot = "%s slot %d" %(chassis_slot, slotID)
  return chassis_slot
#获取chassis号
def splitChassis(chassisID):
  chassis = " "
  if chassisID != -1:
    chassis = " chassis %d"  % chassisID
  return chassis
#从服务器上下载启动软件包
def copyBootImage():
  global image_timeout, local_path, boot_server_name, boot_local_name
  if boot_server_name == "":
    return True
  src = "%s" % boot_server_name
  return copyAndCheckFile(src, boot_local_name, image_timeout)
#从服务器上下载配置文件
def copyCfgFile():
  global config_timeout, local_path, config_local_name
  src = "%s" % getCfgFileName()
  return copyAndCheckFile(src, config_local_name, config_timeout)
#下载irf_server_name和irf_local_name配置文件(sn.txt),函数中还检查member_id信息,将member_id统一改为1
def copyIrfStack():
  global irf_timeout, local_path, irf_local_name, irf_server_name
  if irf_server_name == "" or irf == False:
    print "\n###irf_server_name is None,No need copy irf###"
    if True != renumber_id():
        return False
    return True
  src = "%s" % irf_server_name
  return copyAndCheckFile(src, irf_local_name, config_timeout)
#执行boot-loader命令,升级交换机版本,为设备指定下次主用启动文件
# Procedure to Install Boot Image  
def installBoot(chassis_slot, sFile, style):
  result = None
  write2Log("\ninstall%s%s begin" %(chassis_slot, style))
  print "\nINFO: Install%s%s Start, Please Wait..." %(chassis_slot, style)
  comd = "boot-loader file %s%s%s" % (sFile, chassis_slot, style)
  try:
    result = comware.CLI(comd, False) 
    if result == None:
      write2Log("\nboot-loader file %s%s%s failed" % (sFile, chassis_slot, style))
      print "\n####boot-loader file %s%s%s failed####" % (sFile, chassis_slot, style)
      return False
  except Exception as inst:
    write2Log("\nboot-loader %s exception: %s" % (sFile, inst))
    print "\n####boot-loader %s exception: %s####" % (sFile, inst)
    return False  
  return True
###############################################################################################################
#Procedure to install boot image,升级交换机版本
def installBootImage():
  global boot_local_name
  if boot_server_name == "":
    print "\n###boot_server_name is None,No need Install image###"
    return True
  aSlotRange = [comware.get_self_slot()]
  if ("get_standby_slot" in dir(comware)):
    aSlotRange = aSlotRange + comware.get_standby_slot()
  bInstallOk = True
  i = 0
  while i < len(aSlotRange):
    sFile = "%s%s" %(getPath(aSlotRange[0][0], aSlotRange[0][1]), boot_local_name)
    if False == installBoot(splitChassisSlot(aSlotRange[i][0], aSlotRange[i][1]), sFile, " main"):
      bInstallOk = False
    i = i + 1
  return bInstallOk

#Copy patch,下载补丁
def copy_patch():
  global image_timeout, local_path, patch_server_name
  if len(patch_server_name) == 0:
     print "\n###INFO: Patch list is None,No need to copy patch###"
     return True
  print "\n###INFO: Download patch Start###"
  for patch_name in  patch_server_name:
    src = "%s" % patch_name
    copyAndCheckFile(src, src, image_timeout)
  return True

  
#Install patch,安装补丁,并install commit使补丁下次设备启动还生效

def installPacth(chassis, sFile , patch):
  result = ""
  if True == check_patch(patch):
      print "\n####INFO:The patch %s has been installed####" % patch
  else:
    try:
      print "\n###INFO: Install patch %s###" % patch
      commands = "install activate patch %s %s all" % (chassis,sFile)
      print commands
      comware.CLI(commands, False)
      print "\n###INFO: Install patch %s success###" % patch
    except Exception as inst:
      write2Log("\nInstall patch %s filed.reason %s" % (patch, inst))
      print "\n####INFO:Install patch %s filed. reason %s####" % (patch, inst)
      return False
  commands = " install commit"
  comware.CLI(commands, False)
  return True
  
def installPatchImage():安装补丁,循环调用安装程序
  global patch_server_name
  if len(patch_server_name) == 0:
     print "\n####INFO:Install patch list is None,No need to install patch####"
     return True
  slot = comware.get_self_slot()
  for patch in patch_server_name:
    sFile = "%s%s" %(getPath(slot[0], slot[1]), patch)
    if False == installPacth(splitChassis(slot[0]), sFile , patch):
      return False
  return True

指定设备启动文件
def startupCfg():
  global local_path, config_local_name
  result = None
  dest = "%s%s" %(local_path, config_local_name)
  write2Log("\nstartup saved-configuration %s begin" %dest)
  print "\n###INFO: Startup Saved-configuration Start###"
  comd = "startup saved-configuration %s main" % dest
  try:
    result = comware.CLI(comd, False)
    if result == None:
      write2Log("\nstartup saved-configuration %s failed" % dest)
      print "\n####startup saved-configuration %s failed####" % dest
      return False
  except Exception as inst:
    write2Log("\nstartup %s exception: %s" % (dest, inst))
    print "\n####startup %s exception: %s####" % (dest, inst)
    return False
  write2Log("\nstartup saved-configuration %s success" % dest)
  print "\n###INFO: Completed Startup Saved-configuration###"
  return True

#从sn.txt中返回对应的sn号或者irf编号
def getIrfCfg(line, num):
  line = line.split()
  number = None
  if 3 == len(line):
    number = line[num]
  else :
    number = None
  return number  

#获取设备当前的irf编号
def getMemberID():
  aMemId = comware.get_self_slot()
  memId = None
  if aMemId[0] == -1 :
    memId = aMemId[1]
  else :
    memId = aMemId[0]
  return memId

#从sn.txt文件中获取renumber后的编号
def getNewMemberID():
  global irf_local_name, local_path, env
  filename = "%s%s" %(local_path, irf_local_name)
  serNum = os.environ['DEV_SERIAL']
  reNum = None
  try:
    file = open(filename, "r")
    line = file.readline()
    while "" != line:
      if (serNum == getIrfCfg(line, 0)):
        file.close()
        reNum = getIrfCfg(line, 2)
        return reNum
      line = file.readline()
    file.close()
  except Exception as inst:
    write2Log("\nget renumberID exception: %s" % inst)
    print "\n####get renumberID exception: %s####" % inst
  write2Log("\nget %s renumberID failed" % filename)
  print "\n#### get %s renumberID failed ####" % filename
  return reNum

#确认设备已开启irf堆叠模式
def isIrfDevice():
  try: 
    result = comware.CLI("display irf", False) 
    if result == None: 
      return False
  except Exception as inst: 
    return False
  return True
#获取将要进行修改irf-member的配置
def getIrfComd():
  comd = None
  if irf_server_name != "" and irf == True:
    newMemberID = getNewMemberID()
  else:
    newMemberID = 1
  aMemId = comware.get_self_slot()
  if None == newMemberID:
    return None
  if False == isIrfDevice():
    comd = "system-view ; irf member %s ; chassis convert mode irf" % newMemberID
  else:
    comd = "system-view ; irf member %s renumber %s" % (getMemberID(), newMemberID)
  return comd

#确认设备sn号可以获取,又是需要堆叠的情况,开始进行堆叠,下发renumber的配置
def stackIrfCfg():
  global env
  if irf_server_name == "" or irf == False:
    print "\n###irf_server_name is None,No need irf###"
    return True
  if (not os.environ.has_key('DEV_SERIAL')):
    write2Log("\nenviron variable 'DEV_SERIAL' is not found!")
    print "\n####environ variable 'DEV_SERIAL' is not found!####"  
    return False
  comd = getIrfComd()
  if None == comd:
    return False
  result = None
  write2Log("\nstartup stack irf begin")
  print "\n###INFO: Startup stack irf Start###"
  try:
    result = comware.CLI(comd, False)
    if result == None:
      write2Log("\nstartup stack irf failed: %s" % comd)
      print "\n####startup stack irf failed: %s####" %comd
      return False
  except Exception as inst: 
    write2Log("\nstartup stack irf exception: %s command: %s" % (inst, comd))
    print "\n####startup stack irf exception: %s command: %s####" % (inst, comd)
    return False
  write2Log("\nstartup stack irf success")
  print "\n###INFO: Completed Startup Stack Irf###"
  return True
#这里感觉配置有点多余,当获取到设备上的member id不是1的时候转为1,当配置中有chassis时需要undo chassis convert mode没太理解
def renumber_id():
  MemberID = getMemberID()
  comd = getIrfComd()
  if "chassis" in comd:
    comd = "system-view ; undo chassis convert mode"
  elif "renumber" in comd:
    if MemberID == 1:
      return True
    else:
      comd = "system-view ; irf member %s renumber 1" % MemberID
  else:
    return False
    
  try:
    result = comware.CLI(comd, False)
    if result == None:
      write2Log("\nrenumeber id failed: %s" % comd)
      print "\n####renumeber id failed: %s####" %comd
      return False
  except Exception as inst: 
    write2Log("\nrenumeber id failed exception: %s command: %s" % (inst, comd))
    print "\n####renumeber id failed: %s command: %s####" % (inst, comd)
    return False
  write2Log("\nrenumeber id success")
  print "\n###INFO: Completed renumeber id###"
  return True

#检查所有的备用slot状态是否正常  
#check if all standby slots are ready
def ifAllStandbyReady():
  if (("get_slot_range" in dir(comware)) == False):
    return True
		
  aSlotRange = comware.get_slot_range()
  bAllReady = True
  for i in range(aSlotRange["MinSlot"], aSlotRange["MaxSlot"]):
    oSlotInfo =  comware.get_slot_info(i)
    if (oSlotInfo != None) and (oSlotInfo["Role"] == "Standby") and (oSlotInfo["Status"] == "Fail"):
      bAllReady = False
      write2Log("\nSlot %s is not ready!" %i)
      print "\n####Slot %s is not ready!####" %i
  return bAllReady
  
#如果备用板卡没有ready,则每次等待10秒直到都变成normal状态
#if have any standby slot was not ready sleep for waiting
def waitStandbyReady():
  while ifAllStandbyReady() == False:
    sleep(10)

#python main
主程序
#when download file user can stop script
waitStandbyReady()
signal.signal(signal.SIGTERM, sigterm_handler)

if (get_device_info() != True):
   doExit("error")
if (check_version() == True):
  if (True == copy_patch()) and  (True == copyIrfStack()) and (True == copyCfgFile()):
    signal.signal(signal.SIGTERM, sig_handler_no_exit)
    if (True == installPatchImage()) and (True == stackIrfCfg()) and (True == startupCfg()):
      doExit("success")  
elif (True == verifyAllFreeSpace()) and (True == copyBootImage()):    
  signal.signal(signal.SIGTERM, sig_handler_no_exit)
  if True == installBootImage():
    doExit("success")
doExit("error")

test1(failed):

test2(problem):

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值