def validate_cdn_techsupport(self, config): con = ConfigParser() tftp_config = con.load_common_config().tftp_share remote_ip = tftp_config.tftp_server_ip remote_user = tftp_config.tftp_user remote_passwd = tftp_config.tftp_password tftp_root_dir = tftp_config.tftp_root_path tftp_handle = LinuxUtils(remote_ip, remote_user, remote_passwd) tftp_handle.connect() ts_path = tftp_root_dir + '/TechSupport/' tftp_handle.execute_cmd('mkdir -p ' + ts_path) tftp_handle.execute_cmd('chmod 777 ' + ts_path) tftp_handle.execute_cmd('tar -xzvf /TFTP_DIR/' + self.ts_file_path + ' ' + "-C" + ' ' + ts_path) platform_type = config.mgmtdetail.platform_series if platform_type == 'M5': cdn_ts = tftp_handle.execute_cmd('cat' + ' ' + ts_path + 'mnt/jffs2/BIOS/bt/BiosTech.log \ | grep "Patched eNIC Name"') else: cdn_ts = tftp_handle.execute_cmd('cat' + ' ' + ts_path + 'var/nuova/BIOS/BiosTech.txt \ | grep "Patched eNIC Name"') time.sleep(20) tftp_handle.disconnect() cdn_from_tsr = re.findall(r'=\s+([^\r\n\'\s]+)', cdn_ts) logger.info('CDN info from Tech-support data') logger.info(cdn_from_tsr) '''Getting CDN name from CIMC''' logger.info('Fetching CDN name from CIMC CLI') vic_list = config.inventory_detail vic_obj = VicLib(self, config) for vic in vic_list: slot_no = vic.slot_number out = vic_obj.cimc_cdn_mac_dict(slot_no) cnd_from_cimc = [] for cdn_name in out.values(): cnd_from_cimc.append(cdn_name) logger.info('CDN name from CIMC') logger.info(cnd_from_cimc) for val in cdn_from_tsr: if val not in cnd_from_cimc: logger.info( "From CIMC CDN name are not same as TSR CDN name") return False return True
def verify_host_after_bios_default(self, config, cimc_util_obj): ''' Test Case verify_host_after_bios_default ''' #Bios Config bios_obj = classparam['bios_obj'] host_detail_config = config.host_info[0].nw_intf_list[0] host_info_config = config.host_info[0].host_detail if bios_obj.load_bios_defaults() is False: self.failed("Failed to load bios defaults") else: res_host_up = cimc_util_obj.verify_host_up( hostname=host_detail_config.ip_address, wait_for_ping_fail=False) if res_host_up: logger.info('Host rebooted successfully after bios defaults') else: logger.warning('Issue with host reboot after bios default') logger.info("IP : "+host_detail_config.ip_address+ "\n user : "******"\n pass : "******"Unable to connect to host") else: self.passed( "Successfully booted to os after token change without any error" ) host.disconnect()
def get_release_note_content(self, config): try: mgmt_detail_obj = config.mgmtdetail plat = mgmt_detail_obj.platform platform = self.get_platform_name(plat) build = os.environ["BUILD"] huu_image = os.environ["HUU_IMAGE"] if not build: logger.error("Build is not set in environment variable") return False if not huu_image: logger.error("HUU IMAGE is not set in environment variable") return False huu_iso_file = "/var/www/html/HUU_Sanity/systemupgrade/isos/" + \ platform + "/" + build + "/" + huu_image logger.info("HUU FILe: " + huu_iso_file) host = LinuxUtils('10.127.45.20', 'root', 'HuuWelcome123') host.connect() if "No such file or directory" in host.execute_cmd("ls " + huu_iso_file): logger.error("HUU file not found in filer") return False # Mouting ISO logger.info("Mouting ISO" + huu_iso_file) mount_folder = "/mnt/" + \ re.search(r'(.*?)\.iso', huu_image).group(1) logger.info("Mount Foleder" + mount_folder) host.execute_cmd("mkdir " + mount_folder) # Check mount folder if "No such file or directory" in host.execute_cmd("ls " + mount_folder): logger.error("mount folder is not found in filer") return False host.execute_cmd("mount -o loop " + huu_iso_file + " " + mount_folder) if "No such file or directory" in host.execute_cmd("ls " + mount_folder + "/TOC*.xml"): logger.error("TOC file not found") return False toc_out = host.execute_cmd("cat " + mount_folder + "/TOC*.xml") host.disconnect() return toc_out except: dump_error_in_lib()
def verify_cpu_host(self, config): ''' Test Case verify_cpu_host ''' procc_obj = classparam['procc_obj'] cpu_list = classparam['cpu_info'] result = 'Pass' host_detail_config = config.host_info[0].nw_intf_list[0] host_info_config = config.host_info[0].host_detail logger.info("IP : "+host_detail_config.ip_address+ "\n user : "******"\n pass : "******"CPU OBJECT LIST") logger.info(cpu_list) host.disconnect() if len(cpu_list) > 0: thread_count_config = int( procc_obj.processor_config.thread_count) * len(cpu_list) else: self.failed("Error is getting CPU object list") if cpu_host_info['cores'] == procc_obj.processor_config.core_count: logger.info("Core count verification from host is successful") else: logger.error("Core count not matching : \n In host - " + str(cpu_host_info['cores'])) logger.error("In Config : " + str(procc_obj.processor_config.core_count)) result = 'Fail' if cpu_host_info['thread'] == thread_count_config: logger.info("Thread count verification from host is successful") else: logger.error("Thread count not matching : \n In host - " + str(cpu_host_info['thread'])) logger.error("In Config : " + str(thread_count_config)) result = 'Fail' if result == 'Pass': self.passed("Successfully verified core and thread in host") else: self.failed("Core and Thread verification failed")
def remove_techsupport_file(self): ''' Procedure to remove the tech-support file Returns: True: on success False: on failure ''' try: logger.info('Deleting tech-support file: ' + self.ts_file_path) con = ConfigParser() tftp_config = con.load_common_config().tftp_share remote_ip = tftp_config.tftp_server_ip remote_user = tftp_config.tftp_user remote_passwd = tftp_config.tftp_password handle = LinuxUtils(remote_ip, remote_user, remote_passwd) handle.connect() handle.execute_cmd('rm -f ' + '/TFTP_DIR/' + self.ts_file_path) handle.disconnect() except: dump_error_in_lib()
def asset_tag_puppet_desc_host(self, config): ''' Procedure to fetch assettag and puppet descriptin from host OS ''' log.info('Fetch the Asset tag/Puppet description from host OS') host_detail_config = config.host_info[0].nw_intf_list[0] host_info_config = config.host_info[0].host_detail log.info("############# Host Info ##########") log.info("IP : " + host_detail_config.ip_address + "\n user : "******"\n pass : "******"##################################") host_handle = LinuxUtils(host_detail_config.ip_address, host_info_config.os_login, host_info_config.os_password) if host_handle.connect() is False: log.error("Unable to connect to host") return False else: # Fetch asset tag out = host_handle.execute_cmd('dmidecode -t 2') res = re.search(r'Asset Tag:\s+([^\r\n]+)', out) if res is not None: self.asset_tag_host = res.group(1).strip() log.info('Host: AssetTag info: ' + self.asset_tag_host) else: log.error('Failed to get asset tag info') return False # Fetch Puppet description out2 = host_handle.execute_cmd('dmidecode -t 11') res2 = re.search(r'String 2:\s+([^\r\n]+)', out2) if res2 is not None: self.puppet_desc_host = res2.group(1).strip() log.info('Host: Puppet Description info: ' + self.puppet_desc_host) else: log.error('Failed to get puppet description') return False return True
class CimcUtils(object): hostName = 'None' waitForPingFail = 'None' def __init__(self, cimc_handle, telnet_handle=None, host_handle=None, config=None, common_config=None): self.handle = cimc_handle self.telnet_handle = telnet_handle self.host_handle = host_handle self.bios_util_obj = BiosUtils(self, config, common_config) self.config = config self.ts_file_path = None # self.ts_file_path = 'tmpAutomation-testCase-bmc-2016-12-27_23-11-34.tar.gz' ''' Contructor for the class Parameters: Will be taken from global variables client : handle for connection prompt : Need to update to handle different cases ''' def get_scope_output(self, *scope_list, cmnd='show detail'): for scope in scope_list: self.handle.execute_cmd(scope) if cmnd is None: cmnd = 'show detail' else: cmnd = cmnd return self.handle.execute_cmd(cmnd, wait_time=8) def power_cycle_host(self, wait_time=60): ''' Procedure to power cycle the host Parameter: handle : connection handle of cimc waitForPingFail : If true, will wait for ping to fail and then back up If False, will return True in case host is responding wait_time : Max time attempted to check host's availability Return: True : Success False : Failure ''' power_off = 0 power_on = 0 try: power_state = self.get_power_state() if power_state == 'off': logger.info('Host is already powered off, powering on') power_off = 1 self.set_host_power('on') else: self.handle.execute_cmd_list('top', 'scope chassis', 'power cycle', wait_time=6) time.sleep(1) self.handle.execute_cmd('y') # have to add validation max_wait_time = time.time() + wait_time # wait for 60 sec while True: power_state = self.get_power_state() if power_state == 'off': logger.info('Host is powered off') power_off = 1 elif power_state == 'on': logger.info('Host is powered on') power_on = 1 if power_on == 1 and power_off == 1: break if time.time() > max_wait_time: logger.info('Maximum timeout reached') break else: logger.info('Will continue to wait') time.sleep(2) if power_off == 1 and power_on == 1: logger.info('Successfully power cycled the host') return True else: logger.info('Failed to power cycled the host') return False except: dump_error_in_lib() return False def get_power_state(self): ''' Procedure to get current power state of host Parameter: handle : connection handle of cimc Return: Current power state: Success False : Failure ''' logger.info('Getting the current power state of host') try: self.handle.execute_cmd('top') self.handle.execute_cmd('scope chassis') out = self.handle.execute_cmd('show detail', wait_time=8) time.sleep(3) logger.info(out) return re.search(r'powerstate:\s+([^\r\n]+)', out).group(1) except: dump_error_in_lib() return False def set_host_power(self, power_state): ''' Procedure to power off/on the host Parameter: power_state: 'on' to power on the host 'off' to power off the host Return: True: Success False: Failure ''' try: cur_power_state = self.get_power_state() if cur_power_state == power_state: logger.info('Host is already in expected powered state: ' + cur_power_state) return True else: out = self.handle.execute_cmd_list('top', 'scope chassis', 'power ' + power_state, wait_time=6) if 'Do you want to continue' in out: self.handle.execute_cmd('y') else: logger.error('Failed to power off the host') return False cur_power_state = self.get_power_state() time.sleep(5) if cur_power_state == power_state: logger.info('Host is successfully set to: ' + cur_power_state) else: logger.error('Failed to power state of host to: ' + power_state) return False return True except: dump_error_in_lib() return False def reboot_bmc(self, handle): ''' Procedure to get current power state of host Parameter: handle : connection handle of cimc Return: True: Success False : Failure ''' logger.info('Rebooting CIMC') try: logger.info(handle.execute_cmd('scope cimc')) logger.info(handle.execute_cmd('reboot')) logger.info(handle.execute_cmd('y')) return True except: dump_error_in_lib() return False def reboot_bmc_and_connect(self, config): ''' Procedure to reboot BMC and reconnects the BMC Parameter: None Return: True: Success False : Failure ''' try: logger.info('Rebooting CIMC') self.handle.execute_cmd_list('top', 'scope cimc', 'reboot', 'y') mgmt_detail_obj = config.mgmtdetail bmc_ip = mgmt_detail_obj.bmc_mgmt_ip bmc_login = mgmt_detail_obj.bmc_login bmc_passwd = mgmt_detail_obj.bmc_password logger.info('Successfully rebooted BMC, Wait for BMC to come up') res = self.verify_host_up(bmc_ip, wait_time=500) if res is not True: logger.error('After BMC reboot, failed to ping BMC mgmt IP') return False else: logger.info( 'Successfully rebooted BMC, connecting back to BMC') self.handle = LinuxUtils(bmc_ip, bmc_login, bmc_passwd) self.handle.connect() return True except: dump_error_in_lib() return False def bmc_factory_reset_and_connect(self): ''' Wrapper procedure to perform BMC factory reset and reconnects to BMC Parameter: None Return: True: Success False : Failure ''' try: logger.info( 'bmc_factory_reset_and_connect: BMC factory reset and re-connect procedure' ) if self.telnet_handle.bmc_serial_recover_testbed( self.config) is False: logger.error('Failed: to perform factory reset and reconnect') return False mgmt_detail_obj = self.config.mgmtdetail bmc_ip = mgmt_detail_obj.bmc_mgmt_ip bmc_login = mgmt_detail_obj.bmc_login bmc_passwd = mgmt_detail_obj.bmc_password logger.info('Wait for BMC to come up') res = self.verify_host_up(bmc_ip, wait_time=180) if res is not True: logger.error( 'After BMC Factory reset, failed to ping BMC mgmnt IP') return False # reconnect the BMC after factory reset self.handle = LinuxUtils(bmc_ip, bmc_login, bmc_passwd) self.handle.connect() return True except: dump_error_in_lib() return False def ac_cycle_and_reconnect(self, config): logger.info('Performing AC cycle') apc_obj = config.apcdetails apc_ip = apc_obj.apc_ip port_list = apc_obj.port_list.split(',') model = apc_obj.model con = APCUtilClass(apc_ip, "apc1", "nbv12345") ret = con.ConnectToAPC() if ret != None: logger.info('Successfully connected to APC, model ' + model) else: logger.error('Failed to connect to APC, model ' + model) return False for port_num in port_list: logger.info('Switch off the power on port :' + port_num) # port_num = 10 operation = "off" val = con.SetPowerStatePort(port_num, operation) if val == None: logger.error('Failed to set power state of port number ' + str(port_num) + ' with : ' + operation) return False else: logger.info('Power state of port number ' + str(port_num) + ' set to : ' + operation) val = con.GetPowerStatePort(port_num) if val == None: logger.error('Failed to get power state of port number ' + str(port_num)) else: logger.info('Power state of port number ' + str(port_num) + ' is : ' + val) time.sleep(2) for port_num in port_list: logger.info('Switch On the power on port :' + port_num) operation = "on" val = con.SetPowerStatePort(port_num, operation) if val == None: logger.error('Failed to set power state of port number ' + str(port_num) + ' with : ' + operation) return False else: logger.info('Power state of port number ' + str(port_num) + ' set to : ' + operation) val = con.GetPowerStatePort(port_num) if val == None: logger.error('Failed to get power state of port number ' + str(port_num)) else: logger.info('Power state of port number ' + str(port_num) + ' is : ' + val) ''' reconnecting to mgmt handle ''' mgmt_detail_obj = config.mgmtdetail bmc_ip = mgmt_detail_obj.bmc_mgmt_ip bmc_login = mgmt_detail_obj.bmc_login bmc_passwd = mgmt_detail_obj.bmc_password res = self.verify_host_up(bmc_ip, wait_time=500) if res is not True: logger.error('After AC cycle, failed to ping BMC mgmt IP') return False else: logger.info('After AC cycle, able to ping BMC mgmt IP') self.handle = LinuxUtils(bmc_ip, bmc_login, bmc_passwd) self.handle.connect() return True def verify_host_up(self, hostname='default', wait_for_ping_fail=True, wait_time=500): ''' Procedure to verify if bmc/host is UP using ping Parameter: hostName : IP or hostname of the server to be checked waitForPingFail : If true, will wait for ping to fail and then back up If False, will return True in case host is responding wait_time : Max time attempted to check host's availability Return: True : Success False : Failure ''' pkt_count = 3 time_to_sleep = 10 ping_failed = False host_rebooted = False # sleep for wait_time timeout, default is max_wait_time = time.time() + wait_time if hostname == 'default': logger.info('Will use GlobalVariable for hostname : ' + str(hostname)) else: logger.info('Will verify for a provided host address : ' + str(hostname)) try: while True: # subpocess.check_output('/usr/bin/which ping') png_path = 'ping' logger.info('Ping tool path : ' + png_path) cmdstr = png_path + ' -c ' + str(pkt_count) + ' ' + hostname logger.info('Command: ' + cmdstr) exceptioncaught = False try: pngoutput = subprocess.check_output( cmdstr, shell=True, stderr=subprocess.STDOUT) except: # dump_error_in_lib() pngoutput = 'not all pings were successful' exceptioncaught = True logger.info('Output : ' + str(pngoutput)) obj = re.search( '[0-9]+ packets transmitted, [0-9]+ received, 0% packet loss', str(pngoutput)) logger.info('Object: ' + str(obj)) if obj != None and exceptioncaught != True: logger.info('Ping successful') if ping_failed == False and wait_for_ping_fail == True: logger.info('Ping failure didnt happen yet') else: logger.info('Host has rebooted and back up') host_rebooted = True break else: logger.info('Ping failed') ping_failed = True time.sleep(time_to_sleep) if time.time() > max_wait_time: logger.info('Maximum timeout reached') break else: logger.info('Will continue to wait') continue if host_rebooted == True: logger.info('Host successfully rebooted') return True else: logger.error('Host is not up') return False except: dump_error_in_lib() return False def HuuUpdate(self, huu_update_info, node='1'): ''' Method to update CIMC using HUU iso ''' mgmt_detail_obj = self.config.mgmtdetail bmc_ip = mgmt_detail_obj.bmc_mgmt_ip bmc_login = mgmt_detail_obj.bmc_login bmc_passwd = mgmt_detail_obj.bmc_password pl = mgmt_detail_obj.platform platformHash = { 'dn1': 'delnorte1', 'dn2': 'delnorte2', 'pl1': 'plumas1', 'pl2': 'plumas2', 'mad': 'madeira' } platform = platformHash[pl] logDir = easypy.runtime.directory logger.info('Log Dir is:' + logDir) release = huu_update_info[0] version = huu_update_info[1] node = '1' logger.info('**************************************') logger.info('HUU Update params are:') logger.info("platform {}, release {}, version {}".format( platform, release, version)) logger.info('**************************************') arg = "/data/home/releng/py/bin/python /auto/svbudata-home-bgl/releng/cluster_switch.main/rm_automation/tools/./upgradeWrapper1.py --testbed\ '{}' --cimcuserName '{}' --cimcPassword '{}' --updateComponent '{}' --platform '{}' --release '{}'\ --iso '{}' --logDir '{}' --serverNode {}".format( bmc_ip, bmc_login, bmc_passwd, 'all', platform, release, version, logDir, node) logger.info('upgrade command: ' + str(arg)) p = subprocess.Popen(arg, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() logger.info('Upgrade completed') logger.info('stdout: ' + str(out)) logger.info('stderr: ' + str(err)) if re.search("Firmware update successful for CIMC NOt found", str(out)): logger.error('CIMC update not found, HUU update failed') update = False elif re.search("Firmware update successful for CIMC", str(out)): logger.info( 'INFO : output_message : Firmware update successful for CIMC') update = True else: logger.error( 'ERROR: output_message : Firmware update successful for CIMC NOt found' ) update = False if update is False: logger.error('HUU Update Failed') return False else: logger.info('HUU upgrade success') # After HUU update connect back to CIMC self.handle = LinuxUtils(bmc_ip, bmc_login, bmc_passwd) self.handle.connect() return True def set_techsupport_param_value(self, param, new_value): ''' Procedure to set tech-support attribute values Parameter: handle: connection handle of cimc param: tech-support parameter value new_value: New desired value to set Return: True : Success False : Failure ''' logger.info('Setting tech-support parameter attribute values:') logger.info('Attribute: ' + str(param) + ' Value: ' + str(new_value)) self.handle.execute_cmd_list('top', 'scope cimc', 'scope tech-support') out = self.handle.execute_cmd('set ' + str(param) + ' ' + str(new_value), wait_time=8) match = re.search( 'invalid|exceeding|incomplete|Valid value|Maximum|cannot be used', out, re.I) if match is not None: logger.error('Failed to execute command; got error as: ' + str(match)) return False commit_out = self.handle.execute_cmd('commit') if re.search('ERROR', commit_out, re.IGNORECASE): logger.info('Unable to set parameter ' + str(param) + ' to ' + str(new_value) + ' : ' + str(commit_out)) self.handle.execute_cmd('discard') return False return True def get_techsupport_param_value(self, param): ''' Procedure to get tech-support attribute values Parameter: handle: connection handle of cimc param: tech-support parameter value Return: Value of the parameter that is asked False: Failure ''' try: logger.info('Fetching tech-support attribute param value: ' + str(param)) self.handle.execute_cmd_list('top', 'scope cimc', 'scope tech-support') out = self.handle.execute_cmd('show detail', wait_time=6) return re.search(param + ': ([^\r\n]+)', out).group(1) except: dump_error_in_lib() return False def check_techsupport_param_value(self, param, expected_value): ''' Procedure to validate tech-support attribute values Parameter: handle: connection handle of cimc param: tech-support parameter value expected_value: Value which we expect BMC to report back Return: True : Success False : Failure ''' try: if self.get_techsupport_param_value(param) is expected_value: return True else: return False except: dump_error_in_lib() return False def start_tech_support(self): ''' Procedure to start tech-support Parameter: handle: connection handle of cimc Return: True : Success False : Failure ''' try: self.handle.execute_cmd_list('top', 'scope cimc', 'scope tech-support') out = self.handle.execute_cmd('start', wait_time=8) logger.info(out) if "Tech Support upload started" in out: logger.info( 'Tech Support Upload start command was issued successfully' ) return True match = re.search( 'invalid command detected|Already an upload is in \ progress|Hostname/IP Address|is not reachable', out, re.I) if match is not None: logger.error('Can not issue tech-support start command') return False except: dump_error_in_lib() return False def has_techsupport_started(self): ''' Procedure to check whether tech-support has started collecting data Parameter: handle: connection handle of cimc Return: True : Success False : Failure ''' try: self.handle.execute_cmd_list('top', 'scope cimc', 'scope tech-support') out = self.handle.execute_cmd('show detail', wait_time=6) logger.info(out) out = re.search('remote-status: ([^\r\n]+)', out).group(1) if out == "COLLECTING": logger.info('The Update is in progress') return True elif out == "COMPLETED": logger.error( 'The tech-support status not started after start command was issued' ) return False except: dump_error_in_lib() return False def wait_for_techsupport_to_finish(self, wait_time=1200): ''' Procedure to wait until tech-support is completed Parameter: handle: connection handle of cimc Optional Param: wait_time: Maximum time to wait for tech-support to complete Return: True : Success False : Failure ''' try: max_wait_time = time.time() + wait_time while time.time() < max_wait_time: out = self.get_techsupport_param_value('progress') if out == "100": logger.info('Successfully uploaded tech-support data') return True elif 'Remote_Upload_Error' in out: logger.error('Upload error happened, will exit') return False time.sleep(10) logger.info('Will continue to wait') logger.info('Exceeded max wait time ' + str(max_wait_time) + ' seconds') return False except: dump_error_in_lib() return False def start_and_wait_for_ts_to_finish(self): ''' Wrapper procedure to start and wait for tech-support to complete Parameter: handle: connection handle of cimc Return: True : Success False : Failure ''' try: if self.start_tech_support() is False: logger.error('Tech-support start command failed') return False if self.has_techsupport_started() is False: logger.error( 'The tech-support status not started after start command was issued' ) return False if self.wait_for_techsupport_to_finish() is False: logger.error( "Tech support upload did not finish in max timeout seconds" ) return False return True except: dump_error_in_lib() return False def upload_techsupport_data(self, protocol='None'): ''' Wrapper procedure to start and wait for tech-support to complete Parameter: handle: connection handle of cimc Optional param: protocol: one of the protocol (currently supported 'tftp') Return: True : Success False : Failure ''' path_value = "remote-path" tftp_ip = "remote-ip" status_value = "remote-status" remore_protocol = "remote-protocol" time_stamp = strftime("%Y-%m-%d_%H-%M-%S") tftp_tmp_auto_file_name = 'tmpAutomation-testCase-bmc-' tftp_tmp_auto_file_name += str(time_stamp) tftp_tmp_auto_file_name += '.tar.gz' logger.info('Unique file name on TFTP server: ' + str(tftp_tmp_auto_file_name)) '''Set tech-support remote-path value''' if self.set_techsupport_param_value(path_value, tftp_tmp_auto_file_name) is False: logger.error('Failed to set remote-path value:' + str(tftp_tmp_auto_file_name)) return False '''set tech-support remote-ip parameter value''' '''Need to fetch this IP from config file''' remote_server_ip = '10.126.164.31' if self.set_techsupport_param_value(tftp_ip, remote_server_ip) is False: logger.error('Failed to set remote-ip value:' + str(remote_server_ip)) return False '''set remote protocol value''' if protocol is 'None': protocol = 'tftp' else: protocol = protocol '''Set tech-support remote-protocol parameter value''' if self.set_techsupport_param_value(remore_protocol, protocol) is False: logger.error('Failed to set remote-protocol value:' + str(protocol)) return False stage_value = self.get_techsupport_param_value(status_value) if stage_value == 'COLLECTING' or stage_value == 'UPLOADING': logger.error('BMC tech support progress is' + str(stage_value) + 'Can not continue') return False if self.start_and_wait_for_ts_to_finish() is False: return False self.ts_file_path = tftp_tmp_auto_file_name def get_cimc_sel_log_latest_event(self, log_scope='cimc'): ''' Procedure to get Latest Log entry before an event Return: returns latest event on : Success empty string if no CIMC logs : Failure Author : Jagadish Chanda <*****@*****.**> ''' try: logger.info("Inside get log proc") if log_scope == 'cimc': self.handle.execute_cmd_list('top', 'scope cimc', 'scope log') else: self.handle.execute_cmd_list('top', 'scope sel') log_before_event = self.handle.execute_cmd("show entries", wait_time=20) if '--More--' in log_before_event: log_output = self.handle.execute_cmd("R", wait_time=10) log_before_event += log_output while True: if '--More--' in log_output: log_output = self.handle.execute_cmd("R", wait_time=10) log_before_event += log_output log_output = '' else: break log_before_event = log_before_event.split("\n") if len(log_before_event) > 3: return log_before_event[3] else: logger.info( "There may be no CIMC Log entries before the event") return "" except: dump_error_in_lib() return False def clear_cimc_sel_logs(self, log_scope='cimc'): ''' Procedure to clear CIMC or SEL logs Parameter: log_scope: <cimc | sel> Return: True: On successfully clearing of logs False:On failed to clear logs ''' if log_scope == 'cimc': self.handle.execute_cmd_list('top', 'scope cimc', 'scope log') else: self.handle.execute_cmd_list('top', 'scope sel') out = self.handle.execute_cmd('clear') if 'Continue' in out: self.handle.execute_cmd('y') elif 'Clear the Cisco IMC log' in out: self.handle.execute_cmd('y') else: logger.warning('Failed to clear the logs') return False logger.info('Successfully cleared the logs') return True def check_cimc_sel_log_diff_event(self, log_before_event, log_scope='cimc', severity=["Critical"]): ''' Procedure to check cimc and sel log SEL : If the "log_scope" parameter should be sel and it will check for log diff and if any new log found it will return false CIMC : If log_scope parameter is cimc or by default it will get check cimc log. To check severity in cimc log pass the severity parameter as list with all desired severity. By default it will check for Critical event. Parameters: log_before_event: Latest Log entry before an event log_scope : cimc or sel (default cimc) severity : List severity to be checked.(default Critical events) Return: True if mention severity not found in the log: Success False : Failure Author : Jagadish Chanda <*****@*****.**> and Suren Kumar Moorthy<*****@*****.**> ''' try: if log_scope == 'cimc': self.handle.execute_cmd_list('top', 'scope cimc', 'scope log') else: self.handle.execute_cmd_list('top', 'scope sel') log_after_event = self.handle.execute_cmd('show entries', wait_time=20) if '--More--' in log_after_event: log_output = self.handle.execute_cmd("R") log_after_event += log_output while True: if '--More--' in log_output: log_output = self.handle.execute_cmd("R") log_after_event += log_output else: break log_after_event = log_after_event.split("\n") diff_list = [] if len(log_after_event) > 3: for i in range(3, len(log_after_event)): if log_after_event[i].strip( ) not in log_before_event.strip(): diff_list.append(log_after_event[i]) else: break else: logger.error("Failed to fetch the log difference") return False logger.info("######### Diff List ###################") logger.info(diff_list) logger.info("#########################################") if 'sel' in log_scope or 'cimc' in log_scope: if len(diff_list) > 0: logger.info(diff_list) logger.warning("Found Difference in sel/cimc log") log_found = 0 logger.info("######### Log Diff ##############") logger.info(diff_list) logger.info("#################################") if len(severity) > 1: sev_reg = "|".join(severity) elif len(severity) == 1: sev_reg = severity[0] else: sev_reg = 'Critical' rege = r'\d{2}\:\d{2}\:\d{2}\s+\w{3}\s+(?:' + sev_reg + ")" for log in diff_list: if re.search(rege, log): logger.error(log) log_found = 1 if log_found == 1: logger.error("Found called severity in log") return False else: return True except: dump_error_in_lib() return False def get_overall_health_status(self): ''' Procedure to get over all health status ''' return self.get_led_status() def get_led_status(self, led="LED_HLTH_STATUS"): ''' Procedure to get led state of server Parameter: led: Default - LED_HLTH_STATUS or Pass the appropriate led name to get the status Return: Led status: Success False : Failure Author: Suren kumar Moorthy ''' logger.info('Getting the LED status') try: out = self.handle.execute_cmd_list( ['top', 'scope chassis', 'show led detail'], wait_time=10) logger.info(out) regex = r'name\:\s*' + led + \ r'\s*state\s*\:\s*\w+\s*color\:\s*(\w+)' return re.search(regex, out).group(1) except: dump_error_in_lib() return False def validate_cdn_techsupport(self, config): con = ConfigParser() tftp_config = con.load_common_config().tftp_share remote_ip = tftp_config.tftp_server_ip remote_user = tftp_config.tftp_user remote_passwd = tftp_config.tftp_password tftp_root_dir = tftp_config.tftp_root_path tftp_handle = LinuxUtils(remote_ip, remote_user, remote_passwd) tftp_handle.connect() ts_path = tftp_root_dir + '/TechSupport/' tftp_handle.execute_cmd('mkdir -p ' + ts_path) tftp_handle.execute_cmd('chmod 777 ' + ts_path) tftp_handle.execute_cmd('tar -xzvf /TFTP_DIR/' + self.ts_file_path + ' ' + "-C" + ' ' + ts_path) platform_type = config.mgmtdetail.platform_series if platform_type == 'M5': cdn_ts = tftp_handle.execute_cmd('cat' + ' ' + ts_path + 'mnt/jffs2/BIOS/bt/BiosTech.log \ | grep "Patched eNIC Name"') else: cdn_ts = tftp_handle.execute_cmd('cat' + ' ' + ts_path + 'var/nuova/BIOS/BiosTech.txt \ | grep "Patched eNIC Name"') time.sleep(20) tftp_handle.disconnect() cdn_from_tsr = re.findall(r'=\s+([^\r\n\'\s]+)', cdn_ts) logger.info('CDN info from Tech-support data') logger.info(cdn_from_tsr) '''Getting CDN name from CIMC''' logger.info('Fetching CDN name from CIMC CLI') vic_list = config.inventory_detail vic_obj = VicLib(self, config) for vic in vic_list: slot_no = vic.slot_number out = vic_obj.cimc_cdn_mac_dict(slot_no) cnd_from_cimc = [] for cdn_name in out.values(): cnd_from_cimc.append(cdn_name) logger.info('CDN name from CIMC') logger.info(cnd_from_cimc) for val in cdn_from_tsr: if val not in cnd_from_cimc: logger.info( "From CIMC CDN name are not same as TSR CDN name") return False return True def remove_techsupport_file(self): ''' Procedure to remove the tech-support file Returns: True: on success False: on failure ''' try: logger.info('Deleting tech-support file: ' + self.ts_file_path) con = ConfigParser() tftp_config = con.load_common_config().tftp_share remote_ip = tftp_config.tftp_server_ip remote_user = tftp_config.tftp_user remote_passwd = tftp_config.tftp_password handle = LinuxUtils(remote_ip, remote_user, remote_passwd) handle.connect() handle.execute_cmd('rm -f ' + '/TFTP_DIR/' + self.ts_file_path) handle.disconnect() except: dump_error_in_lib() def get_sensor_data(self, type='voltage'): output = self.handle.execute_cmd_list('top', 'scope sensor', 'show ' + type) sensor_list = output.splitlines() sensor_out = [] for sensor in sensor_list: if sensor != sensor_list[0] and sensor != sensor_list[ 1] and sensor != sensor_list[2] and sensor != sensor_list[ 3] and sensor != sensor_list[4]: sensor_data = [] for val in sensor.split(' '): if val != '': sensor_data.append(val) sensor_out.append(sensor_data) logger.info('sensor out is') logger.info(sensor_out) return sensor_out def verfiy_sol_screen(self, config): sol_enabled = self.bios_util_obj.get_common_token_value( "enabled", "sol") logger.info("Sol enabled value is" + sol_enabled) if 'no' in sol_enabled: status = self.bios_util_obj.set_common_token_value("enabled", "yes", "sol", commit_wait=120) if status is False: logger.error("Failed to set sol enabled to yes") return False sol_out = self.handle.execute_cmd_list('top', 'scope sol', 'connect host', "\n") logger.info(sol_out) host_info_obj = config.host_info[0].host_detail prompt = host_info_obj.os_host_name logger.info("Prompt " + prompt) out = self.handle.execute_cmd_list(chr(24)) logger.info(out) if prompt in sol_out: logger.info("Successfully verified sol") return True elif re.search(r'(login)|(password)\:', sol_out).group(0): logger.info( "Successfully verified sol matched login or password prompt") return True else: logger.error("Failed to verify sol") return False def get_platform_name(self, plat): plat_dict = {"dn1": "delnorte1"} return plat_dict[plat] def get_release_note_content(self, config): try: mgmt_detail_obj = config.mgmtdetail plat = mgmt_detail_obj.platform platform = self.get_platform_name(plat) build = os.environ["BUILD"] huu_image = os.environ["HUU_IMAGE"] if not build: logger.error("Build is not set in environment variable") return False if not huu_image: logger.error("HUU IMAGE is not set in environment variable") return False huu_iso_file = "/var/www/html/HUU_Sanity/systemupgrade/isos/" + \ platform + "/" + build + "/" + huu_image logger.info("HUU FILe: " + huu_iso_file) host = LinuxUtils('10.127.45.20', 'root', 'HuuWelcome123') host.connect() if "No such file or directory" in host.execute_cmd("ls " + huu_iso_file): logger.error("HUU file not found in filer") return False # Mouting ISO logger.info("Mouting ISO" + huu_iso_file) mount_folder = "/mnt/" + \ re.search(r'(.*?)\.iso', huu_image).group(1) logger.info("Mount Foleder" + mount_folder) host.execute_cmd("mkdir " + mount_folder) # Check mount folder if "No such file or directory" in host.execute_cmd("ls " + mount_folder): logger.error("mount folder is not found in filer") return False host.execute_cmd("mount -o loop " + huu_iso_file + " " + mount_folder) if "No such file or directory" in host.execute_cmd("ls " + mount_folder + "/TOC*.xml"): logger.error("TOC file not found") return False toc_out = host.execute_cmd("cat " + mount_folder + "/TOC*.xml") host.disconnect() return toc_out except: dump_error_in_lib()
def specjvm_test(self, cimc_util_obj): ''' Runs specjvm at 30,90 and 180 ops and checks for error in host , cimc log , sel log ''' host_ping_status = cimc_util_obj.verify_host_up( hostname=self.host_ip, wait_for_ping_fail=False, wait_time=30) if host_ping_status is True: logger.info("Host OS is pinging ...") else: output = self.boot_order_obj.set_boot_order_HDD() if output == True: host_ping_status = cimc_util_obj.verify_host_up( hostname=self.host_ip, wait_for_ping_fail=False, wait_time=600) if host_ping_status is True: logger.info("Host OS is pinging ...") else: self.failed( "Testcase failed .... since Unabke to boot to OS") ops_list = [30, 90, 180] spec_jvm_pid = '' spec_jvm_kill = "kill -9 " + spec_jvm_pid time_out = 2 host = self.host host.connect() host_utils = self.host_utils host_log_flag = False sel_log_flag = False cimc_log_flag = False handle_2 = LinuxUtils(host.ip, host.username, host.password) handle_2.connect() for ops in ops_list: logger.info("Running specJVM at " + str(ops) + " Ops") logs_before_stress = host_utils.get_host_logs(host) cimc_log_before = cimc_util_obj.get_cimc_sel_log_latest_event() sel_log_before = cimc_util_obj.get_cimc_sel_log_latest_event( log_scope='sel') spec_jvm_cmd = "java -jar /root/tools/SPECjvm2008.jar -ikv -ops " + \ str(ops) + " crypto.aes > /root/tools/specjvm.txt 2>&1 &" spec_jvm_pid = self.get_pid(handle_2.execute_cmd(spec_jvm_cmd)) start_time = strftime("%H", gmtime()) end_time = strftime("%H", gmtime()) time.sleep((3600 * time_out) / 4) while (abs(int(start_time) - int(end_time)) <= time_out): end_time = strftime("%H", gmtime()) out = host.execute_cmd("ps -ef | grep SPECjvm") ps_out = '\t'.join([line.strip() for line in out.splitlines()]) logger.info("process out is" + ps_out) if spec_jvm_pid in ps_out: time.sleep(60) else: break if (abs(int(start_time) - int(end_time))) > time_out: host.execute_cmd('kill -9 ' + spec_jvm_pid) logs_after_stress = host_utils.get_host_logs(host) cimc_log_flag = cimc_util_obj.check_cimc_sel_log_diff_event( cimc_log_before) cimc_log_flag = True sel_log_flag = cimc_util_obj.check_cimc_sel_log_diff_event( sel_log_before, log_scope='sel') sel_log_flag = True host_log_flag = host_utils.check_host_logs_diff( logs_before_stress, logs_after_stress) if host_log_flag and cimc_log_flag and sel_log_flag: continue else: self.failed("Difference in host log") host.disconnect() handle_2.disconnect() if host_log_flag: self.passed("Spec JVM ran successfully") else: self.failed("Difference in host log")
class MemoryModeAndPorTest(aetest.Testcase): ''' Note :mem_mode_array=["Maximum_Performance", "Mirroring", "Lockstep"] has to be passed from the job file ''' @aetest.setup def setup(self, mem_mode_array, cimc_util_obj, config): ''' Loops through testcase for all the memory mode config passed from job file and loads host related details ''' host_detail_config = config.host_info[0].nw_intf_list[0] host_info_config = config.host_info[0].host_detail logger.info("IP : " + host_detail_config.ip_address + "\n user : "******"\n pass : "******"Host OS is pinging ...") else: output = self.boot_order_obj.set_boot_order_HDD() if output == True: host_ping_status = cimc_util_obj.verify_host_up( hostname=self.host_ip, wait_for_ping_fail=False, wait_time=600) if host_ping_status is True: logger.info("Host OS is pinging ...") else: logger.error("ERROR :Host OS is not pinging \ ,after setting the boot order to HDD and retrying ..." ) logger.error( "Testcase failed .... since Unabke to boot to OS") aetest.loop.mark(self.validate_memory_config_in_cimc_and_host, mem_mode=mem_mode_array) @aetest.test def validate_memory_config_in_cimc_and_host(self, mem_mode, cimc_util_obj, config): ''' Test case covers configuring memory mode and validating in CIMC , host, EFI Shell , BIOS post ''' mem_obj = MemoryLib(cimc_util_obj) self.mem_obj = mem_obj # set memory mode res_mem_mode = mem_obj.configure_ras_mode(mem_mode) res_host_up = False if res_mem_mode == True: logger.info('Memory mode configured successfully') #host_ip = config.host_info[0].host_detail.os_host_name # power cycle host cimc_util_obj.power_cycle_host() time.sleep(60) # verify host is up res_host_up = cimc_util_obj.verify_host_up(hostname=self.host_ip, wait_for_ping_fail=True) if res_host_up: logger.info( 'Host rebooted successfully after memory configuration') else: output = self.boot_order_obj.set_boot_order_HDD() if output == True: logger.info("Host OS is pinging ...") else: logger.error("ERROR :Host OS is not pinging \ ,after setting the boot order to HDD and retrying ..." ) logger.warning( 'Issue with host reboot starting to collect tech support' ) cimc_util_obj.upload_techsupport_data() self.failed('Issue with host') # verify memory por after config res_mem_por = mem_obj.verify_expected_frequency() # verify total and effective memory res_mem_config = mem_obj.verify_memory_config() # Linux host validation host_details = config.host_info[0].host_detail self.host_handle = LinuxUtils(host_details.os_host_name, host_details.os_login, host_details.os_password) self.host_handle.connect() mem_obj = MemoryLib(cimc_util_obj, self.host_handle) self.mem_obj = mem_obj res_mem_host = mem_obj.verify_memory_config_in_linux_host() res_mem_efi = mem_obj.verify_memory_config_in_efi_shell() if res_mem_por and res_mem_config and res_mem_host and res_mem_efi[ 0] and res_mem_efi[1]: self.passed('memory validation in host is successful') else: logger.error( 'memory por , mem_config ,host results,EFI and POST results are below:' ) logger.error(res_mem_por) logger.error(res_mem_config) logger.error(res_mem_host) logger.error(res_mem_efi[0]) logger.error(res_mem_efi[1]) self.failed('Issue with memory validation in host') else: logger.error('Issue in configuring memory mode') cimc_util_obj.upload_techsupport_data() self.failed('test cases failed because of memory configuration') @aetest.test def verify_dimm_pid(self, cimc_util_obj, config): ''' validates cimc dimm pid inventory with config file ''' mem_obj = MemoryLib(cimc_util_obj) self.mem_obj = mem_obj mem_dict = mem_obj.get_mem_pid() dimm_validation = True for val in mem_dict: if mem_dict[val] in config.dimm_pid: continue else: dimm_validation = False logger.error('DIMM pid not found in list' + str(mem_dict[val])) if dimm_validation: logger.info('PID list from config') logger.info(config.dimm_pid) self.passed('DIMM PID verified') else: self.failed('DIMM PID verification failed') @aetest.test def cpu_and_memory_stress_using_ptu(self, cimc_util_obj): ''' Runs ptugen and ptumon and monitor for any errors ''' host_ping_status = cimc_util_obj.verify_host_up( hostname=self.host_ip, wait_for_ping_fail=False, wait_time=30) if host_ping_status is True: logger.info("Host OS is pinging ...") else: output = self.boot_order_obj.set_boot_order_HDD() if output == True: host_ping_status = cimc_util_obj.verify_host_up( hostname=self.host_ip, wait_for_ping_fail=False, wait_time=600) if host_ping_status is True: logger.info("Host OS is pinging ...") else: self.failed( "Testcase failed .... since Unabke to boot to OS") host = self.host host_utils = self.host_utils ptu_gen_cmd = "/root/tools/ptugen -ct 1 -mt 2 -t " ptu_gen_log_path = 'cat /root/tools/ptu_gen_file.txt' wait_time = 60 host.connect() time.sleep(5) logs_before_stress = host_utils.get_host_logs(host) cimc_log_before = cimc_util_obj.get_cimc_sel_log_latest_event() sel_log_before = cimc_util_obj.get_cimc_sel_log_latest_event( log_scope='sel') logger.info( "Successfully booted to os after token change without any error") ptugen_out = host_utils.start_ptu_gen(host, ptu_gen_cmd, wait=wait_time) time.sleep(wait_time) ptumon_out = host_utils.get_ptu_monitor_out(host, scope='MEM') time.sleep(wait_time) ptugen_out = host.execute_cmd(ptu_gen_log_path, buffer_size=500000, wait_time=wait_time) logs_after_stress = host_utils.get_host_logs(host) cimc_log_flag = cimc_util_obj.check_cimc_sel_log_diff_event( cimc_log_before) cimc_log_flag = True sel_log_flag = cimc_util_obj.check_cimc_sel_log_diff_event( sel_log_before, log_scope='sel') sel_log_flag = True host_log_flag = host_utils.check_host_logs_diff( logs_before_stress, logs_after_stress) logger.info('ptugen out') logger.info(ptugen_out) logger.info('ptumon out') logger.info(ptumon_out) host.disconnect() if host_log_flag and cimc_log_flag and sel_log_flag: self.passed("Stress ran successfully") else: self.failed("Issue during stress") @aetest.test def mprime_test(self, cimc_util_obj): ''' Runs mprime and monitor for error ''' host_ping_status = cimc_util_obj.verify_host_up( hostname=self.host_ip, wait_for_ping_fail=False, wait_time=30) if host_ping_status is True: logger.info("Host OS is pinging ...") else: output = self.boot_order_obj.set_boot_order_HDD() if output == True: host_ping_status = cimc_util_obj.verify_host_up( hostname=self.host_ip, wait_for_ping_fail=False, wait_time=600) if host_ping_status is True: logger.info("Host OS is pinging ...") else: self.failed( "Testcase failed .... since Unabke to boot to OS") mprime_cmd = "/root/tools/mprime >> /root/tools/mprime.txt &" mprime_stress_time = 1800 mprime_pid = '' mprime_kill = "kill -9 " + mprime_pid host = self.host host_utils = self.host_utils host.connect() logs_before_stress = host_utils.get_host_logs(host) cimc_log_before = cimc_util_obj.get_cimc_sel_log_latest_event() sel_log_before = cimc_util_obj.get_cimc_sel_log_latest_event( log_scope='sel') mprime_pid = host.execute_cmd(mprime_cmd) mprime_pid = self.get_pid(mprime_pid) time.sleep(mprime_stress_time) logger.info('mprime pid is : ' + mprime_pid) host.execute_cmd(mprime_kill) time.sleep(5) logs_after_stress = host_utils.get_host_logs(host) cimc_log_flag = cimc_util_obj.check_cimc_sel_log_diff_event( cimc_log_before) sel_log_flag = cimc_util_obj.check_cimc_sel_log_diff_event( sel_log_before, log_scope='sel') sel_log_flag = True host_log_flag = host_utils.check_host_logs_diff( logs_before_stress, logs_after_stress) host.disconnect() if host_log_flag and cimc_log_flag and sel_log_flag: self.passed("Stress ran successfully") else: self.failed("Issue during stress") @aetest.test def specjvm_test(self, cimc_util_obj): ''' Runs specjvm at 30,90 and 180 ops and checks for error in host , cimc log , sel log ''' host_ping_status = cimc_util_obj.verify_host_up( hostname=self.host_ip, wait_for_ping_fail=False, wait_time=30) if host_ping_status is True: logger.info("Host OS is pinging ...") else: output = self.boot_order_obj.set_boot_order_HDD() if output == True: host_ping_status = cimc_util_obj.verify_host_up( hostname=self.host_ip, wait_for_ping_fail=False, wait_time=600) if host_ping_status is True: logger.info("Host OS is pinging ...") else: self.failed( "Testcase failed .... since Unabke to boot to OS") ops_list = [30, 90, 180] spec_jvm_pid = '' spec_jvm_kill = "kill -9 " + spec_jvm_pid time_out = 2 host = self.host host.connect() host_utils = self.host_utils host_log_flag = False sel_log_flag = False cimc_log_flag = False handle_2 = LinuxUtils(host.ip, host.username, host.password) handle_2.connect() for ops in ops_list: logger.info("Running specJVM at " + str(ops) + " Ops") logs_before_stress = host_utils.get_host_logs(host) cimc_log_before = cimc_util_obj.get_cimc_sel_log_latest_event() sel_log_before = cimc_util_obj.get_cimc_sel_log_latest_event( log_scope='sel') spec_jvm_cmd = "java -jar /root/tools/SPECjvm2008.jar -ikv -ops " + \ str(ops) + " crypto.aes > /root/tools/specjvm.txt 2>&1 &" spec_jvm_pid = self.get_pid(handle_2.execute_cmd(spec_jvm_cmd)) start_time = strftime("%H", gmtime()) end_time = strftime("%H", gmtime()) time.sleep((3600 * time_out) / 4) while (abs(int(start_time) - int(end_time)) <= time_out): end_time = strftime("%H", gmtime()) out = host.execute_cmd("ps -ef | grep SPECjvm") ps_out = '\t'.join([line.strip() for line in out.splitlines()]) logger.info("process out is" + ps_out) if spec_jvm_pid in ps_out: time.sleep(60) else: break if (abs(int(start_time) - int(end_time))) > time_out: host.execute_cmd('kill -9 ' + spec_jvm_pid) logs_after_stress = host_utils.get_host_logs(host) cimc_log_flag = cimc_util_obj.check_cimc_sel_log_diff_event( cimc_log_before) cimc_log_flag = True sel_log_flag = cimc_util_obj.check_cimc_sel_log_diff_event( sel_log_before, log_scope='sel') sel_log_flag = True host_log_flag = host_utils.check_host_logs_diff( logs_before_stress, logs_after_stress) if host_log_flag and cimc_log_flag and sel_log_flag: continue else: self.failed("Difference in host log") host.disconnect() handle_2.disconnect() if host_log_flag: self.passed("Spec JVM ran successfully") else: self.failed("Difference in host log") @aetest.test def mem_test(self, cimc_util_obj): '''Random value,XOR comparison,SUB comparison,MUL comparison,DIV comparison,OR comparison ,AND comparison Sequential Increment, Block Sequential, Solid Bits, Bit Flip, Checkerboard ,Walking Ones ,Walking Zeroes , Bit Spread ''' host_ping_status = cimc_util_obj.verify_host_up( hostname=self.host_ip, wait_for_ping_fail=False, wait_time=30) if host_ping_status is True: logger.info("Host OS is pinging ...") else: output = self.boot_order_obj.set_boot_order_HDD() if output == True: host_ping_status = cimc_util_obj.verify_host_up( hostname=self.host_ip, wait_for_ping_fail=False, wait_time=600) if host_ping_status is True: logger.info("Host OS is pinging ...") else: self.failed( "Testcase failed .... since Unabke to boot to OS") memory_in_mb = '20000' memtest_cmd = "memtester " + memory_in_mb + \ " >> /root/tools/memtest.txt &" memtest_stress_time = 1800 memtest_pid = '' memtest_kill = "kill -9 " + memtest_pid host = self.host host_utils = self.host_utils host.connect() logs_before_stress = host_utils.get_host_logs(host) cimc_log_before = cimc_util_obj.get_cimc_sel_log_latest_event() sel_log_before = cimc_util_obj.get_cimc_sel_log_latest_event( log_scope='sel') memtest_pid = host.execute_cmd(memtest_cmd) memtest_pid = self.get_pid(memtest_pid) time.sleep(memtest_stress_time) logger.info('memtest pid is : ' + memtest_pid) host.execute_cmd(memtest_kill) time.sleep(5) logs_after_stress = host_utils.get_host_logs(host) cimc_log_flag = cimc_util_obj.check_cimc_sel_log_diff_event( cimc_log_before) cimc_log_flag = True sel_log_flag = cimc_util_obj.check_cimc_sel_log_diff_event( sel_log_before, log_scope='sel') sel_log_flag = True host_log_flag = host_utils.check_host_logs_diff( logs_before_stress, logs_after_stress) host.disconnect() if host_log_flag and sel_log_flag and cimc_log_flag: self.passed("Stress ran successfully") else: self.failed("Issue during stress") def get_pid(self, process_log): ''' process the log and gets the process id ''' return process_log.splitlines()[1].replace('[1]', '').replace(' ', '')
class APCUtilClass(object): def __init__(self, ApcIP, APCUser, APCPass): ''' Contructor for the class Parameters: ApcIP : APC IP address or hostname APCUser: Username to use for connection APCPass: Password for connection client : handle for connection prompt : Need to update to handle different cases ''' self.ApcIP = ApcIP self.APCUser = APCUser self.APCPass = APCPass self.client = None self.prompt = '>' def ConnectToAPC(self): ''' Connect to APC using interactive shell The procedure uses SSH to connect to APC Basic error handling ''' try: cmd = '/usr/bin/ssh -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no ' cmd += self.APCUser cmd += '@' cmd += self.ApcIP logger.info('Command : %s ' % cmd) self.client = pexpect.spawn(cmd) self.client.expect('password') self.client.sendline(self.APCPass) self.client.expect(self.prompt) return (self.client) except Exception as inst: logger.info('Caught exception while connecting to APC %s ' % self.ApcIP) logger.info(type(inst)) logger.info(inst.args) logger.info(inst) return (None) def DisnnectFromAPC(self): ''' Disnnect From APC Close the Connection handle after operations are done Basic error handling ''' try: self.client.sendline("exit") return (0) except Exception as inst: logger.info('Caught exception while connecting to APC %s ' % self.ApcIP) logger.info(type(inst)) logger.info(inst.args) logger.info(inst) return (None) def GetPowerStatePort(self, portNum): ''' Get Power status for APC port Uses the port number passed to procedure and returns the current status Input : Port number to which server is connected Returns : on/off in case of success : None in case of Failure Assumption: user passes the appropriate port number Basic error checking ''' try: command = "show outlets " command += str(portNum) self.client.sendline(command) self.client.expect(self.prompt) output = self.client.before logger.info('output: ' + output.decode('ascii')) match = re.search("Power state:[ ]+([^\r\n]+)", output.decode('ascii')) power_state = None if match != None: power_state = match.group(1) else: power_state = None return (power_state) except Exception as inst: logger.info('Caught exception while executing command %s ' % command) logger.info(type(inst)) logger.info(inst.args) logger.info(inst) def SetPowerStatePort(self, portNum, operation): ''' Set Power status for APC port Set the port state to on or off depending on need Input : on for powering on a port : off for powering off a port : (other values will be rejected) Returns : 1 in case of success : None in case of failure Assumption: user passes the appropriate port number Basic error checking ''' try: if operation == "on" or operation == "off": logger.info('Valid Value passed for operation') else: logger.info('Please pass valid value on/off for operation') return (None) command = "power outlets " command += str(portNum) command += " " command += operation self.client.sendline(command) self.client.expect('y/n]') self.client.sendline('y') self.client.expect(self.prompt) output = self.client.before logger.info('output: ' + output.decode('ascii')) return (1) except Exception as inst: logger.info('Caught exception while executing command %s ' % command) logger.info(type(inst)) logger.info(inst.args) logger.info(inst) return (None) def apc_cycle_and_reconnect(self, config): con = APCUtilClass("10.127.51.191", "apc1", "nbv12345") ret = con.ConnectToAPC() if ret != None: logger.info('Successfully connected to APC') else: logger.error('Failed to connect to APC') return False portNum = 10 operation = "off" val = con.SetPowerStatePort(portNum, operation) if val == None: logger.error('Failed to set power state of port number ' + str(portNum) + ' with : ' + operation) return False else: logger.info('Power state of port number ' + str(portNum) + ' set to : ' + operation) val = con.GetPowerStatePort(portNum) if val == None: logger.error('Failed to get power state of port number ' + str(portNum)) else: logger.info('Power state of port number ' + str(portNum) + ' is : ' + val) operation = "on" val = con.SetPowerStatePort(portNum, operation) if val == None: logger.error('Failed to set power state of port number ' + str(portNum) + ' with : ' + operation) return False else: logger.info('Power state of port number ' + str(portNum) + ' set to : ' + operation) val = con.GetPowerStatePort(portNum) if val == None: logger.error('Failed to get power state of port number ' + str(portNum)) else: logger.error('Power state of port number ' + str(portNum) + ' is : ' + val) ''' reconnecting to mgmt handle ''' mgmt_detail_obj = config.mgmtdetail bmc_ip = mgmt_detail_obj.bmc_mgmt_ip bmc_login = mgmt_detail_obj.bmc_login bmc_passwd = mgmt_detail_obj.bmc_password res = self.cimc_utils_obj.verify_host_up(bmc_ip, wait_time=500) if res is not True: logger.error('After AC cycle, failed to ping BMC mgmt IP') return False else: logger.info('After AC cycle, able to ping BMC mgmt IP') self.handle = LinuxUtils(bmc_ip, bmc_login, bmc_passwd) self.handle.connect() return True
def powercycle_and_verify_cdn_on_cimc_and_host(self, slot_no): ''' procedure to verify cdn details from CIMC and Host side Parameter: slot_no: adapter slot no. Return: True: Success False : FAILURE Author : jchanda ''' res = self.cimc_obj.power_cycle_host() if res is not True: logger.error('Failed to power cycle the host') time.sleep(60) # verify host is up host_detail_obj = self.config.host_info[0].host_detail host_ip = host_detail_obj.os_host_name res_host_up = self.cimc_obj.verify_host_up(hostname=host_ip) if res_host_up: logger.info('Host rebooted successfully after creating new vNIC') else: logger.warn('Issue with host reboot') '''Get the interface details in Dictionary ['mac_addr' : 'cdn_name']''' cimc_dict = self.cimc_cdn_mac_dict(slot_no) logger.info('vNIC interface mac:cdn details from CIMC: ' + str(cimc_dict)) if cimc_dict is False: logger.warn('CIMC CDN mac list is empty') return False host_user = host_detail_obj.os_login host_passwd = host_detail_obj.os_password ntw_list = self.config.host_info[0].nw_intf_list for intf in ntw_list: if intf.is_mgmt_intf == 'yes': logger.info('Host Managment IP is: ' + intf.ip_address) host_ip = intf.ip_address '''connect to host and get CDN details''' host_handle = LinuxUtils(host_ip, host_user, host_passwd) host_handle.connect() host_dict = self.host_cdn_mac_dict(host_handle, 'biosdevname -d') logger.info('vNIC interface mac:cdn details from Host: ' + str(host_dict)) match = True for key in cimc_dict.keys(): if key in host_dict.keys(): if cimc_dict[key] != host_dict[key]: logger.error( 'After OS boot, CDN name set from CIMC CLI and Host are not same' ) logger.error('CDN name from CIMC:' + cimc_dict[key] + 'Host CDN: ' + host_dict[key]) match = False else: logger.info( 'After OS boot, CDN name set from CIMC CLI and Host are remains same' ) logger.info('Configure CDN name from CIMC: ' + cimc_dict[key] + ' Host CDN: ' + host_dict[key]) if match is True: return True else: return False
def cpu_frequency_eist_turbo_ed(self, config, parameter, cimc_util_obj): bios_obj = classparam['bios_obj'] procc_obj = classparam['procc_obj'] host_util = classparam['host_utils'] ######## Bios Default ############################# if bios_obj.load_bios_defaults() is False: self.failed("Failed to load bios defaults") else: logger.info("Waiting for host to reboot after load bios default") time.sleep(180) ################################################## if bios_obj.set_bios_token_value( parameter, 'Disabled', commit_wait=150) is False: self.failed("Failed to Disable " + parameter) else: turbo_value = bios_obj.get_bios_token_value(parameter) if 'Disabled' not in turbo_value: self.failed("Disabling " + parameter + " token failed") host_detail_config = config.host_info[0].nw_intf_list[0] host_info_config = config.host_info[0].host_detail logger.info("IP : " + host_detail_config.ip_address + "\n user : "******"\n pass : "******"Host OS is not pinging") if host.connect() is False: self.failed("Unable to connect to host") else: logger.info( "Successfully booted to os after token change without any error" ) logger.info("Keeping host for 5mins before PTU monitor") time.sleep(300) param_key = PARAM_TOKEN[parameter] config_frequency = float( getattr(procc_obj.processor_config, param_key)) logger.info("Config core val " + str(config_frequency)) if host_util.start_ptu_gen(host, wait=60) is False: self.failed("Failed to start PTU stress") host.disconnect() else: platform_type = config.mgmtdetail.platform_series avg_cpu_list = host_util.get_ptu_monitor_out(host) if len(avg_cpu_list) < 1: self.failed("Error is getting average frequency") for ind, core_freq in enumerate(avg_cpu_list): if platform_type == 'M5': core_freq = core_freq * 1000 if core_freq - 1000 <= config_frequency <= core_freq + 1000: logger.info("Successfully Verified core " + str(ind) + " frequency after stress when " + parameter + " Disabled :(" + str(core_freq) + ")") else: logger.error("Core " + str(ind) + " value not satisfied with config : " + str(core_freq)) result = 'Fail' host.disconnect() if result == 'Pass': self.passed( "Processor frequency verification for all cores successful" ) else: self.failed( "Frequency value in idle state not matched with PTU value")
def verify_cpu_frequency_eist_turbo(self, config, parameter): bios_obj = classparam['bios_obj'] procc_obj = classparam['procc_obj'] host_util = classparam['host_utils'] ######## Bios Default ############################# if bios_obj.load_bios_defaults() is False: self.failed("Failed to load bios defaults") else: logger.info("Waiting for host to reboot after load bios default") time.sleep(180) ################################################### host_detail_config = config.host_info[0].nw_intf_list[0] host_info_config = config.host_info[0].host_detail logger.info("############# Host Info ##########") logger.info("IP : " + host_detail_config.ip_address + "\n user : "******"\n pass : "******"##################################") result = 'Pass' host = LinuxUtils(host_detail_config.ip_address, host_info_config.os_login, host_info_config.os_password) if host.connect() is False: self.failed("Unable to connect to host") else: logger.info( "Successfully booted to os after token change without any error" ) eist_value = bios_obj.get_bios_token_value( 'EnhancedIntelSpeedStep') logger.info("Currently EIST is " + eist_value) turbo_value = bios_obj.get_bios_token_value('IntelTurboBoostTech') logger.info("Currently Turbo is " + turbo_value) if 'Enabled' not in eist_value: self.failed("Eist is not set to enabled") if 'Enabled' not in turbo_value: self.failed("Turbo is not set to enabled") cores_enabled = bios_obj.get_bios_token_value( 'CoreMultiProcessing') if parameter in cores_enabled: logger.info("Enabled cores is " + cores_enabled) logger.info("#########Param" + parameter + "########") logger.info(PARAM_DICT_PTU) logger.info("####################################") param_key = PARAM_DICT_PTU[parameter] logger.info("Config Key " + param_key) max_core_config = float( getattr(procc_obj.processor_config, param_key)) logger.info("Config core val " + str(max_core_config)) if host_util.start_ptu_gen(host, wait=600) is False: self.failed("Failed to start PTU stress") host.disconnect() else: platform_type = config.mgmtdetail.platform_series avg_cpu_list = host_util.get_ptu_monitor_out(host) if len(avg_cpu_list) < 1: self.failed("Error is getting average frequency") for ind, core_freq in enumerate(avg_cpu_list): if platform_type == 'M5': core_freq = core_freq * 1000 if core_freq - 1000 <= max_core_config <= core_freq + 1000: logger.info("Successfully Verified core " + str(ind) + " frequency after stress when " + parameter + " enabled :(" + str(core_freq) + ")") else: logger.error( "Core " + str(ind) + " value not satisfied with config : " + str(core_freq)) result = 'Fail' else: self.failed("Expected cores not got enabled(" + cores_enabled + ")") host.disconnect() host.disconnect() if result == 'Pass': self.passed( "Processor frequency verification for all cores successful" ) else: self.failed( "Frequency value in idle state not matched with PTU value")
def verify_processor_frequency_idlestate(self, config): bios_obj = classparam['bios_obj'] procc_obj = classparam['procc_obj'] host_util = classparam['host_utils'] ######## Bios Default ############################# if bios_obj.load_bios_defaults() is False: self.failed("Failed to load bios defaults") else: logger.info("Waiting for host to reboot after load bios default") time.sleep(180) #################################################### host_detail_config = config.host_info[0].nw_intf_list[0] host_info_config = config.host_info[0].host_detail logger.info("##### Host Detail ####################") logger.info("IP : " + host_detail_config.ip_address + "\n user : "******"\n pass : "******"#####################################") host = LinuxUtils(host_detail_config.ip_address, host_info_config.os_login, host_info_config.os_password) if host.connect() is False: self.failed("Unable to connect to host") else: logger.info( "Successfully booted to os after token change without any error" ) logger.info("Keeping host for 5mins before PTU monitor") time.sleep(300) # Average frequency from ptu platform_type = config.mgmtdetail.platform_series avg_cpu_list = host_util.get_ptu_monitor_out(host, wait=600) if len(avg_cpu_list) < 1: self.failed("Error is getting average frequency") logger.info(avg_cpu_list) #idle_freq = round(float(procc_obj.processor_config.cpu_maxcore_turbo), 2) idle_freq = round( float(procc_obj.processor_config.cpu_lowest_freq), 2) logger.info('Idle frequency from config file is: ' + str(idle_freq)) result = 'Pass' for ind, core_freq in enumerate(avg_cpu_list): if platform_type == 'M5': core_freq = core_freq * 1000 if core_freq - 600 <= idle_freq <= core_freq + 600: logger.info("Successfully Verified core " + str(ind) + " frequency in idle state(" + str(core_freq) + ")") else: logger.error("Core " + str(ind) + " value not satisfied the idle frequency : " + str(core_freq)) result = 'Fail' host.disconnect() if result == 'Pass': self.passed( "Processor frequency verification for all cores successful" ) else: self.failed( "Frequency value in idle state not matched with PTU value")
def verfiy_hyper_thread(self, config, cimc_util_obj, parameter): bios_obj = classparam['bios_obj'] host_util = classparam['host_utils'] procc_obj = ProcessorUtils(classparam['bios_obj']) host_detail_config = config.host_info[0].nw_intf_list[0] host_info_config = config.host_info[0].host_detail ######## Bios Default ############################# if bios_obj.load_bios_defaults() is False: self.failed("Failed to load bios defaults") else: res_host_up = cimc_util_obj.verify_host_up( hostname=host_detail_config.ip_address, wait_for_ping_fail=False) if res_host_up: logger.info('Host rebooted successfully after bios defaults') else: logger.warning('Issue with host reboot after bios default') #################################################### htpthd_value = bios_obj.get_bios_token_value('IntelHyperThread') logger.info("##########################################") logger.info("Currently Hyper Thread Token is " + htpthd_value) logger.info("##########################################") if 'Enabled' not in htpthd_value: self.failed("Hyper Thread is not set to enabled") cores_enabled = bios_obj.get_bios_token_value('CoreMultiProcessing') if parameter != cores_enabled: if bios_obj.set_bios_token_value('CoreMultiProcessing', parameter, commit_wait=150) is False: self.failed("Failed to set core enabled to " + parameter) else: cores_enabled1 = bios_obj.get_bios_token_value( 'CoreMultiProcessing') if parameter != cores_enabled1: self.failed("Failed to set core enabled to " + parameter) logger.info("################################################") logger.info("Successfully set the core enabled to " + parameter) logger.info("################################################") logger.info("############## Host Info ####################") logger.info("IP : " + host_detail_config.ip_address + "\n user : "******"\n pass : "******"#############################################") result = 'Pass' status = host_util.check_host_up(cimc_util_obj, procc_obj.boot_order_obj, config) if status is False: self.failed('Host is not up') host = LinuxUtils(host_detail_config.ip_address, host_info_config.os_login, host_info_config.os_password) if host.connect() is False: self.failed("Unable to connect to host") else: logger.info( "################################################################" ) logger.info( "Successfully booted to os after token change without any error" ) logger.info( "#################################################################" ) cpu_host_info = procc_obj.get_cpu_info_host(host) logger.info("Enabled cores is " + cores_enabled) if parameter == 'All': physical_core = int(procc_obj.processor_config.core_count) else: physical_core = int(parameter) cpu_list = classparam['cpu_info'] logger.info("CPU list") logger.info(cpu_list) if len(cpu_list) > 0: calculated_logical_core = int(physical_core) * len( cpu_list) * 2 else: self.failed("Error in getting CPU object") logger.info("################################################") logger.info("Logical and Physical values") logger.info("Logical : " + str(cpu_host_info['thread'])) logger.info("Physical : " + str(physical_core)) logger.info("################################################") if cpu_host_info['thread'] == calculated_logical_core: logger.info( "Logical thread is equal to calculated logical core from physical core thread" ) else: logger.error("Logical Core not matching: \n Logical- " + str(cpu_host_info['thread']) + "Calculated Logical core" + str(calculated_logical_core)) result = 'Fail' host.disconnect() if result == 'Pass': self.passed("Physical and logical core comparison passed") else: self.failed("Physical and logical core comparison failed")
class FirmwareUtils(): def __init__(self, cimc_utils_obj, common_config, config=None): self.handle = cimc_utils_obj.handle self.cimc_utils_obj = cimc_utils_obj self.common_config = common_config self.tftp_ip = self.common_config.tftp_share.tftp_server_ip self.tftp_user = self.common_config.tftp_share.tftp_user self.tftp_password = self.common_config.tftp_share.tftp_password self.tftp_handle = LinuxUtils(self.tftp_ip, self.tftp_user, self.tftp_password) self.tftp_root_dir = self.common_config.tftp_share.tftp_root_path self.cap_image_file_path = None self.host_ip = common_utils.get_host_mgmt_ip(config) def bios_update(self, protocol='tftp'): ''' procedure to update BIOS firmware using default protocol Parameters: protocol: protocol for the file transfer Address: IP address or Hostname of remote server PATH: File path to BIOS firmware (.cap) file on the remote server Author: jchanda ''' '''power off the host, it is required to update the bios firmware''' if self.cimc_utils_obj.set_host_power('off') is not True: logger.error('Failed to power off the host, aborting BIOS Upgrade') return False self.handle.execute_cmd_list('top', 'scope bios') if protocol is 'tftp': cap_image_file_path = '/'.join( self.cap_image_file_path.split('/')[2:4]) bios_update_cmd = 'update' + ' ' + protocol + ' ' + self.tftp_ip + ' ' + cap_image_file_path logger.info('update command:' + bios_update_cmd) bios_out = self.handle.execute_cmd(bios_update_cmd, wait_time=8) if 'bios update has started' in bios_out: logger.info('BIOS Update has started') else: logger.error('Failed to start BIOS Update. Command output: ' + bios_out) return False wait_time = 10 logger.info('Sleep for ' + str(wait_time) + ' seconds before checking BIOS upgrade status') time.sleep(wait_time) upgrade_done = 0 wait_time = 600 max_wait_time = time.time() + wait_time while time.time() < max_wait_time: res = self.handle.execute_cmd('show detail') print(res) if re.search('fw-status: Done, OK', res, re.I): upgrade_done = 1 break elif re.search('Error,', res, re.I): regex = 'Error,' + '\s*([^\\r\\n]+)' err_msg = re.search(regex, res).group(1) logger.error('BIOS Update failed: ' + err_msg) break else: logger.info( 'BIOS Firmware image download in-progress. Will continue to wait' ) time.sleep(5) if upgrade_done == 0: logger.info('Download failed or Exceeded max wait time ' + str(max_wait_time) + ' seconds') return False logger.info('Activating the backup BIOS version') if upgrade_done == 1: out2 = self.handle.execute_cmd('activate') if 'Continue' in out2: self.handle.execute_cmd('y') else: logger.error('Failed to activate the BIOS firmware') return False logger.info('BIOS update completed successfully') return True def bios_update_cfc_image(self, protocol='tftp', activate='no'): ''' procedure to update BIOS CFC firmware using default protocol Parameters: protocol: protocol for the file transfer Address: IP address or Hostname of remote server PATH: File path to BIOS firmware (.cap) file on the remote server Author: jchanda ''' self.handle.execute_cmd_list('top', 'scope bios') if protocol is 'tftp': cfc_image_file_path = '/'.join( self.cfc_image_file_path.split('/')[2:4]) bios_update_cmd = 'update' + ' ' + protocol + ' ' + self.tftp_ip + ' ' + cfc_image_file_path logger.info('update command:' + bios_update_cmd) bios_out = self.handle.execute_cmd(bios_update_cmd, wait_time=8) if 'bios update has started' in bios_out: logger.info('BIOS Update has started') else: logger.error('Failed to start BIOS Update. Command output: ' + bios_out) return False wait_time = 10 logger.info('Sleep for ' + str(wait_time) + ' seconds before checking BIOS upgrade status') time.sleep(wait_time) upgrade_done = 0 wait_time = 600 max_wait_time = time.time() + wait_time while time.time() < max_wait_time: res = self.handle.execute_cmd('show detail') print(res) if re.search('fw-status: Done, OK', res, re.I): upgrade_done = 1 break elif re.search('Error,', res, re.I): regex = 'Error,' + '\s*([^\\r\\n]+)' err_msg = re.search(regex, res).group(1) logger.error('BIOS Update failed: ' + err_msg) break else: logger.info( 'BIOS Firmware image download in-progress. Will continue to wait' ) time.sleep(5) if upgrade_done == 0: logger.info('Download failed or Exceeded max wait time ' + str(max_wait_time) + ' seconds') return False else: logger.info('Successfully updated the BIOS image on backup bank') if activate == 'yes': logger.info('Activating the backup BIOS version') # power off the host before activating backup bios if self.cimc_utils_obj.set_host_power('off') is not True: logger.error( 'Failed to power off the host, aborting BIOS Activate') return False if upgrade_done == 1: self.handle.execute_cmd_list('top', 'scope bios') out2 = self.handle.execute_cmd('activate') if 'Continue' in out2: self.handle.execute_cmd('y') # res = self.cimc_utils_obj.verify_host_up(self.host_ip, wait_for_ping_fail=False) # if res is False: # logger.warning('Failed to ping the host after activating backup bios') # else: # logger.info("Host IP pinging successfully after activating backup bios") else: logger.error('Failed to activate the BIOS firmware') return False logger.info('BIOS update and activate successful') return True else: logger.info('BIOS update completed successfully') return True def activate_bios_image(self): ''' Procedure to activate BIOS backup image ''' logger.info('Activating the backup BIOS version') # power off the host before activating backup bios if self.cimc_utils_obj.set_host_power('off') is not True: logger.error( 'Failed to power off the host, aborting BIOS activate') return False self.handle.execute_cmd_list('top', 'scope bios') out = self.handle.execute_cmd('activate') if 'Continue' in out: self.handle.execute_cmd('y') elif 'Please power off the system and then run this command' in out: logger.error( 'Make sure host is powered OFF, before activating BIOS') return False else: logger.error('Failed to activate the BIOS firmware') return False logger.info('Successfully activated BIOS backup image') return True def prepare_bios_cfc_image_file(self, bios_image_path): ''' Procedure to get extract the container zip file and fetch bios CAP file for update Parameter: system_image : container file in the form of zip file Return: True : Success False : Failure Author: jchanda ''' logger.info( 'Copying the BIOS CFC image file to TFTP share folder for BIOS update' ) cmd = 'ls ' + bios_image_path + ' ' + '| grep cfc | grep -v D.cfc' cfc_image_file = subprocess.getoutput(cmd) if 'No such file or directory' in cfc_image_file: logger.error('BIOS CFC image file does not exists') return False logger.info('BIOS CFC Image file: ' + cfc_image_file) # Connect to remote TFTP filer server self.tftp_handle.connect() logger.info('Successfully connected to remote tftp server') logger.info('Creating dir in remote server') remote_path = self.tftp_root_dir + '/' + 'bios_' + str(int( time.time())) self.tftp_handle.execute_cmd('mkdir -p ' + remote_path) logger.info('Copying the BIOS CFC image to remote tftp share server') res = self.tftp_handle.copy_local_to_remote( bios_image_path + '/' + str(cfc_image_file), remote_path + '/' + str(cfc_image_file)) if res is not True: logger.error('Failed to copy bios cfc image file :' + cfc_image_file) return False else: logger.info('Successfully copied file: ' + cfc_image_file) #self.tftp_handle.execute_cmd('chmod 755' + ' ' + '../../../'+cap_file_name) self.cfc_image_file_path = remote_path + '/' + cfc_image_file return True def prepare_bios_image_file(self, system_image): ''' Procedure to get extract the container zip file and fetch bios CAP file for update Parameter: system_image : container file in the form of zip file Return: True : Success False : Failure Author: jchanda ''' logger.info('Extract zip file and set BIOS CAP file name for update') image_name = system_image.split('/')[-1] self.tftp_handle.connect() logger.info('Successfully connected to remote tftp server') logger.info('Creating dir in remote server') remote_path = self.tftp_root_dir + '/' + 'bios_' + str(int( time.time())) self.tftp_handle.execute_cmd('mkdir -p ' + remote_path) logger.info('Copying the system image to remote tftp share server') res = self.tftp_handle.copy_local_to_remote( system_image, remote_path + '/' + image_name) if res is not True: logger.error('Failed to copy file') return False else: logger.info('Successfully copied file') logger.info('Extracting the zip file, and fetch CAP file') self.tftp_handle.execute_cmd('cd ' + remote_path) time.sleep(1) self.tftp_handle.execute_cmd('unzip ' + image_name) time.sleep(2) cap_file_dir = '*/bios/cimc' self.tftp_handle.execute_cmd('cd ' + cap_file_dir) out = self.tftp_handle.execute_cmd('ls | grep -i cap | grep -i bios') for line in out.splitlines(): if (re.search('\.cap', line, re.I)): cap_file_name = line.strip() logger.info('Cap file name for bios update: ' + cap_file_name) self.tftp_handle.execute_cmd('cp ' + cap_file_name + ' ' + ' ../../../' + cap_file_name) self.tftp_handle.execute_cmd('ls -l ' + ' ' + '../../../' + cap_file_name) self.tftp_handle.execute_cmd('chmod 755' + ' ' + '../../../' + cap_file_name) self.cap_image_file_path = remote_path + '/' + cap_file_name return True ''' if os.path.exists(self.cap_image_file_path): logger.info('BIOS image CAP file on remote tftp server: {}'.format(self.cap_image_file_path)) return True else: logger.error('BIOS image CAP file does not exists') return False ''' def update_vic_firmware(self, adapter_slot, vic_fw_image, protocol='tftp'): ''' procedure to update VIC firmware using default protocol Parameters: protocol: protocol for the file transfer Address: IP address or Hostname of remote server PATH: File path to VIC firmware file on the remote server Author: jchanda ''' logger.info('Extract zip file and set BIOS CAP file name for update') image_name = vic_fw_image.split('/')[-1] self.tftp_handle.connect() logger.info('Successfully connected to remote tftp server') logger.info('Creating dir in remote server') remote_path = self.tftp_root_dir + '/' + 'vic_' + str(int(time.time())) self.tftp_handle.execute_cmd('mkdir -p ' + remote_path) logger.info('Copying the VIC fw image to remote tftp share server') res = self.tftp_handle.copy_local_to_remote( vic_fw_image, remote_path + '/' + image_name) if res is not True: logger.error('Failed to copy file') return False else: logger.info('Successfully copied file') logger.info('Make sure that host is up') if self.cimc_utils_obj.set_host_power('on') is not True: logger.error( 'Failed to power cycle the host, aborting BIOS Upgrade') return False logger.info( 'Check whether VIC firmware image file exists on remote share server' ) vic_fw_file_path = remote_path + '/' + image_name out = self.tftp_handle.execute_cmd('ls ' + vic_fw_file_path) if 'No such file or directory' in out: logger.warn( 'VIC firmware image {} not found in remote share server'. format(vic_fw_file_path)) return 'SKIP' self.handle.execute_cmd_list('top', 'scope chassis') if protocol is 'tftp': vic_fw_file = '/'.join(vic_fw_file_path.split('/')[2:4]) else: vic_fw_file = vic_fw_file_path vic_fiw_update_cmd = 'update-adapter-fw ' + protocol + ' ' + self.tftp_ip + ' ' + vic_fw_file + ' no-activate ' + adapter_slot vic_out = self.handle.execute_cmd(vic_fiw_update_cmd, wait_time=60) if 'Adapter firmware update has started' in vic_out: logger.info('VIC firmware Update has started') else: logger.error( 'Failed to start VIC firmware update for adapter slot {}'. format(adapter_slot)) return False upgrade_done = 0 wait_time = 300 max_wait_time = time.time() + wait_time while time.time() < max_wait_time: res = self.handle.execute_cmd('show adapter detail') if re.search('fw-update-status: Firmware update complete', res, re.I): upgrade_done = 1 break elif re.search('Error,', res, re.I): regex = 'Error,' + '\s*([^\\r\\n]+)' err_msg = re.search(regex, res).group(1) logger.error('VIC firmware Update failed: ' + err_msg) break else: logger.info( 'VIC Firmware image download in-progress. Will continue to wait' ) time.sleep(2) if upgrade_done == 1: logger.info('VIC Firmware update completed successfully') return True else: logger.info('Download failed or Exceeded max wait time ' + str(max_wait_time) + ' seconds') return False
class BiosUtils(): def __init__(self, cimc_obj, config=None, common_config=None): self.handle = cimc_obj.handle self.cimc_obj = cimc_obj self.remote_ip = None self.cap_image_file_path = None self.config = config self.common_config = common_config self.tftp_ip = self.common_config.tftp_share.tftp_server_ip self.tftp_user = self.common_config.tftp_share.tftp_user self.tftp_password = self.common_config.tftp_share.tftp_password self.tftp_handle = LinuxUtils(self.tftp_ip, self.tftp_user, self.tftp_password) self.tftp_root_dir = self.common_config.tftp_share.tftp_root_path self.host_ip = get_host_mgmt_ip(config) def select_token_scope(self, token): ''' BIOS token Dictionary ''' # M5 platform bios token Dictionary m5_token_dict = { 'memory': ['MemoryMappedIOAbove4GB', 'NUMAOptimize', 'SelectMemoryRAS'], 'processor': [ 'CoreMultiProcessing', 'EnhancedIntelSpeedStep', 'ExecuteDisable', 'IntelHyperThread', 'IntelTurboBoostTech', 'IntelVT', 'LocalX2Apic', 'ProcessorC1E', 'ProcessorC6Report' ], 'security': ['PowerOnPassword', 'TPMControl', 'TXTSupport'], 'server-management': [ 'BORCoolDown', 'BORNumRetry', 'BaudRate', 'BootOptionRetry', 'ConsoleRedir', 'FRB-2', 'FlowCtrl', 'OSBootWatchdogTimer', 'OSBootWatchdogTimerPolicy', 'OSBootWatchdogTimerTimeout', 'TerminalType', 'cdnEnable' ], 'power-or-performance': [ 'AdjacentCacheLinePrefetch', 'CPUPerformance', 'DcuIpPrefetch', 'DcuStreamerPrefetch', 'HardwarePrefetch' ], 'input-output': [ 'ATS', 'AllLomPortControl', 'AllPCIeSlotsOptionROM', 'CoherencySupport', 'IntelVTD', 'LomOpromControlPort0', 'LomOpromControlPort1', 'PcieSlot1LinkSpeed', 'PcieSlot1OptionROM', 'PcieSlot2LinkSpeed', 'PcieSlot2OptionROM', 'PcieSlotFrontNvme1LinkSpeed', 'PcieSlotFrontNvme2LinkSpeed', 'PcieSlotHBALinkSpeed', 'PcieSlotHBAOptionROM', 'PcieSlotMLOMLinkSpeed', 'PcieSlotMLOMOptionROM', 'PcieSlotN1OptionROM', 'PcieSlotN2OptionROM', 'SataModeSelect', 'UsbLegacySupport', 'VgaPriority', 'pSATA' ] } # M4 platform bios token Dictionary m4_token_dict = { 'main': ['POPSupport', 'TPMAdminCtrl'], 'server-management': [ 'FRB-2', 'OSBootWatchdogTimer', 'OSBootWatchdogTimerPolicy', 'OSBootWatchdogTimerTimeout' ], 'advanced': [ 'ASPMSupport', 'ATS', 'AdjacentCacheLinePrefetch', 'AllLomPortControl', 'AllUsbDevices', 'Altitude', 'AutonumousCstateEnable', 'BaudRate', 'BootPerformanceMode', 'CPUPowerManagement', 'ChannelInterLeave', 'CmciEnable', 'CoherencySupport', 'ConsoleRedir', 'CoreMultiProcessing', 'CpuEngPerfBias', 'CpuPerformanceProfile', 'DcuIpPrefetch', 'DcuStreamerPrefetch', 'DemandScrub', 'DirectCacheAccess', 'EnhancedIntelSpeedStep', 'ExecuteDisable', 'FlowCtrl', 'HWPMEnable', 'HardwarePrefetch', 'IntelHyperThread', 'IntelTurboBoostTech', 'IntelVT', 'IntelVTD', 'InterruptRemap', 'LegacyUSBSupport', 'LocalX2Apic', 'LomOpromControlPort0', 'LomOpromControlPort1', 'MemoryMappedIOAbove4GB', 'NUMAOptimize', 'PCIROMCLP', 'PCIeSSDHotPlugSupport', 'PackageCstateLimit', 'PassThroughDMA', 'PatrolScrub', 'PchUsb30Mode', 'PcieOptionROMs', 'PcieSlot1OptionROM', 'PcieSlot2OptionROM', 'PcieSlotFrontSlot5LinkSpeed', 'PcieSlotFrontSlot6LinkSpeed', 'PcieSlotHBALinkSpeed', 'PcieSlotHBAOptionROM', 'PcieSlotMLOMLinkSpeed', 'PcieSlotMLOMOptionROM', 'PcieSlotN1OptionROM', 'PcieSlotN2OptionROM', 'PcieSlotRiser1LinkSpeed', 'PcieSlotRiser2LinkSpeed', 'ProcessorC1E', 'ProcessorC3Report', 'ProcessorC6Report', 'PsdCoordType', 'PuttyFunctionKeyPad', 'PwrPerfTuning', 'QPILinkFrequency', 'QpiSnoopMode', 'RankInterLeave', 'RedirectionAfterPOST', 'SataModeSelect', 'SelectMemoryRAS', 'SrIov', 'TerminalType', 'UsbEmul6064', 'UsbPortFront', 'UsbPortInt', 'UsbPortKVM', 'UsbPortRear', 'UsbPortVMedia', 'UsbXhciSupport', 'VgaPriority', 'WorkLdConfig', 'cdnEnable', 'comSpcrEnable' ] } platform_type = self.config.mgmtdetail.platform_series logger.info('Platform Series Type is: ' + platform_type) if platform_type == 'M4': token_dict = m4_token_dict elif platform_type == 'M5': token_dict = m5_token_dict else: logger.error( 'Unable to detect platform series type. Please check whether defined in config file or not.\ if not please update config file with server series type.' ) return False for key in token_dict: if token in token_dict[key]: logger.info('"%s" token is associated with "%s" scope' % (token, key)) return key logger.error( 'Failed to locate "%s" token with its corresponding scope' % (token)) return False def token_map(self): platform_type = self.config.mgmtdetail.platform_series if platform_type == 'M4': token_supp_val = 'COM_0' elif platform_type == 'M5': token_supp_val = 'COM_0' else: logger.error('Unable to detect platform series type:' + platform_type) return False return token_supp_val def enable_disable_sol(self, value='no'): ''' Procedure to enable or disable SOL''' self.handle.execute_cmd_list('top', 'scope sol', 'set enabled ' + value) commit_out = self.handle.execute_cmd('commit', wait_time=8) if re.search('ERROR', commit_out, re.IGNORECASE): logger.info('Unable commit SOL parameters' + str(commit_out)) self.handle.execute_cmd('discard') return False return True def get_bios_token_value(self, token): ''' Procedure to get bios values by passing its token name Parameter: param: Default - None or Pass the appropriate name of the token to get the value (Pass sub scope name to get token values inside sub scopes like advance,server-management,main,bios-profile,boot-device) Return: Token value: Success False : Failure Author: Suren kumar Moorthy ''' logger.info('Getting bios token value') sub_scope = self.select_token_scope(token) if sub_scope is False: logger.error('Failed to get "%s" token associated scope mapping' % (token)) return False try: if sub_scope is None: out = self.handle.execute_cmd_list('top', 'scope bios', 'show detail', wait_time=8) else: out = self.handle.execute_cmd_list('top', 'scope bios', 'scope ' + sub_scope, 'show detail', wait_time=8) logger.info(out) regex = token + r'\s*\:\s+([^\r\n]+)' return re.search(regex, out).group(1) except: dump_error_in_lib() return False def set_bios_token_value(self, token, new_value, reboot='yes', commit_wait=150): ''' Procedure to get bios values by passing its token name Parameter: param: Default - None or Pass the appropriate name of the token to get the value (Pass sub scope name to get token values inside sub scopes like advance,server-management,main,bios-profile,boot-device) Return: Token value: Success False : Failure Author: Suren kumar Moorthy ''' logger.info('Getting bios token value') sub_scope = self.select_token_scope(token) if sub_scope is False: logger.error('Failed to get "%s" token associated scope mapping') return False try: if sub_scope is None: self.handle.execute_cmd_list('top', 'scope bios') else: self.handle.execute_cmd_list('top', 'scope bios', 'scope ' + sub_scope) time.sleep(3) out = self.handle.execute_cmd('set ' + token + ' ' + new_value, wait_time=8) match = re.search( 'invalid|exceeding|incomplete|Valid value\ |cannot be used', out, re.I) time.sleep(2) if match is not None: logger.error('Failed to execute command; got error as: ' + str(match)) return False commit_out = self.handle.execute_cmd('commit', wait_time=commit_wait) logger.info('commit out is ' + token + ' to ' + new_value + ' : ' + str(commit_out)) if re.search('ERROR', commit_out, re.IGNORECASE): logger.info('Unable to set parameter ' + token + ' to ' + new_value + ' : ' + str(commit_out)) self.handle.execute_cmd('discard') return False if 'Do you want to reboot the system' in commit_out or 'Your changes will be reflected' in commit_out: logger.info('inside Do u want to reboot check') if reboot is 'yes': reboot_out = self.handle.execute_cmd('y', wait_time=150) if 'A system reboot has been initiated' in reboot_out: logger.info('Successfully set the token ' + token + ' and host reboot initiated.') time.sleep(180) else: logger.error( 'Failed to initiate host reboot after setting bios token' ) return False else: reboot_out = self.handle.execute_cmd('N', wait_time=6) if 'Changes will be applied on next reboot' in reboot_out: logger.info('Successfully set the token, \ changes will reflect in next host reboot') else: logger.error('Failed to set' + token + ' to new value ' + new_value) return False else: logger.warn('Unexpected output') return False return True except: curframe = inspect.currentframe() calframe = inspect.getouterframes(curframe, 2) logger.error("Error occured at the library function call name :" + str(calframe[1][3])) logger.error("Error occured is " + sys.exc_info().__str__()) return False return True def load_bios_defaults(self, clear_cmos=None, restore='Yes'): ''' Procedure to set bios tokens to default values Parameter: None Return: True : Success False : Failure Author: jchanda ''' try: if clear_cmos is None: out = self.handle.execute_cmd_list('top', 'scope bios', 'bios-setup-default', wait_time=6) else: out = self.handle.execute_cmd_list('top', 'scope bios', 'clear-cmos', wait_time=6) if 'Continue' in out: out = self.handle.execute_cmd('y') if re.search('Error', out): logger.error( 'Failed to perform operation. Got Error Msg: ' + out) return False time.sleep(180) logger.info("Waiting for host to come up") if restore == 'Yes': if self.set_bios_token_value("ConsoleRedir", self.token_map(), commit_wait=150) is False: logger.error("Failed to set consoleRedir") return False except: dump_error_in_lib() return False return True def restore_tokens_to_defaults(self, restore_type): ''' Procedure to set bios tokens to default values Parameter: None Return: True : Success False : Failure Author: jchanda ''' try: logger.info('Performing bios restore operation: %s' % (restore_type)) self.handle.execute_cmd_list('top', 'scope bios') if restore_type == 'bios-setup-default': out = self.handle.execute_cmd('bios-setup-default') elif restore_type == 'clear-cmos': # Power off the system to run clear-cmos command self.cimc_obj.set_host_power('off') out = self.handle.execute_cmd_list('top', 'scope bios', 'clear-cmos') elif restore_type == 'restore-mfg-defaults': # Power off the system to run restore-mfg-defaults command self.cimc_obj.set_host_power('off') out = self.handle.execute_cmd_list('top', 'scope bios', 'restore-mfg-defaults') else: logger.warning('Invalid bios token restore option: %s' % (restore_type)) return False if 'Continue' in out: out = self.handle.execute_cmd('y') if re.search('Error', out): logger.error( 'Failed to perform %s operation. Got Error Msg: %s ' % (restore_type, out)) return False logger.info("Waiting for host to come up") res = self.cimc_obj.verify_host_up(hostname=self.host_ip, wait_for_ping_fail=False) if res is False: logger.warning('Failed to ping the host') except: dump_error_in_lib() return False logger.info('Successfully performed operation %s' % (restore_type)) return True def restore_mfg_defaults(self): ''' Procedure to Reset BIOS setup parameters to manufacturing defaults ''' # Power off the system to run restore-mfg-defaults command if self.cimc_obj.set_host_power('off') is False: logger.error('Failed to power of host') return False out = self.handle.execute_cmd_list('top', 'scope bios', 'restore-mfg-defaults') if 'Continue' in out: self.handle.execute_cmd('y') else: logger.error('Failed: restore-mfg-defaults operation failed') return False logger.info('Host will be powered on. Will wait for host to ping') res = self.cimc_obj.verify_host_up(hostname=self.host_ip, wait_for_ping_fail=False) if res is False: logger.warning('Failed to ping the host') logger.info('Passed: restore-mfg-defaults operation succeeds') return True def get_bios_token_value_list(self, token=[]): ''' Procedure to get bios values by passing its token name Parameter: param: Default - None or Pass the appropriate name of the token list to get the value (Pass sub scope name to get token values inside sub scopes like advance,server-management,main,bios-profile,boot-device) Return: Token value in dictionary format: Success False : Failure Author: Suren kumar Moorthy ''' logger.info('Getting bios token value') try: token_dict = defaultdict(dict) for tok in token: sub_scope = self.select_token_scope(tok) if sub_scope is False: logger.error( 'Failed to get "%s" token associated scope mapping' % (tok)) return False out = self.handle.execute_cmd_list('top', 'scope bios', 'scope ' + sub_scope, 'show detail') logger.info(out) regex = tok + r'\s*\:\s+([^\r\n]+)' token_dict[tok] = re.search(regex, out).group(1) return token_dict except: dump_error_in_lib() return False def set_bios_token_value_list(self, token_dict, reboot='yes', commit_wait=150): ''' Procedure to get bios values by passing its token name Parameter: param: Default - None or Pass the appropriate name of the token to get the value (Pass sub scope name to get token values inside sub scopes like advance,server-management,main,bios-profile,boot-device) Return: Token value: Success False : Failure Author: Suren kumar Moorthy ''' logger.info('Getting bios token value') try: for token, new_value in token_dict.items(): sub_scope = self.select_token_scope(token) if sub_scope is False: logger.error( 'Failed to get "%s" token associated scope mapping') return False self.handle.execute_cmd_list('top', 'scope bios', 'scope ' + sub_scope) out = self.handle.execute_cmd('set ' + token + ' ' + str(new_value)) match = re.search( 'invalid|exceeding|incomplete|Valid value| \ Maximum|cannot be used', out, re.I) if match is not None: logger.error('Failed to execute command; got error as: ' + str(match)) return False commit_out = self.handle.execute_cmd('commit', wait_time=commit_wait) logger.info("commit output :" + commit_out) if re.search('ERROR', commit_out, re.IGNORECASE): logger.info('Unable to set parameter ' + str(commit_out)) self.handle.execute_cmd('discard') return False elif re.search('Do you want to reboot the system', commit_out) and reboot is 'yes': reboot_out = self.handle.execute_cmd('y', wait_time=60) if 'A system reboot has been initiated' in reboot_out: logger.info( 'Successfully set the token and host reboot initiated.' ) time.sleep(180) else: logger.error( 'Failed to initiate host reboot after setting bios token' ) return False elif reboot is not 'yes': reboot_out = self.handle.execute_cmd('N') if 'Changes will be applied on next reboot' in reboot_out: logger.info('Successfully set the token, \ changes will reflect in next host reboot') else: logger.error('Failed to set to new value ') return False else: return False return True except: dump_error_in_lib() return False return True def console_redirect_defaults(self): ''' Procedure to set defaults of console redirect ConsoleRedir COM_0 TerminalType VT100+ BaudRate 115200 FlowCtrl None PuttyFunctionKeyPad ESCN RedirectionAfterPOST Always_Enable This procedure checks all console redirection tokens have default value and if not make it default Return: True: Success False : Failure Author: Suren kumar Moorthy ''' try: logger.info("Verify console redirection paramters are in defaults") platform_type = self.config.mgmtdetail.platform_series logger.info('Platform Series Type is: ' + platform_type) if platform_type == 'M4': token_dict = { "ConsoleRedir": self.token_map(), "TerminalType": "VT100+", "BaudRate": "115200", "FlowCtrl": "None", "PuttyFunctionKeyPad": "ESCN", "RedirectionAfterPOST": "Always_Enable" } out_dict = self.get_bios_token_value_list([ 'ConsoleRedir', 'TerminalType', 'BaudRate', 'FlowCtrl', 'PuttyFunctionKeyPad', 'RedirectionAfterPOST' ]) else: token_dict = { "ConsoleRedir": self.token_map(), "TerminalType": "VT100-PLUS", "BaudRate": "115.2k", "FlowCtrl": "None" } out_dict = self.get_bios_token_value_list( ['ConsoleRedir', 'TerminalType', 'BaudRate', 'FlowCtrl']) set_toke_dict = defaultdict(dict) change_flag = 0 for token, value in out_dict.items(): if token_dict[token] != out_dict[token]: set_toke_dict[token] = token_dict[token] change_flag = 1 if change_flag == 1: if self.set_bios_token_value_list(set_toke_dict) is True: logger.info("Setting default console redirect successful") return True else: logger.error( "Failed to set default values in console redirection") return False else: logger.info("Console redirect has default values.") return True except: dump_error_in_lib() return False def set_common_token_value(self, token, new_value, scope, sub_scope=None, reboot='yes', commit_wait=120): ''' Procedure to get bios values by passing its token name Parameter: param: Default - None or Pass the appropriate name of the token to get the value (Pass sub scope name to get token values inside sub scopes like advance,server-management,main,bios-profile,boot-device) Return: Token value: Success False : Failure Author: Suren kumar Moorthy ''' logger.info('Getting bios token value') try: if sub_scope is None: self.handle.execute_cmd_list('top', 'scope ' + scope) else: self.handle.execute_cmd_list('top', 'scope ' + scope, 'scope ' + sub_scope) time.sleep(3) out = self.handle.execute_cmd('set ' + token + ' ' + new_value, wait_time=8) match = re.search( 'invalid|exceeding|incomplete|Valid value\ |Maximum|cannot be used', out, re.I) time.sleep(2) if match is not None: logger.error('Failed to execute command; got error as: ' + str(match)) return False commit_out = self.handle.execute_cmd('commit', wait_time=commit_wait) logger.info('commit out is ' + token + ' to ' + new_value + ' : ' + str(commit_out)) if re.search('ERROR', commit_out, re.IGNORECASE): logger.info('Unable to set parameter ' + token + ' to ' + new_value + ' : ' + str(commit_out)) self.handle.execute_cmd('discard') return False if 'Do you want to reboot the system' in commit_out: logger.info('inside Do u want to reboot check') if reboot is 'yes': reboot_out = self.handle.execute_cmd('y', wait_time=120) if 'A system reboot has been initiated' in reboot_out: logger.info('Successfully set the token ' + token + ' and host reboot initiated.') time.sleep(180) else: logger.error( 'Failed to initiate host reboot after setting bios token' ) return False else: reboot_out = self.handle.execute_cmd('N', wait_time=6) if 'Changes will be applied on next reboot' in reboot_out: logger.info('Successfully set the token, \ changes will reflect in next host reboot') else: logger.error('Failed to set' + token + ' to new value ' + new_value) return False elif self.get_common_token_value(token, scope, sub_scope) == new_value: return True else: logger.warn('Unexpected output') return False return True except: curframe = inspect.currentframe() calframe = inspect.getouterframes(curframe, 2) logger.error("Error occured at the library function call name :" + str(calframe[1][3])) logger.error("Error occured is " + sys.exc_info().__str__()) return False return True def get_common_token_value(self, token, scope, sub_scope=None): ''' Procedure to get bios values by passing its token name Parameter: param: Default - None or Pass the appropriate name of the token to get the value (Pass sub scope name to get token values inside sub scopes like advance,server-management,main,bios-profile,boot-device) Return: Token value: Success False : Failure Author: Suren kumar Moorthy ''' logger.info('Getting bios token value') try: if sub_scope is None: out = self.handle.execute_cmd_list('top', 'scope ' + scope, 'show detail', wait_time=8) else: out = self.handle.execute_cmd_list('top', 'scope ' + scope, 'scope ' + sub_scope, 'show detail', wait_time=8) logger.info(out) regex = token + r'\s*\:\s+([^\r\n]+)' return re.search(regex, out).group(1) except: dump_error_in_lib() return False global default_token_dict default_token_dict = { 'input_output': { 'ATS': 'Enabled', 'AllLomPortControl': 'Enabled', 'CoherencySupport': 'Disabled', 'IPV6PXE': 'Disabled', 'IntelVTD': 'Enabled', 'LomOpromControlPort0': 'Enabled', 'LomOpromControlPort1': 'Enabled', 'PcieSlot1LinkSpeed': 'Auto', 'PcieSlot1OptionROM': 'Enabled', 'PcieSlot2LinkSpeed': 'Auto', 'PcieSlot2OptionROM': 'Enabled', 'PcieSlot3LinkSpeed': 'Auto', 'PcieSlot3OptionROM': 'Enabled', 'PcieSlot4LinkSpeed': 'Auto', 'PcieSlot4OptionROM': 'Enabled', 'PcieSlot5LinkSpeed': 'Auto', 'PcieSlot5OptionROM': 'Enabled', 'PcieSlot6LinkSpeed': 'Auto', 'PcieSlot6OptionROM': 'Enabled', 'PcieSlotFrontNvme1LinkSpeed': 'Auto', 'PcieSlotFrontNvme2LinkSpeed': 'Auto', 'PcieSlotMLOMLinkSpeed': 'Auto', 'PcieSlotMLOMOptionROM': 'Enabled', 'PcieSlotMRAIDLinkSpeed': 'Auto', 'PcieSlotMRAIDOptionROM': 'Enabled', 'PcieSlotN1OptionROM': 'Enabled', 'PcieSlotN2OptionROM': 'Enabled', 'PcieSlotRearNvme1LinkSpeed': 'Auto', 'PcieSlotRearNvme1OptionRom': 'Enabled', 'PcieSlotRearNvme2LinkSpeed': 'Auto', 'PcieSlotRearNvme2OptionRom': 'Enabled', 'SataModeSelect': 'AHCI', 'UsbLegacySupport': 'Enabled', 'UsbPortFront': 'Enabled', 'UsbPortInt': 'Enabled', 'UsbPortKVM': 'Enabled', 'UsbPortRear': 'Enabled', 'UsbPortSdCard': 'Enabled', 'VgaPriority': 'Onboard', 'pSATA': 'LSI_SW_RAID' }, 'server_management': { 'BaudRate': '115.2k', 'ConsoleRedir': 'Disabled', 'FRB-2': 'Enabled', 'FlowCtrl': 'None', 'OSBootWatchdogTimer': 'Disabled', 'OSBootWatchdogTimerPolicy': 'Power_Off', 'OSBootWatchdogTimerTimeout': '10_minutes', 'TerminalType': 'VT100', 'cdnEnable': 'Enabled' }, 'memory': { 'MemoryMappedIOAbove4GB': 'Enabled', 'NUMAOptimize': 'Enabled', 'SelectMemoryRAS': 'Maximum_Performance' }, 'power_or_performance': { 'AdjacentCacheLinePrefetch': 'Enabled', #'CPUPerformance' : 'Custom', 'DcuIpPrefetch': 'Enabled', 'DcuStreamerPrefetch': 'Enabled', 'HardwarePrefetch': 'Enabled' }, 'processor': { 'BootPerformanceMode': 'Max_Performance', 'CoreMultiProcessing': 'All', 'CpuEngPerfBias': 'Balanced_Performance', 'CpuHWPM': 'HWPM_Native_Mode', 'EnhancedIntelSpeedStep': 'Enabled', 'ExecuteDisable': 'Enabled', 'IMCInterleave': 'Auto', 'IntelHyperThread': 'Enabled', 'IntelTurboBoostTech': 'Enabled', 'IntelVT': 'Enabled', 'KTIPrefetch': 'Enabled', 'LLCPrefetch': 'Disabled', 'LocalX2Apic': 'Disabled', 'PackageCstateLimit': 'C0_C1_State', 'ProcessorC1E': 'Disabled', 'ProcessorC6Report': 'Disabled', 'ProcessorCMCI': 'Enabled', 'PsdCoordType': 'HW_ALL', 'PwrPerfTuning': 'OS', 'SNC': 'Disabled', 'WorkLdConfig': 'IO_Sensitive', 'XPTPrefetch': 'Disabled', 'AutoCCState': 'Disabled', 'EnergyEfficientTurbo': 'Disabled', 'PatrolScrub': 'Enabled', 'EPPProfile': 'Balanced_Performance' }, 'security': { 'PowerOnPassword': '******', 'TPMControl': 'Enabled', 'TXTSupport': 'Disabled' } } def validate_default_tokens(self, bios_scope_dict, bios_scope): ''' Procedure to validate default bios tokens after the CMOS clear operation Procedure to validate default bios tokens after the BIOS load default operation ''' logger.info('Validating BIOS tokens for scope: {}'.format(bios_scope)) logger.info('Current default values obtained from the testbed are:' + str(bios_scope_dict)) logger.info( 'Actual expected default tokens for the testbed are: {}'.format( default_token_dict[bios_scope])) if common_utils.compare_dictionaries(default_token_dict[bios_scope], bios_scope_dict) is True: return True else: return False def validate_mfg_custom_default_tokens(self, bios_scope_dict, user_token_dict, bios_scope): ''' Procedure to validate mfg default bios tokens after the restore-mfg-defaults Below are the some of the sample mfg tokens considred for the test: CPUPerformance : HPC OSBootWatchdogTimerPolicy : Reset FRB-2 : Disabled CoherencySupport : Enabled TPMControl : Disabled ATS : Disabled AdjacentCacheLinePrefetch : Disabled ''' # CoherencySupport, default value:Disabled, User default value:Enabled # ATS, default value: Enabled, User default value:Disabled # FRB-2 default value:Enabled, User default value: Disabled # AdjacentCacheLinePrefetch: default value:Enabled, User default value: 'Disabled' # AdjacentCacheLinePrefetch: default value:Enabled, User default value: 'Disabled' # IntelVT: default value:Enabled, User default value: Disabled # PwrPerfTuning: default value:OS, User default value: BIOS # TPMControl default value:Enabled; User default value:Disabled for token, token_val in default_token_dict[bios_scope].items(): logger.info('Default token value %s %s' % (token, token_val)) print(token, token_val) if token in user_token_dict.keys(): val = user_token_dict[token] default_token_dict[bios_scope][token] = '_'.join( val.split(' ')) logger.info( 'Changed token values as per user mfg default token as %s %s' % (token, val)) logger.info('After updating token dict as per user mfg default dict:') logger.info(default_token_dict[bios_scope]) logger.info('Validating BIOS tokens for scope: {}'.format(bios_scope)) logger.info('Current default values obtained from the testbed are:' + str(bios_scope_dict)) logger.info( 'Actual expected default tokens for the testbed are: {}'.format( default_token_dict[bios_scope])) if common_utils.compare_dictionaries(default_token_dict[bios_scope], bios_scope_dict) is True: return True else: return False def create_bios_profile_and_copy2tftpshare(self, user_token_dict=None): ''' Procedure to create BIOS token JSON format profile to install this profile on cimc to update the set of tokens Parameter: user_token_dict: bios token dictionary; if not passed will take default created one Return: True : Success False : Failure Author: jchanda ''' # Some sample Bios token values other than default values for testing # clear-cmos and bios-setup-default operation token_dict_value = { 'IntelHyperThread': 'Disabled', 'HardwarePrefetch': 'Disabled', 'AdjacentCacheLinePrefetch': 'Disabled', 'DcuStreamerPrefetch': 'Disabled', 'DcuIpPrefetch': 'Disabled', 'LLCPrefetch': 'Enabled', 'IntelTurboBoostTech': 'Disabled', 'CpuHWPM': 'Disabled', 'PackageCstateLimit': 'Auto', 'PwrPerfTuning': 'BIOS', 'NUMAOptimize': 'Disabled', 'IMCInterleave': '1-way Interleave', 'XPTPrefetch': 'Enabled', 'KTIPrefetch': 'Disabled', 'SNC': 'Auto' } # create default dictionary token_dict = defaultdict(dict) token_dict['name'] = 'bios_profile' token_dict['description'] = 'bios token settings test' if user_token_dict is not None: token_dict['tokens'] = user_token_dict else: token_dict['tokens'] = token_dict_value # dump into json object bios_token_json_profile = json.dumps(token_dict) logger.info('Created the bios token json format: ' + bios_token_json_profile) # copy dump json string data into a file with open('bios_profile.json', 'w') as fh: fh.write(bios_token_json_profile) # copy json file to remote tftp share server logger.info('Copying json file to remote tftp share server') self.tftp_handle.connect() logger.info('Successfully connected to remote tftp server: ' + self.tftp_ip) logger.info('Creating bios_profile dir in remote server') remote_path = self.tftp_root_dir + '/' + 'bios_profile_dir' self.tftp_handle.execute_cmd('mkdir -p ' + remote_path) self.profile_name = 'bios_profile' self.json_relative_path = 'bios_profile_dir' + '/' + 'bios_profile.json' logger.info( 'Copying the bios token json format file to remote tftp share server' ) res = self.tftp_handle.copy_local_to_remote( 'bios_profile.json', remote_path + '/' + 'bios_profile.json') if res is not True: logger.error('Failed to copy bios json format file') return False else: logger.info('Successfully copied file bios json format fiel') return True def delete_bios_profile(self, profile_name=None): ''' Procedure to delete the profile by passing the name of the profile Parameter: profile_name: to be deleted Return: True : Success False : Failure Author: jchanda ''' self.handle.execute_cmd_list('top', 'scope bios', 'scope bios-profile') profile_name = self.profile_name out = self.handle.execute_cmd('delete ' + profile_name) if 'Error' in out: logger.warning( 'BIOS profile: %s does not exists. command output: %s' % (profile_name, out)) return False elif 'Do you want to delete the active profile' in out: self.handle.execute_cmd('y') logger.info('Successfully deleted the bios profile') return True def install_and_activate_bios_profile(self, protocol=None, reboot=None): ''' Procedure to install and activate the BIOS profile on CIMC Parameter: protocol: by default tftp will be taken reboot: yes; to reboot host Return: True : Success False : Failure Author: jchanda ''' self.handle.execute_cmd_list('top', 'scope bios', 'scope bios-profile') # delete if any existing bios profile is already installed on CIMC self.delete_bios_profile() # install the bios profile on CIMC if protocol is None: cmd = 'install ' + 'tftp' + ' ' + self.tftp_ip + ' ' + self.json_relative_path self.handle.execute_cmd(cmd) out = self.handle.execute_cmd('show detail') if 'validation success' not in out: logger.error('Failed to install the bios profile on cimc') return False # activate the bios profile profile_name = self.profile_name cmd = 'activate ' + profile_name out = self.handle.execute_cmd(cmd) if 'Do you want to continue with BIOS Profile activation' in out: out2 = self.handle.execute_cmd('y') if 'Do you want to take a backup of BIOS tokens' in out2: out3 = self.handle.execute_cmd('y') if 'Do you want to reboot the system' in out3: if reboot is not None: out4 = self.handle.execute_cmd('y') if 'A system reboot has been initiated' in out4: logger.info( 'Successfully activated bios profile %s' % (profile_name)) return True else: logger.error('Failed to activate the bios profile') return False else: out4 = self.handle.execute_cmd('N') if 'Changes will be applied on next reboot' in out4: logger.info( 'Successfully activated bios profile %s' % (profile_name)) return True else: logger.error('Failed to activate the bios profile') return False def load_bios_mfg_custom_tokens(self, user_defined_tokens_dic): ''' Procedure will create token.txt file and edit file with custom mfg-def tokens, and load the file by executing SetMfgDefaults -f command. Parameter: user_defined_tokens_dic: User defined token dictionary to be applied on system Return: True : Success False : Failure Author: jchanda ''' logger.info('User defined tokens opted for mfg are: ' + str(user_defined_tokens_dic)) cimc_debug_handle = self.cimc_obj.telnet_handle cimc_debug_handle.connect_to_mgmnt() # change the prompt to Linux shell prompt = 'linuxMode' cimc_debug_handle.set_bmc_serial_mode(prompt) # delete if any existing token file present; and create new one cimc_debug_handle.execute_cmd_serial('rm /tmp/token.txt &2>/dev/null') for keys, val in user_defined_tokens_dic.items(): cmd = 'echo ' + keys + ' ' + ':' + ' ' + val + '>> /tmp/token.txt' cimc_debug_handle.execute_cmd_serial(cmd) # Load bios mfg tokens from debug shell cmd = 'SetMfgDefaults -f /tmp/token.txt' out = cimc_debug_handle.execute_cmd_serial(cmd) if 'Error' in out: logger.error('Failed: to load mfg bios token') return False elif 'Please restart host' in out: logger.info('Passed: successfully issued the command') # Power cycle the host logger.info( 'Need to restart host for manufacturing settings to take effect') if self.cimc_obj.power_cycle_host() is False: logger.error('Failed to power cycle the host') return False # Wait for host to come up res = self.cimc_obj.verify_host_up(hostname=self.host_ip, wait_for_ping_fail=False) if res is False: logger.warning('Failed to ping the host') logger.info('Passed: successfully loaded mfg bios tokens on CIMC') return True
class ExpImpUtils(): def __init__(self, cimc_utils_obj, config, common_config): self.cimc_utils_obj = cimc_utils_obj self.handle = cimc_utils_obj.handle self.config = config self.common_config = common_config self.tftp_ip = self.common_config.tftp_share.tftp_server_ip self.tftp_user = self.common_config.tftp_share.tftp_user self.tftp_password = self.common_config.tftp_share.tftp_password self.tftp_handle = LinuxUtils(self.tftp_ip, self.tftp_user, self.tftp_password) self.tftp_root_dir = self.common_config.tftp_share.tftp_root_path self.export_path = None def export_vic_config(self, slot_no, protocol='tftp', server=None, path=None, user=None, password=None): ''' Procedure to export VIC configuration Parameter: slot_no: slot number on adapter card is present protocol: Protocol to use { tftp | ftp | sftp | scp | http } server: Remote server IP address path: Image file path on the remote server user: remote server user name password: remote server user password Return: True : Success False : Failure ''' try: if server == None: remote_dir = '/vic_export/' remote_path = self.tftp_root_dir + remote_dir self.tftp_handle.connect() logger.info('Successfully connected to remote tftp server') self.tftp_handle.execute_cmd_list('mkdir -p ' + remote_path) self.tftp_handle.execute_cmd_list('chmod 777 ' + remote_path) self.tftp_handle.disconnect() self.handle.execute_cmd_list('top', 'scope chassis', 'scope adapter ' + slot_no) vic_xml_file = "vic_config" + "_" + "slot_no_" + slot_no if protocol is 'tftp' or protocol is 'http': out = self.handle.execute_cmd('export-vnic' + ' ' + protocol + ' ' + self.tftp_ip + ' ' + remote_dir + vic_xml_file, wait_time=6) if 'Export succeeded' in out: logger.info( 'VIC export operation completed successfully: ' + remote_path + vic_xml_file) self.export_path = remote_path + vic_xml_file else: logger.exception('Failed to export VIC config data') return False elif protocol is 'sftp' or protocol is 'scp': out = self.handle.execute_cmd('export-vnic' + ' ' + protocol + ' ' + self.tftp_ip + ' ' + remote_path + vic_xml_file, wait_time=6) if 'Do you wish to continue' in out: self.handle.execute_cmd('y') time.sleep(1) self.handle.execute_cmd(user) time.sleep(1) out = self.handle.execute_cmd(password, wait_time=6) if 'Export succeeded' in out: logger.info( 'VIC export operation completed successfully') self.export_path = remote_path + vic_xml_file else: logger.exception('Failed to export VIC config data') return False elif protocol is 'ftp': self.handle.execute_cmd('export-vnic' + ' ' + protocol + ' ' + self.tftp_ip + ' ' + remote_dir + vic_xml_file, wait_time=6) self.handle.execute_cmd(user) time.sleep(1) out = self.handle.execute_cmd(password, wait_time=6) if 'Export succeeded' in out: logger.info('VIC export operation completed successfully') self.export_path = remote_path + vic_xml_file else: logger.exception('Failed to export VIC config data') return False else: logger.error('Invalid protocol selected') return False return True except: dump_error_in_lib() return False def validate_vic_config(self, slot_no): logger.info("Verifying the VIC configuration exported for slot no " + slot_no) self.tftp_handle.connect() out = self.tftp_handle.execute_cmd('cat ' + self.export_path + ' | ' + 'grep -F "<CDN>"') self.tftp_handle.disconnect() cdn_name_from_export = re.findall(r'<CDN>(\w+)<\/CDN>', out) logger.info('exported CDN_names are') logger.info(cdn_name_from_export) logger.info('Fetching CDN name from CIMC CLI') vic_obj = VicLib(self.cimc_utils_obj, self.config) out = vic_obj.cimc_cdn_mac_dict(slot_no) cnd_name_from_cimc = [] for cdn_name in out.values(): cnd_name_from_cimc.append(cdn_name) logger.info('CDN Name from CIMC list:' + str(cnd_name_from_cimc)) ''' if len(cnd_name_from_cimc) != len(cdn_name_from_export): logger.error('Both lists have different size lengths') return False ''' for val in cdn_name_from_export: if val not in cnd_name_from_cimc: logger.info("From CIMC CDN name are not same as TSR CDN name") return False return True def remove_vic_config(self): ''' Procedure to remove the VIC exported file Returns: True: on success False: on failure ''' try: logger.info('Deleting vic export config file: ' + self.export_path) self.tftp_handle.connect() self.tftp_handle.execute_cmd('rm -f ' + self.export_path) self.tftp_handle.disconnect() except: dump_error_in_lib()