class OpTestHost(): ## # @brief Initialize this object # # @param i_hostip @type string: IP Address of the host # @param i_hostuser @type string: Userid to log into the host # @param i_hostpasswd @type string: Password of the userid to log into the host # @param i_bmcip @type string: IP Address of the bmc # def __init__(self, i_hostip, i_hostuser, i_hostpasswd, i_bmcip, i_results_dir, scratch_disk="", proxy="", logfile=sys.stdout, check_ssh_keys=False, known_hosts_file=None): self.ip = i_hostip self.user = i_hostuser self.passwd = i_hostpasswd self.util = OpTestUtil() self.bmcip = i_bmcip parent_dir = os.path.dirname(os.path.abspath(__file__)) self.results_dir = i_results_dir self.logfile = logfile self.ssh = OpTestSSH(i_hostip, i_hostuser, i_hostpasswd, logfile=self.logfile, check_ssh_keys=check_ssh_keys, known_hosts_file=known_hosts_file, use_default_bash=True) self.scratch_disk = scratch_disk self.proxy = proxy self.scratch_disk_size = None def hostname(self): return self.ip def username(self): return self.user def password(self): return self.passwd def get_scratch_disk(self): return self.scratch_disk def get_scratch_disk_size(self, console=None): if self.scratch_disk_size is not None: return self.scratch_disk_size if console is None: raise Exception("You need to call get_scratch_disk_size() with a console first") console.run_command("stty cols 300") dev_sdX = console.run_command("readlink -f %s" % self.get_scratch_disk()) dev_sdX = dev_sdX[0].replace("/dev/","") scratch_disk_size = console.run_command("cat /sys/block/%s/size" % dev_sdX) # Use the (undocumented) /size sysfs property of nr 512byte sectors self.scratch_disk_size = int(scratch_disk_size[0])*512 def get_proxy(self): return self.proxy def get_ssh_connection(self): return self.ssh ## # @brief Get and Record Ubunto OS level # # @return l_oslevel @type string: OS level of the host provided # or raise OpTestError # def host_get_OS_Level(self): l_oslevel = self.ssh.run_command("cat /etc/os-release", timeout=60) return '\n'.join(l_oslevel) ## # @brief Executes a command on the os of the bmc to protect network setting # # @return OpTestError if failed # def host_protect_network_setting(self): try: l_rc = self.ssh.run_command(BMC_CONST.OS_PRESERVE_NETWORK, timeout=60) except: l_errmsg = "Can't preserve network setting" print l_errmsg raise OpTestError(l_errmsg) ## # @brief Performs a cold reset onto the host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_cold_reset(self): print ("Applying Cold reset on host.") l_rc = self.ssh.run_command(BMC_CONST.HOST_COLD_RESET, timeout=60) # TODO: enable once defect SW331585 is fixed '''if BMC_CONST.BMC_PASS_COLD_RESET in l_rc: print l_rc time.sleep(BMC_CONST.BMC_COLD_RESET_DELAY) return BMC_CONST.FW_SUCCESS else: l_msg = "Cold reset Failed" print l_msg raise OpTestError(l_msg)''' self.util.PingFunc(self.bmcip, BMC_CONST.PING_RETRY_FOR_STABILITY) ## # @brief Flashes image using ipmitool # # @param i_image @type string: hpm file including location # @param i_imagecomponent @type string: component to be # update from the hpm file BMC_CONST.BMC_FW_IMAGE_UPDATE # or BMC_CONST.BMC_PNOR_IMAGE # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_code_update(self, i_image, imagecomponent): # Copy the hpm file to the tmp folder in the host try: self.util.copyFilesToDest(i_image, self.user, self.ip, "/tmp/", self.passwd) except: l_msg = "Copying hpm file to host failed" print l_msg raise OpTestError(l_msg) #self.host_protect_network_setting() #writing to host is not stable l_cmd = "\necho y | ipmitool -I usb " + BMC_CONST.BMC_HPM_UPDATE + "/tmp/" \ + i_image.rsplit("/", 1)[-1] + " " + imagecomponent print l_cmd try: l_rc = self.ssh.run_command(l_cmd, timeout=1500) print l_rc self.ssh.run_command("rm -rf /tmp/" + i_image.rsplit("/", 1)[1],timeout=120) except subprocess.CalledProcessError: l_msg = "Code Update Failed" print l_msg raise OpTestError(l_msg) if(l_rc.__contains__("Firmware upgrade procedure successful")): return BMC_CONST.FW_SUCCESS else: l_msg = "Code Update Failed" print l_msg raise OpTestError(l_msg) def host_run_command(self, i_cmd, timeout=1500): return self.ssh.run_command(i_cmd, timeout) ## # @brief It will gather OPAL Message logs and store the copy in a logfile # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_gather_opal_msg_log(self): try: l_data = '\n'.join(self.host_run_command(BMC_CONST.OPAL_MSG_LOG)) except OpTestError: l_msg = "Failed to gather OPAL message logs" raise OpTestError(l_msg) if not self.results_dir: print l_data return l_res = (time.asctime(time.localtime())).replace(" ", "_") l_logFile = "Opal_msglog_%s.log" % l_res fn = os.path.join(self.results_dir, l_logFile) print fn with open(fn, 'w') as f: f.write(l_data) ## # @brief Check if one or more binaries are present on host # # @param i_cmd @type string: binaries to check for # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_check_command(self, *i_cmd): l_cmd = 'which ' + ' '.join(i_cmd) print l_cmd try: l_res = self.host_run_command(l_cmd) except CommandFailed as c: l_msg = "host_check_command: (%s) not present on host. output of '%s': %s" % (','.join(i_cmd), l_cmd, '\n'.join(c.output)) print l_msg raise OpTestError(l_msg) return True ## # @brief It will get the linux kernel version on host # # @return l_kernel @type string: kernel version of the host provided # or raise OpTestError # def host_get_kernel_version(self): l_kernel = self.ssh.run_command("uname -a | awk {'print $3'}", timeout=60) l_kernel = ''.join(l_kernel) print l_kernel return l_kernel ## # @brief This function will checks first for config file for a given kernel version on host, # if available then check for config option value and return that value # whether it is y or m...etc. # sample config option values: # CONFIG_CRYPTO_ZLIB=m # CONFIG_CRYPTO_LZO=y # # CONFIG_CRYPTO_842 is not set # # # @param i_kernel @type string: kernel version # @param i_config @type string: Which config option want to check in config file # Ex:CONFIG_SENSORS_IBMPOWERNV # # @return l_val @type string: It will return config option value y or m, # or raise OpTestError if config file is not available on host # or raise OpTestError if config option is not set in file. # def host_check_config(self, i_kernel, i_config): l_file = "/boot/config-%s" % i_kernel try: l_res = self.ssh.run_command("test -e %s" % l_file, timeout=60) except CommandFailed as c: raise NoKernelConfig(i_kernel, l_file) print "Config file is available" l_cmd = "cat %s" % (l_file) l_res = self.ssh.run_command(l_cmd, timeout=60) config_opts = {} for o in l_res: m = re.match('# (.*) is not set', o) if m: config_opts[m.group(0)]='n' else: if '=' in o: opt, val = o.split("=") config_opts[opt] = val if config_opts.get(i_config) not in ["y","m"]: raise KernelConfigNotSet(i_config) return config_opts[i_config] ## # @brief It will return installed package name for given linux command(i_cmd) on host # # @param i_cmd @type string: linux command # @param i_oslevel @type string: OS level # # @return l_pkg @type string: installed package on host # def host_check_pkg_for_utility(self, i_oslevel, i_cmd): if 'Ubuntu' in i_oslevel: return ''.join(self.ssh.run_command("dpkg -S `which %s`" % i_cmd, timeout=60)) else: l_cmd = "rpm -qf `which %s`" % i_cmd return ''.join(self.ssh.run_command(l_cmd, timeout=60)) ## # @brief This function loads ibmpowernv driver only on powernv platform # and also this function works only in root user mode # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_ibmpowernv(self, i_oslevel): if "PowerKVM" not in i_oslevel: o = self.ssh.run_command("modprobe ibmpowernv",timeout=60) cmd = "lsmod | grep -i ibmpowernv" response = self.ssh.run_command(cmd, timeout=60) if "ibmpowernv" not in ''.join(response): l_msg = "ibmpowernv module is not loaded, exiting" raise OpTestError(l_msg) else: print "ibmpowernv module is loaded" print cmd print response return BMC_CONST.FW_SUCCESS ## # @brief This function restarts the lm_sensors service on host using systemctl utility # systemctl utility is not present in ubuntu, This function will work in remaining all # other OS'es i.e redhat, sles and PowerKVM # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_start_lm_sensor_svc(self, i_oslevel): if 'Ubuntu' in i_oslevel: pass else: try: # Start the lm_sensors service cmd = "/bin/systemctl stop lm_sensors.service" self.host_run_command(cmd) cmd = "/bin/systemctl start lm_sensors.service" self.host_run_command(cmd) cmd = "/bin/systemctl status lm_sensors.service" res = self.host_run_command(cmd) return BMC_CONST.FW_SUCCESS except: l_msg = "loading lm_sensors service failed" print l_msg raise OpTestError(l_msg) ## # @brief It will clone latest linux git repository in i_dir directory # # @param i_dir @type string: directory where linux source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_linux_source(self, i_dir): l_msg = 'git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git' l_cmd = "git clone --depth=1 %s %s" % (l_msg, i_dir) self.ssh.run_command("rm -rf %s" % i_dir, timeout=300) self.ssh.run_command("mkdir %s" % i_dir, timeout=60) try: print l_cmd res = self.ssh.run_command(l_cmd, timeout=1500) print res return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning linux git repository is failed" print l_msg raise OpTestError(l_msg) ## # @brief reads getscom data # example: # Chip ID | Rev | Chip type # ---------|-------|-------- # 80000005 | DD2.0 | Centaur memory buffer # 80000004 | DD2.0 | Centaur memory buffer # 00000000 | DD2.0 | P8 (Venice) processor # # @param i_xscom_dir @type string: directory where getscom is installed # # @return @type string: getscom data # else raise OpTestError def host_read_getscom_data(self, i_xscom_dir): try: l_rc = self.ssh.run_command(BMC_CONST.SUDO_COMMAND + i_xscom_dir + BMC_CONST.OS_GETSCOM_LIST, timeout=60) except OpTestError as e: l_errmsg = "Can't get getscom data" print l_errmsg raise OpTestError(l_errmsg) if("command not found" in l_rc): l_errmsg = "Failed to locate getscom. Make sure it is installed in dir: " + i_xscom_dir print l_errmsg raise OpTestError(l_errmsg) return l_rc ## # @brief injects error using getscom # # @param i_xscom_dir @type string: directory where putscom is installed # param i_error @type string: error to be injected including the location # # @return output generated after executing putscom command or else raise OpTestError # def host_putscom(self, i_xscom_dir, i_error): print('Injecting Error.') l_rc = self.ssh.run_command_ignore_fail(BMC_CONST.SUDO_COMMAND + i_xscom_dir + BMC_CONST.OS_PUTSCOM_ERROR + i_error) ## # @brief Clears the gard records # # @param i_gard_dir @type string: directory where putscom is installed # # @return BMC_CONST.FW_SUCCESS or else raise OpTestError # def host_clear_gard_records(self, i_gard_dir): l_rc = self.ssh.run_command(BMC_CONST.SUDO_COMMAND + i_gard_dir + BMC_CONST.CLEAR_GARD_CMD, timeout=60) if(BMC_CONST.GARD_CLEAR_SUCCESSFUL not in l_rc): l_msg = l_rc + '. Failed to clear gard' print l_msg raise OpTestError(l_msg) # Check to make sure no gard records were left l_result = self.host_list_gard_records(i_gard_dir) if(BMC_CONST.NO_GARD_RECORDS not in l_result): l_msg = l_rc + '. Gard records still found after clearing them' print l_msg raise OpTestError(l_msg) return BMC_CONST.FW_SUCCESS ## # @brief Lists all gard records # # @param i_gard_dir @type string: directory where putscom is installed # # @return gard records or else raise OpTestError # def host_list_gard_records(self, i_gard_dir): try: return self.ssh.run_command(BMC_CONST.SUDO_COMMAND + i_gard_dir + BMC_CONST.LIST_GARD_CMD, timeout=60) except: l_errmsg = "Can't clear gard records" print l_errmsg raise OpTestError(l_errmsg) ## # @brief enable/disable cpu states # # @param i_cpu_state @type string: BMC_CONST.CPU_ENABLE_STATE/ # BMC_CONST.CPU_DISABLE_STATE # # @return BMC_CONST.FW_SUCCESS or OpTestError # def host_disable_enable_cpu_states(self, i_cpu_state): try: self.ssh.run_command(BMC_CONST.SUDO_COMMAND + "sh -c 'for i in " + \ BMC_CONST.CPU_IDLEMODE_STATE1 + "; do echo " + \ i_cpu_state + " > $i; done'", timeout=60) self.ssh.run_command(BMC_CONST.SUDO_COMMAND + "sh -c 'for i in " + \ BMC_CONST.CPU_IDLEMODE_STATE2 + "; do echo " + \ i_cpu_state + " > $i; done'", timeout=60) return BMC_CONST.FW_SUCCESS except: l_errmsg = "Could not enable/disable cpu idle states" print l_errmsg raise OpTestError(l_errmsg) ## # @brief It will load the module using modprobe and verify whether it is loaded or not # # @param i_module @type string: module name, which we want to load on host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_module(self, i_module): try: l_res = self.host_run_command("modprobe %s" % i_module) except CommandFailed as c: l_msg = "Error in loading the module %s, modprobe failed: %s" % (i_module,str(c)) raise OpTestError(l_msg) l_res = self.host_run_command("lsmod | grep -i --color=never %s" % i_module) if re.search(i_module, ''.join(l_res)): print "%s module is loaded" % i_module return BMC_CONST.FW_SUCCESS else: raise KernelModuleNotLoaded(i_module) ## # @brief This function will read real time clock(RTC) time using hwclock utility # # @return l_res @type string: return hwclock value if command execution successfull # else raise OpTestError # def host_read_hwclock(self): print "Reading the hwclock" self.host_run_command("hwclock -r;echo $?") ## # @brief This function will read system time using date utility (This will be mantained by kernel) # # @return l_res @type string: return system time value if command execution successfull # else raise OpTestError # def host_read_systime(self): print "Reading system time using date utility" l_res = self.host_run_command("date") return l_res ## # @brief This function will set hwclock time using the --date option # format should be "2015-01-01 12:12:12" # # @param i_time @type string: this is the time for setting the hwclock # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_set_hwclock_time(self, i_time): print "Setting the hwclock time to %s" % i_time self.host_run_command("hwclock --set --date \'%s\'" % i_time) ## # @brief This function will load driver module on host based on the config option # if config value m: built as a module # y: driver built into kernel itself # else raises OpTestError # # @param i_kernel @type string: kernel version to get config file # i_config @type string: config option to check in config file # i_module @type string: driver module to load on host based on config value # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_module_based_on_config(self, i_kernel, i_config, i_module): l_val = self.host_check_config(i_kernel, i_config) if l_val == 'm': self.host_load_module(i_module) elif l_val == 'y': print "Driver built into kernel itself" elif l_val == 'n': raise KernelConfigNotSet(i_config) ## # @brief It will clone latest skiboot git repository in i_dir directory # # @param i_dir @type string: directory where skiboot source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_skiboot_source(self, i_dir): l_msg = 'https://github.com/open-power/skiboot.git/' l_cmd = "git clone %s %s" % (l_msg, i_dir) self.host_run_command("git config --global http.sslverify false") self.host_run_command("rm -rf %s" % i_dir) self.host_run_command("mkdir %s" % i_dir) try: print l_cmd l_res = self.host_run_command(l_cmd) print l_res return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning skiboot git repository is failed" print l_msg raise OpTestError(l_msg) ## # @brief This function enable only a single core # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_enable_single_core(self): self.host_run_command("ppc64_cpu --cores-on=1") ## # @brief This function is used to get list of PCI PHB domains. # # @return self.pci_domains list of PHB domains @type list or raise OpTestError # def host_get_list_of_pci_domains(self): self.pci_domains = [] self.host_run_command("lspci -mm") res = self.host_run_command('lspci -mm | cut -d":" -f1 | sort | uniq') for domain in res: if not domain: continue if len(domain) != 4: domain = ''.join(("00", domain)) domain = 'PCI' + domain if not self.pci_domains.__contains__(domain): self.pci_domains.append(domain) print self.pci_domains return self.pci_domains ## # @brief This function is used to get the PHB domain of root port where # the filesystem is mounted(We need to skip this in EEH tests as recovery # will fail on this domain is expected) # # @return boot_domain root PHB @type string or raise OpTestError # def host_get_root_phb(self): cmd = "df -h /boot | awk 'END {print $1}'" res = self.host_run_command(cmd) boot_disk = ''.join(res).split("/dev/")[1] boot_disk = boot_disk.replace("\r\n", "") cmd = "ls -l /dev/disk/by-path/ | grep %s | awk '{print $(NF-2)}'" % boot_disk res = self.host_run_command(cmd) matchObj = re.search(r"\d{4}(?!\d)", '\n'.join(res), re.S) if not matchObj: raise OpTestError("Not able to find out root phb domain") boot_domain = 'PCI' + matchObj.group(0) return boot_domain ## # @brief It will gather kernel dmesg logs and store the copy in a logfile # which will be stored in results dir. # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_gather_kernel_log(self): try: l_data = '\n'.join(self.host_run_command("dmesg")) except OpTestError: l_msg = "Failed to gather kernel dmesg log" raise OpTestError(l_msg) if not self.results_dir: print l_data return l_res = (time.asctime(time.localtime())).replace(" ", "_") l_logFile = "Kernel_dmesg_log_%s.log" % l_res fn = os.path.join(self.results_dir, l_logFile) print fn with open(fn, 'w') as f: f.write(l_data) return BMC_CONST.FW_SUCCESS ## # @brief This function starts opal_errd daemon # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_start_opal_errd_daemon(self): self.host_run_command("systemctl start opal_errd") ## # @brief This function stops opal_errd daemon # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_stop_opal_errd_daemon(self): self.host_run_command("systemctl stop opal_errd") ## # @brief This function gets the status of opal_errd daemon # # @return True/False: if opal_errd run/not run or throws exception # if not able to get status # def host_get_status_of_opal_errd_daemon(self): res = self.host_run_command("ps -ef | grep -v grep | grep opal_errd | wc -l") print res if res[0].strip() == "0": print "Opal_errd daemon is not running" return False elif res[0].strip() == "1": print "Opal_errd daemon is running" return True else: raise OpTestError("Not able to get status of opal errd daemon") ## # @brief This function lists all error logs in host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_list_all_errorlogs(self): self.host_run_command("opal-elog-parse -l") ## # @brief This function lists all service action logs in host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_list_all_service_action_logs(self): self.host_run_command("opal-elog-parse -s") ## # @brief This function gets the number of error logs # # @return res or raise OpTestError # def host_get_number_of_errorlogs(self): res = self.host_run_command("ls %s | wc -l" % BMC_CONST.OPAL_ELOG_DIR) print res return res ## # @brief This function clears/acknowledges all error logs in host # # @return True on success or raise OpTestError # def host_clear_error_logs(self): self.host_run_command("rm -f %s/*" % BMC_CONST.OPAL_ELOG_DIR) res = self.host_run_command("ls %s -1 --color=never" % BMC_CONST.OPAL_ELOG_SYSFS_DIR) print '\n'.join(res) for entry in res: entry = entry.strip() if entry == '': continue self.host_run_command("echo 1 > %s/%s/acknowledge" % (BMC_CONST.OPAL_ELOG_SYSFS_DIR, entry)) return True ## # @brief This function clears/acknowledges all dumps in host # # @return True on success or raise OpTestError # def host_clear_all_dumps(self): self.host_run_command("rm -f %s/*" % BMC_CONST.OPAL_DUMP_DIR) res = self.host_run_command("ls %s -1 --color=never" % BMC_CONST.OPAL_DUMP_SYSFS_DIR) for entry in res: entry = entry.strip() if (entry == "initiate_dump") or (entry == ''): continue else: self.host_run_command("echo 1 > %s/%s/acknowledge" % (BMC_CONST.OPAL_DUMP_SYSFS_DIR, entry)) return True # @brief This function disables kdump service # # @param os_level: string output of /etc/os-release # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_disable_kdump_service(self, os_level): if "Ubuntu" in os_level: self.host_run_command("systemctl stop kdump-tools.service") try: self.host_run_command("systemctl status kdump-tools.service") except CommandFailed as cf: if cf.exitcode == 3: pass else: print str(cf) raise OpTestError("kdump-tools service is failed to stop") else: self.host_run_command("systemctl stop kdump.service") try: self.host_run_command("systemctl status kdump.service") except CommandFailed as cf: if cf.exitcode == 3: pass else: print str(cf) raise OpTestError("kdump service is failed to stop") ## # @brief This function disables kdump service # # @param os_level: string output of /etc/os-release # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_enable_kdump_service(self, os_level): if "Ubuntu" in os_level: self.host_run_command("systemctl stop kdump-tools.service") self.host_run_command("systemctl start kdump-tools.service") self.host_run_command("systemctl status kdump-tools.service") else: self.host_run_command("systemctl stop kdump.service") self.host_run_command("systemctl start kdump.service") self.host_run_command("service status kdump.service") def host_check_sysfs_path_availability(self, path): res = self.host_run_command("ls %s" % path) if "No such file or directory" in res: return False return True def host_check_dt_node_exist(self, node_path): path = "/proc/device-tree/" + node_path res = self.host_run_command("ls %s" % path) if "No such file or directory" in res: return False return True def host_get_list_of_chips(self): res = self.host_run_command("PATH=/usr/local/sbin:$PATH getscom -l") chips = [] for line in res: matchObj = re.search("(\d{8}).*processor", line) if matchObj: chips.append(matchObj.group(1)) if not chips: raise Exception("Getscom failed to list processor chip ids") chips.sort() print chips # ['00000000', '00000001', '00000010'] return chips def host_get_cores(self): proc_gen = self.host_get_proc_gen() core_ids = {} cpu_files = self.host_run_command("find /sys/devices/system/cpu/ -name 'cpu[0-9]*'") for cpu_file in cpu_files: cpu_id = self.host_run_command("basename %s | tr -dc '0-9'" % cpu_file)[-1] try: pir = self.host_run_command("cat %s/pir" % cpu_file)[-1] except CommandFailed: continue if proc_gen in ["POWER8", "POWER8E"]: core_id = hex((int("0x%s" % pir, 16) >> 3 ) & 0xf) chip_id = hex((int("0x%s" % pir, 16) >> 7 ) & 0x3f) elif proc_gen in ["POWER9"]: core_id =hex((int("0x%s" % pir, 16) >> 2 ) & 0x3f) chip_id = hex((int("0x%s" % pir, 16) >> 8 ) & 0x7f) else: raise OpTestError("Unknown or new processor type") core_id = core_id.split('x')[1] chip_id = chip_id.split('x')[1] if chip_id in core_ids: core_ids[chip_id].append(core_id) else: core_ids[chip_id] = [core_id] for i in core_ids: core_ids[i] = list(set(core_ids[i])) core_ids = sorted(core_ids.iteritems()) print core_ids return core_ids # Supported on OpenPower and P9 FSP system def host_prd_supported(self, bmc_type): if not "FSP" in bmc_type: return True proc_gen = self.host_get_proc_gen() if proc_gen in ["POWER8", "POWER8E"]: return False return True def host_get_proc_gen(self): try: if self.proc_gen: pass except AttributeError: self.proc_gen = ''.join(self.host_run_command("grep '^cpu' /proc/cpuinfo |uniq|sed -e 's/^.*: //;s/[,]* .*//;'")) return self.proc_gen def host_get_smt(self): self.cpu = self.host_get_proc_gen() if self.cpu in ["POWER8", "POWER8E"]: return 8 elif self.cpu in ["POWER9"]: return 4 else: return 1 def host_get_core_count(self): res = self.host_run_command("lscpu --all -e| wc -l") return int(res[0])/(self.host_get_smt()) def host_gather_debug_logs(self): self.ssh.run_command_ignore_fail("grep ',[0-4]\]' /sys/firmware/opal/msglog") self.ssh.run_command_ignore_fail("dmesg -T --level=alert,crit,err,warn") def host_copy_fake_gard(self): path = os.path.abspath(os.path.join("common", os.pardir)) i_image = path + "/test_binaries/fake.gard" # Copy the fake.gard file to the tmp folder in the host try: self.util.copyFilesToDest(i_image, self.user, self.ip, "/tmp/", self.passwd) except: l_msg = "Copying fake.gard file to host failed" print l_msg raise OpTestError(l_msg) def host_pflash_get_partition(self, partition): d = self.host_run_command("pflash --info") for line in d: s = re.search(partition, line) if s: m = re.match(r'ID=\d+\s+\S+\s+((0[xX])?[0-9a-fA-F]+)..(0[xX])?[0-9a-fA-F]+\s+\(actual=((0[xX])?[0-9a-fA-F]+)\).*', line) offset = int(m.group(1), 16) length = int(m.group(4), 16) ret = {'offset': offset, 'length': length} return ret ## # @brief Check that host has a CAPI FPGA card # # @return True or False # def host_has_capi_fpga_card(self): l_cmd = "lspci -d \"1014:0477\"" l_res = self.host_run_command(l_cmd) l_res = " ".join(l_res) if (l_res.__contains__('IBM Device 0477')): l_msg = "Host has a CAPI FPGA card" print l_msg return True else: l_msg = "Host has no CAPI FPGA card; skipping test" print l_msg return False ## # @brief Clone latest cxl-tests git repository in i_dir directory # # @param i_dir @type string: directory where cxl-tests will be cloned # # @return True or False # def host_clone_cxl_tests(self, i_dir): l_msg = "https://github.com/ibm-capi/cxl-tests.git" l_cmd = "git clone %s %s" % (l_msg, i_dir) self.host_run_command("git config --global http.sslverify false") self.host_run_command("rm -rf %s" % i_dir) self.host_run_command("mkdir %s" % i_dir) try: l_res = self.host_run_command(l_cmd) return True except: l_msg = "Cloning cxl-tests git repository is failed" return False def host_build_cxl_tests(self, i_dir): l_cmd = "cd %s; make" % i_dir self.host_run_command(l_cmd) l_cmd = "test -x %s/libcxl/libcxl.so" % i_dir self.host_run_command(l_cmd) l_cmd = "test -x %s/libcxl_tests; echo $?" % i_dir self.host_run_command(l_cmd) l_cmd = "test -x %s/memcpy_afu_ctx; echo $?" % i_dir self.host_run_command(l_cmd) def host_check_binary(self, i_dir, i_file): l_cmd = "test -x %s/%s;" % (i_dir, i_file) try: self.host_run_command(l_cmd) l_msg = "Executable file %s/%s is available" % (i_dir, i_file) print l_msg return True except CommandFailed: l_msg = "Executable file %s/%s is not present" % (i_dir, i_file) print l_msg return False
class OpTestHost(): ## # @brief Initialize this object # # @param i_hostip @type string: IP Address of the host # @param i_hostuser @type string: Userid to log into the host # @param i_hostpasswd @type string: Password of the userid to log into the host # @param i_bmcip @type string: IP Address of the bmc # @param i_ffdcDir @type string:specifies the directory under which to save all FFDC data # def __init__(self, i_hostip, i_hostuser, i_hostpasswd, i_bmcip, i_ffdcDir=None): self.ip = i_hostip self.user = i_hostuser self.passwd = i_hostpasswd self.util = OpTestUtil() self.bmcip = i_bmcip self.cv_ffdcDir = i_ffdcDir ## # @brief This method executes the command(i_cmd) on the host using a ssh session # # @param i_cmd: @type string: Command to be executed on host through a ssh session # @return command output if command execution is successful else raises OpTestError # def _ssh_execute(self, i_cmd): l_host = self.ip l_user = self.user l_pwd = self.passwd l_output = '' ssh_ver = '-2' # Flush everything out prior to forking sys.stdout.flush() # Connect the child controlling terminal to a pseudo-terminal try: pid, fd = pty.fork() except OSError as e: # Explicit chain of errors l_msg = "Got OSError attempting to fork a pty session for ssh." raise OpTestError(l_msg) if pid == 0: # In child process. Issue attempt ssh connection to remote host arglist = ('/usr/bin/ssh -o StrictHostKeyChecking=no', l_host, ssh_ver, '-k', '-l', l_user, i_cmd) try: os.execv('/usr/bin/ssh', arglist) except Exception as e: # Explicit chain of errors l_msg = "Can not spawn os.execv for ssh." print l_msg raise OpTestError(l_msg) else: # In parent process # Polling child process for output poll = select.poll() poll.register(fd, select.POLLIN) start_time = time.time() # time.sleep(1) while True: try: evt = poll.poll() x = os.read(fd, 1024) #print "ssh x= " + x end_time = time.time() if (end_time - start_time > 1500): if (i_cmd.__contains__('updlic') or i_cmd.__contains__('update_flash')): continue else: l_msg = "Timeout occured/SSH request " \ "un-responded even after 25 minutes" print l_msg raise OpTestError(l_msg) if (x.__contains__('(yes/no)')): l_res = "yes\r\n" os.write(fd, l_res) if (x.__contains__('s password:'******'' os.write(fd, l_pwd + '\r\n') if (x.__contains__('Password:'******'' os.write(fd, l_pwd + '\r\n') if (x.__contains__('password')): response = l_pwd + "\r\n" os.write(fd, response) if (x.__contains__('yes')): response = '1' + "\r\n" os.write(fd, response) if (x.__contains__('Connection refused')): print x raise OpTestError(x) if (x.__contains__('Received disconnect from')): self.ssh_ver = '-1' if (x.__contains__('Connection closed by')): print(x) raise OpTestError(x) if (x.__contains__( "WARNING: POSSIBLE DNS SPOOFING DETECTED")): print(x) raise OpTestError("Its a RSA key problem : \n" + x) if (x.__contains__( "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED") ): print(x) raise OpTestError("Its a RSA key problem : \n" + x) if (x.__contains__("Permission denied")): l_msg = "Wrong Login or Password(" + l_user + "/" + l_pwd + ") :" + x print(l_msg) raise OpTestError(l_msg) if(x.__contains__("Rebooting") or \ (x.__contains__("rebooting the system"))): l_output = l_output + x raise OpTestError(l_output) if (x.__contains__("Connection timed out")): l_msg = "Connection timed out/" + \ l_host + " is not pingable" print(x) raise OpTestError(l_msg) if (x.__contains__("could not connect to CLI daemon")): print(x) raise OpTestError("Director server is not up/running(" "Do smstop then smstart to restart)") if ((x.__contains__("Error:")) and (i_cmd.__contains__('rmsys'))): print(x) raise OpTestError("Error removing:" + l_host) if ((x.__contains__( "Bad owner or permissions on /root/.ssh/config"))): print(x) raise OpTestError( "Bad owner or permissions on /root/.ssh/config," "Try 'chmod -R 600 /root/.ssh' & retry operation") l_output = l_output + x # time.sleep(1) except OSError: break if l_output.__contains__("Name or service not known"): reason = 'SSH Failed for :' + l_host + \ "\n Please provide a valid Hostname" print reason raise OpTestError(reason) # Gather child process status to freeup zombie and # Close child file descriptor before return if (fd): os.waitpid(pid, 0) os.close(fd) return l_output ## # @brief Get and Record Ubunto OS level # # @return l_oslevel @type string: OS level of the host provided # or raise OpTestError # def host_get_OS_Level(self): l_oslevel = self._ssh_execute(BMC_CONST.BMC_GET_OS_RELEASE) print l_oslevel return l_oslevel ## # @brief Executes a command on the os of the bmc to protect network setting # # @return OpTestError if failed # def host_protect_network_setting(self): try: l_rc = self._ssh_execute(BMC_CONST.OS_PRESERVE_NETWORK) except: l_errmsg = "Can't preserve network setting" print l_errmsg raise OpTestError(l_errmsg) ## # @brief Performs a cold reset onto the host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_cold_reset(self): print("Applying Cold reset on host.") l_rc = self._ssh_execute(BMC_CONST.HOST_COLD_RESET) # TODO: enable once defect SW331585 is fixed '''if BMC_CONST.BMC_PASS_COLD_RESET in l_rc: print l_rc time.sleep(BMC_CONST.BMC_COLD_RESET_DELAY) return BMC_CONST.FW_SUCCESS else: l_msg = "Cold reset Failed" print l_msg raise OpTestError(l_msg)''' self.util.PingFunc(self.bmcip, BMC_CONST.PING_RETRY_FOR_STABILITY) ## # @brief Flashes image using ipmitool # # @param i_image @type string: hpm file including location # @param i_imagecomponent @type string: component to be # update from the hpm file BMC_CONST.BMC_FW_IMAGE_UPDATE # or BMC_CONST.BMC_PNOR_IMAGE # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_code_update(self, i_image, imagecomponent): # Copy the hpm file to the tmp folder in the host try: self.util.copyFilesToDest(i_image, self.user, self.ip, "/tmp/", self.passwd) except: l_msg = "Copying hpm file to host failed" print l_msg raise OpTestError(l_msg) #self.host_protect_network_setting() #writing to host is not stable l_cmd = "\necho y | ipmitool -I usb " + BMC_CONST.BMC_HPM_UPDATE + "/tmp/" \ + i_image.rsplit("/", 1)[-1] + " " + imagecomponent print l_cmd try: l_rc = self._ssh_execute(l_cmd) print l_rc self._ssh_execute("rm -rf /tmp/" + i_image.rsplit("/", 1)[1]) except subprocess.CalledProcessError: l_msg = "Code Update Failed" print l_msg raise OpTestError(l_msg) if (l_rc.__contains__("Firmware upgrade procedure successful")): return BMC_CONST.FW_SUCCESS else: l_msg = "Code Update Failed" print l_msg raise OpTestError(l_msg) ## # @brief It will run linux command(i_cmd) on host using private interface _ssh_execute() # making this interface is public # # @param i_cmd @type string: linux command # # @return command output if command execution is successful else raises OpTestError # def host_run_command(self, i_cmd): try: l_res = self._ssh_execute(i_cmd) except: l_msg = "Command execution on host failed" print l_msg print sys.exc_info() raise OpTestError(l_msg) print l_res return l_res # @brief It will gather OPAL Message logs and store the copy in a logfile # which will be stored in FFDC dir. # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_gather_opal_msg_log(self): try: l_data = self.host_run_command(BMC_CONST.OPAL_MSG_LOG) except OpTestError: l_msg = "Failed to gather OPAL message logs" raise OpTestError(l_msg) l_res = commands.getstatusoutput("date +%Y%m%d_%H%M") l_logFile = "Opal_msglog_%s.log" % l_res[1] fn = self.cv_ffdcDir + "/" + l_logFile with open(fn, 'w') as f: f.write(l_data) return BMC_CONST.FW_SUCCESS ## # @brief Check if one or more binaries are present on host # # @param i_cmd @type string: binaries to check for # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_check_command(self, *i_cmd): l_cmd = 'which ' + ' '.join(i_cmd) + '; echo $?' print l_cmd l_res = self.host_run_command(l_cmd) l_res = l_res.splitlines() if (int(l_res[-1]) == 0): return BMC_CONST.FW_SUCCESS else: l_msg = "host_check_command: (%s) not present on host. output of '%s': %s" % ( ','.join(i_cmd), l_cmd, '\n'.join(l_res)) print l_msg raise OpTestError(l_msg) ## # @brief It will get the linux kernel version on host # # @return l_kernel @type string: kernel version of the host provided # or raise OpTestError # def host_get_kernel_version(self): l_kernel = self._ssh_execute("uname -a | awk {'print $3'}") l_kernel = l_kernel.replace("\r\n", "") print l_kernel return l_kernel ## # @brief This function will checks first for config file for a given kernel version on host, # if available then check for config option value and return that value # whether it is y or m...etc. # sample config option values: # CONFIG_CRYPTO_ZLIB=m # CONFIG_CRYPTO_LZO=y # # CONFIG_CRYPTO_842 is not set # # # @param i_kernel @type string: kernel version # @param i_config @type string: Which config option want to check in config file # Ex:CONFIG_SENSORS_IBMPOWERNV # # @return l_val @type string: It will return config option value y or m, # or raise OpTestError if config file is not available on host # or raise OpTestError if config option is not set in file. # def host_check_config(self, i_kernel, i_config): l_file = "/boot/config-%s" % i_kernel l_res = self._ssh_execute("test -e %s; echo $?" % l_file) l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "Config file is available" else: l_msg = "Config file %s is not available on host" % l_file print l_msg raise OpTestError(l_msg) l_cmd = "cat %s | grep -i --color=never %s" % (l_file, i_config) print l_cmd l_res = self._ssh_execute(l_cmd) print l_res try: l_val = ((l_res.split("=")[1]).replace("\r\n", "")) except: print l_val l_msg = "config option is not set,exiting..." print l_msg raise OpTestError(l_msg) return l_val ## # @brief It will return installed package name for given linux command(i_cmd) on host # # @param i_cmd @type string: linux command # @param i_oslevel @type string: OS level # # @return l_pkg @type string: installed package on host # def host_check_pkg_for_utility(self, i_oslevel, i_cmd): if 'Ubuntu' in i_oslevel: l_res = self._ssh_execute("dpkg -S `which %s`" % i_cmd) return l_res else: l_cmd = "rpm -qf `which %s`" % i_cmd l_res = self._ssh_execute(l_cmd) l_pkg = l_res.replace("\r\n", "") print l_pkg return l_pkg ## # @brief It will check whether a package is installed in a host OS # # @param i_oslevel @type string: OS level # @param i_package @type string: package name # # @return BMC_CONST.FW_SUCCESS if package is available # raise OpTestError if package is not available # def host_check_pkg_availability(self, i_oslevel, i_package): if 'Ubuntu' in i_oslevel: l_res = self.host_run_command("dpkg -l %s;echo $?" % i_package) else: l_cmd = "rpm -qa | grep -i %s" % i_package l_res = self.host_run_command(l_cmd) l_res = l_res.splitlines() if (int(l_res[-1]) == 0): return BMC_CONST.FW_SUCCESS else: l_msg = "Package %s is not there in host OS" % i_package raise OpTestError(l_msg) ## # @brief This function loads ibmpowernv driver only on powernv platform # and also this function works only in root user mode # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_ibmpowernv(self, i_oslevel): if "PowerKVM" not in i_oslevel: l_rc = self._ssh_execute("modprobe ibmpowernv; echo $?") l_rc = l_rc.replace("\r\n", "") if int(l_rc) == 0: cmd = "lsmod | grep -i ibmpowernv" response = self._ssh_execute(cmd) if "ibmpowernv" not in response: l_msg = "ibmpowernv module is not loaded, exiting" raise OpTestError(l_msg) else: print "ibmpowernv module is loaded" print cmd print response return BMC_CONST.FW_SUCCESS else: l_msg = "modprobe failed while loading ibmpowernv,exiting..." print l_msg raise OpTestError(l_msg) else: return BMC_CONST.FW_SUCCESS ## # @brief This function restarts the lm_sensors service on host using systemctl utility # systemctl utility is not present in ubuntu, This function will work in remaining all # other OS'es i.e redhat, sles and PowerKVM # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_start_lm_sensor_svc(self, i_oslevel): if 'Ubuntu' in i_oslevel: pass else: try: # Start the lm_sensors service cmd = "/bin/systemctl stop lm_sensors.service" self.host_run_command(cmd) cmd = "/bin/systemctl start lm_sensors.service" self.host_run_command(cmd) cmd = "/bin/systemctl status lm_sensors.service" res = self.host_run_command(cmd) return BMC_CONST.FW_SUCCESS except: l_msg = "loading lm_sensors service failed" print l_msg raise OpTestError(l_msg) ## # @brief It will clone latest linux git repository in i_dir directory # # @param i_dir @type string: directory where linux source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_linux_source(self, i_dir): l_msg = 'git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git' l_cmd = "git clone %s %s" % (l_msg, i_dir) self._ssh_execute("rm -rf %s" % i_dir) self._ssh_execute("mkdir %s" % i_dir) try: print l_cmd res = self._ssh_execute(l_cmd) print res return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning linux git repository is failed" print l_msg raise OpTestError(l_msg) ## # @brief reads msglog for getting Chip and Core information # # @return @type string: Chip and Core information # else raise OpTestError def host_read_msglog_core(self): try: return self._ssh_execute(BMC_CONST.OS_READ_MSGLOG_CORE) except: l_errmsg = "Can't get msglog data" print l_errmsg raise OpTestError(l_errmsg) ## # @brief reads getscom data # example: # Chip ID | Rev | Chip type # ---------|-------|-------- # 80000005 | DD2.0 | Centaur memory buffer # 80000004 | DD2.0 | Centaur memory buffer # 00000000 | DD2.0 | P8 (Venice) processor # # @param i_xscom_dir @type string: directory where getscom is installed # # @return @type string: getscom data # else raise OpTestError def host_read_getscom_data(self, i_xscom_dir): try: l_rc = self._ssh_execute(BMC_CONST.SUDO_COMMAND + i_xscom_dir + BMC_CONST.OS_GETSCOM_LIST) except OpTestError as e: l_errmsg = "Can't get getscom data" print l_errmsg raise OpTestError(l_errmsg) if ("command not found" in l_rc): l_errmsg = "Failed to locate getscom. Make sure it is installed in dir: " + i_xscom_dir print l_errmsg raise OpTestError(l_errmsg) return l_rc ## # @brief injects error using getscom # # @param i_xscom_dir @type string: directory where putscom is installed # param i_error @type string: error to be injected including the location # # @return output generated after executing putscom command or else raise OpTestError # def host_putscom(self, i_xscom_dir, i_error): print('Injecting Error.') l_rc = self._execute_no_return(BMC_CONST.SUDO_COMMAND + i_xscom_dir + BMC_CONST.OS_PUTSCOM_ERROR + i_error) ## # @brief Clears the gard records # # @param i_gard_dir @type string: directory where putscom is installed # # @return BMC_CONST.FW_SUCCESS or else raise OpTestError # def host_clear_gard_records(self, i_gard_dir): l_rc = self._ssh_execute(BMC_CONST.SUDO_COMMAND + i_gard_dir + BMC_CONST.CLEAR_GARD_CMD) if (BMC_CONST.GARD_CLEAR_SUCCESSFUL not in l_rc): l_msg = l_rc + '. Failed to clear gard' print l_msg raise OpTestError(l_msg) # Check to make sure no gard records were left l_result = self.host_list_gard_records(i_gard_dir) if (BMC_CONST.NO_GARD_RECORDS not in l_result): l_msg = l_rc + '. Gard records still found after clearing them' print l_msg raise OpTestError(l_msg) return BMC_CONST.FW_SUCCESS ## # @brief Lists all gard records # # @param i_gard_dir @type string: directory where putscom is installed # # @return gard records or else raise OpTestError # def host_list_gard_records(self, i_gard_dir): try: return self._ssh_execute(BMC_CONST.SUDO_COMMAND + i_gard_dir + BMC_CONST.LIST_GARD_CMD) except: l_errmsg = "Can't clear gard records" print l_errmsg raise OpTestError(l_errmsg) ## # @brief Execute a command on the targeted host but don't expect # any return data. # # @param i_cmd: @type str: command to be executed # @param i_timeout: @type int: # # @return BMC_CONST.FW_SUCCESS or else raise OpTestError # def _execute_no_return(self, i_cmd, i_timeout=60): print('Executing command: ' + i_cmd) try: p = pxssh.pxssh() p.login(self.ip, self.user, self.passwd) p.sendline() p.prompt() p.sendline(i_cmd) p.prompt(i_timeout) return BMC_CONST.FW_SUCCESS except: l_msg = "Failed to execute command: " + i_cmd print l_msg raise OpTestError(l_msg) ## # @brief enable/disable cpu states # # @param i_cpu_state @type string: BMC_CONST.CPU_ENABLE_STATE/ # BMC_CONST.CPU_DISABLE_STATE # # @return BMC_CONST.FW_SUCCESS or OpTestError # def host_disable_enable_cpu_states(self, i_cpu_state): try: self._ssh_execute(BMC_CONST.SUDO_COMMAND + "sh -c 'for i in " + \ BMC_CONST.CPU_IDLEMODE_STATE1 + "; do echo " + \ i_cpu_state + " > $i; done'") self._ssh_execute(BMC_CONST.SUDO_COMMAND + "sh -c 'for i in " + \ BMC_CONST.CPU_IDLEMODE_STATE2 + "; do echo " + \ i_cpu_state + " > $i; done'") return BMC_CONST.FW_SUCCESS except: l_errmsg = "Could not enable/disable cpu idle states" print l_errmsg raise OpTestError(l_errmsg) ## # @brief It will get the linux kernel version on host # # @return l_kernel @type string: kernel version of the host provided # or raise OpTestError # def host_get_kernel_version(self): l_kernel = self._ssh_execute("uname -a | awk {'print $3'}") l_kernel = l_kernel.replace("\r\n", "") print l_kernel return l_kernel ## # @brief This function will checks first for config file for a given kernel version on host, # if available then check for config option value and return that value # whether it is y or m...etc. # sample config option values: # CONFIG_CRYPTO_ZLIB=m # CONFIG_CRYPTO_LZO=y # # CONFIG_CRYPTO_842 is not set # # # @param i_kernel @type string: kernel version # @param i_config @type string: Which config option want to check in config file # Ex:CONFIG_SENSORS_IBMPOWERNV # # @return l_val @type string: It will return config option value y or m, # or raise OpTestError if config file is not available on host # or raise OpTestError if config option is not set in file. # def host_check_config(self, i_kernel, i_config): l_file = "/boot/config-%s" % i_kernel l_res = self._ssh_execute("test -e %s; echo $?" % l_file) l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "Config file is available" else: l_msg = "Config file %s is not available on host" % l_file print l_msg raise OpTestError(l_msg) l_cmd = "cat %s | grep -i --color=never %s" % (l_file, i_config) print l_cmd l_res = self._ssh_execute(l_cmd) print l_res try: l_val = ((l_res.split("=")[1]).replace("\r\n", "")) except: print l_val l_msg = "config option is not set,exiting..." print l_msg raise OpTestError(l_msg) return l_val ## # @brief It will return installed package name for given linux command(i_cmd) on host # # @param i_cmd @type string: linux command # @param i_oslevel @type string: OS level # # @return l_pkg @type string: installed package on host # def host_check_pkg_for_utility(self, i_oslevel, i_cmd): if 'Ubuntu' in i_oslevel: l_res = self._ssh_execute("dpkg -S `which %s`" % i_cmd) return l_res else: l_cmd = "rpm -qf `which %s`" % i_cmd l_res = self._ssh_execute(l_cmd) l_pkg = l_res.replace("\r\n", "") print l_pkg return l_pkg ## # @brief This function loads ibmpowernv driver only on powernv platform # and also this function works only in root user mode # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_ibmpowernv(self, i_oslevel): if "PowerKVM" not in i_oslevel: l_rc = self._ssh_execute("modprobe ibmpowernv; echo $?") l_rc = l_rc.replace("\r\n", "") if int(l_rc) == 0: cmd = "lsmod | grep -i ibmpowernv" response = self._ssh_execute(cmd) if "ibmpowernv" not in response: l_msg = "ibmpowernv module is not loaded, exiting" raise OpTestError(l_msg) else: print "ibmpowernv module is loaded" print cmd print response return BMC_CONST.FW_SUCCESS else: l_msg = "modprobe failed while loading ibmpowernv,exiting..." print l_msg raise OpTestError(l_msg) else: return BMC_CONST.FW_SUCCESS ## # @brief This function restarts the lm_sensors service on host using systemctl utility # systemctl utility is not present in ubuntu, This function will work in remaining all # other OS'es i.e redhat, sles and PowerKVM # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_start_lm_sensor_svc(self, i_oslevel): if 'Ubuntu' in i_oslevel: pass else: try: # Start the lm_sensors service cmd = "/bin/systemctl stop lm_sensors.service" self.host_run_command(cmd) cmd = "/bin/systemctl start lm_sensors.service" self.host_run_command(cmd) cmd = "/bin/systemctl status lm_sensors.service" res = self.host_run_command(cmd) return BMC_CONST.FW_SUCCESS except: l_msg = "loading lm_sensors service failed" print l_msg raise OpTestError(l_msg) ## # @brief It will clone latest linux git repository in i_dir directory # # @param i_dir @type string: directory where linux source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_linux_source(self, i_dir): l_msg = 'git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git' l_cmd = "git clone %s %s" % (l_msg, i_dir) self._ssh_execute("rm -rf %s" % i_dir) self._ssh_execute("mkdir %s" % i_dir) try: print l_cmd res = self._ssh_execute(l_cmd) print res return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning linux git repository is failed" print l_msg raise OpTestError(l_msg) ## # @brief It will load the module using modprobe and verify whether it is loaded or not # # @param i_module @type string: module name, which we want to load on host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_module(self, i_module): l_res = self.host_run_command("modprobe %s; echo $?" % i_module) l_res = l_res.splitlines() if int(l_res[-1]) == 0: pass else: l_msg = "Error in loading the module %s, modprobe failed" % i_module print l_msg raise OpTestError(l_msg) l_res = self.host_run_command("lsmod | grep -i --color=never %s" % i_module) if l_res.__contains__(i_module): print "%s module is loaded" % i_module return BMC_CONST.FW_SUCCESS else: l_msg = " %s module is not loaded" % i_module print l_msg raise OpTestError(l_msg) ## # @brief This function will read real time clock(RTC) time using hwclock utility # # @return l_res @type string: return hwclock value if command execution successfull # else raise OpTestError # def host_read_hwclock(self): print "Reading the hwclock" l_res = self.host_run_command("hwclock -r;echo $?") l_res = l_res.splitlines() if int(l_res[-1]) == 0: return l_res else: l_msg = "Reading the hwclock failed" print l_msg raise OpTestError(l_msg) ## # @brief This function will read system time using date utility (This will be mantained by kernel) # # @return l_res @type string: return system time value if command execution successfull # else raise OpTestError # def host_read_systime(self): print "Reading system time using date utility" l_res = self.host_run_command("date;echo $?") l_res = l_res.splitlines() if int(l_res[-1]) == 0: return l_res else: l_msg = "Reading the system time failed" print l_msg raise OpTestError(l_msg) ## # @brief This function will set hwclock time using the --date option # format should be "2015-01-01 12:12:12" # # @param i_time @type string: this is the time for setting the hwclock # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_set_hwclock_time(self, i_time): print "Setting the hwclock time to %s" % i_time l_res = self.host_run_command("hwclock --set --date \'%s\';echo $?" % i_time) l_res = l_res.splitlines() if int(l_res[-1]) == 0: return BMC_CONST.FW_SUCCESS else: l_msg = "Setting the hwclock failed" print l_msg raise OpTestError(l_msg) ## # @brief This function will load driver module on host based on the config option # if config value m: built as a module # y: driver built into kernel itself # else raises OpTestError # # @param i_kernel @type string: kernel version to get config file # i_config @type string: config option to check in config file # i_module @type string: driver module to load on host based on config value # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_module_based_on_config(self, i_kernel, i_config, i_module): l_val = self.host_check_config(i_kernel, i_config) if l_val == 'm': self.host_load_module(i_module) elif l_val == 'y': print "Driver built into kernel itself" else: l_msg = "Config value is changed" print l_msg raise OpTestError(l_msg) return BMC_CONST.FW_SUCCESS ## # @brief This function will return the list of installed i2c buses on host in two formats # list-by number Ex: ["0","1","2",....] # list-by-name Ex: ["i2c-0","i2c-1","i2c-2"....] # # @return l_list @type list: list of i2c buses by number # l_list1 @type list: list of i2c buses by name # or raise OpTestError if not able to get list of i2c buses # def host_get_list_of_i2c_buses(self): l_res = self.host_run_command("i2cdetect -l;echo $?") l_res = l_res.splitlines() if int(l_res[-1]) == 0: pass else: l_msg = "Not able to get list of i2c buses" print l_msg raise OpTestError(l_msg) l_res = self.host_run_command("i2cdetect -l | awk '{print $1}'") l_res = l_res.splitlines() # list by number Ex: ["0","1","2",....] l_list = [] # list by name Ex: ["i2c-0","i2c-1"...] l_list1 = [] for l_bus in l_res: matchObj = re.search("(i2c)-(\d{1,})", l_bus) if matchObj: l_list.append(matchObj.group(2)) l_list1.append(l_bus) else: pass return l_list, l_list1 ## # @brief This function will get information of EEPROM chips attached to the i2c buses # # @return l_res @type string: return EEPROM chips information # else raise OpTestError # def host_get_info_of_eeprom_chips(self): print "Getting the information of EEPROM chips" l_res = self.host_run_command("dmesg | grep -i --color=never at24") if l_res.__contains__("at24"): pass else: l_res = self.host_run_command("dmesg -C") self.host_run_command("rmmod at24") self.host_load_module("at24") l_res = self.host_run_command("dmesg | grep -i --color=never at24") if l_res.__contains__("at24"): pass else: l_msg = "Not able to get at24 info" raise OpTestError(l_msg) return l_res ## # @brief It will return list with elements having pairs of eeprom chip addresses and # corresponding i2c bus where the chip is attached. This information is getting # through sysfs interface. format is ["0 0x50","0 0x51","1 0x51","1 0x52"....] # # @return l_chips @type list: list having pairs of i2c bus number and eeprom chip address. # else raise OpTestError # def host_get_list_of_eeprom_chips(self): l_res = self.host_run_command("find /sys/ -name eeprom;echo $?") l_res = l_res.splitlines() if int(l_res[-1]) == 0: pass else: l_msg = "Not able to get list of eeprom chip addresses through sysfs interface" print l_msg raise OpTestError(l_msg) l_chips = [] for l_line in l_res: if l_line.__contains__("eeprom"): matchObj = re.search("/(\d{1,}-\d{4})/eeprom", l_line) if matchObj: l_line = matchObj.group(1) i_args = (l_line.replace("-", " ")) print i_args else: continue i_args = re.sub(" 00", " 0x", i_args) l_chips.append(i_args) print i_args return l_chips ## # @brief The hexdump utility is used to display the specified files. # This function will display in both ASCII+hexadecimal format. # # @param i_dev @type string: this is the file used as a input to hexdump for display info # Example file:"/sys/devices/platform/3fc0000000000.xscom:i2cm@a0000:i2c-bus@1/i2c-3/3-0050/eeprom" # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # # def host_hexdump(self, i_dev): l_res = self.host_run_command("hexdump -C %s;echo $?" % i_dev) l_res = l_res.splitlines() if int(l_res[-1]) == 0: return BMC_CONST.FW_SUCCESS else: l_msg = "hexdump failed for device %s" % i_dev print l_msg raise OpTestError(l_msg) ## # @brief It will clone latest skiboot git repository in i_dir directory # # @param i_dir @type string: directory where skiboot source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_skiboot_source(self, i_dir): l_msg = 'https://github.com/open-power/skiboot.git/' l_cmd = "git clone %s %s" % (l_msg, i_dir) self.host_run_command("git config --global http.sslverify false") self.host_run_command("rm -rf %s" % i_dir) self.host_run_command("mkdir %s" % i_dir) try: print l_cmd l_res = self.host_run_command(l_cmd) print l_res return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning skiboot git repository is failed" print l_msg raise OpTestError(l_msg) ## # @brief It will compile xscom-utils in the skiboot directory which was cloned in i_dir directory # # @param i_dir @type string: directory where skiboot source was cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_compile_xscom_utilities(self, i_dir): l_cmd = "cd %s/external/xscom-utils; make;" % i_dir print l_cmd l_res = self.host_run_command(l_cmd) l_cmd = "test -f %s/external/xscom-utils/getscom; echo $?" % i_dir l_res = self.host_run_command(l_cmd) l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "Executable binary getscom is available" else: l_msg = "getscom bin file is not present after make" print l_msg raise OpTestError(l_msg) l_cmd = "test -f %s/external/xscom-utils/putscom; echo $?" % i_dir l_res = self.host_run_command(l_cmd) l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "Executable binary putscom is available" return BMC_CONST.FW_SUCCESS else: l_msg = "putscom bin file is not present after make" print l_msg raise OpTestError(l_msg) ## # @brief It will compile gard utility in the skiboot directory which was cloned in i_dir directory # # @param i_dir @type string: directory where skiboot source was cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_compile_gard_utility(self, i_dir): l_cmd = "cd %s/external/gard; make;" % i_dir print l_cmd l_res = self.host_run_command(l_cmd) l_cmd = "test -f %s/external/gard/gard; echo $?" % i_dir l_res = self.host_run_command(l_cmd) l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "Executable binary gard is available" return BMC_CONST.FW_SUCCESS else: l_msg = "gard bin file is not present after make" print l_msg raise OpTestError(l_msg) ## # @brief This function generates olog.json file from skiboot which is used for # fwts olog test: Run OLOG scan and analysis checks. # # @param i_dir @type string: directory where skiboot source was cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_generate_fwts_olog_json(self, i_dir): l_cmd = "%s/external/fwts/generate-fwts-olog %s/ -o %s/olog.json" % ( i_dir, i_dir, i_dir) print l_cmd l_res = self.host_run_command(l_cmd) l_cmd = "test -f %s/olog.json; echo $?" % i_dir l_res = self.host_run_command(l_cmd) l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "olog.json is available in working directory %s" % i_dir return BMC_CONST.FW_SUCCESS else: l_msg = "olog.json file is failed to create from skiboot" print l_msg raise OpTestError(l_msg) ## # @brief It will clone latest fwts git repository in i_dir directory # # @param i_dir @type string: directory where fwts source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_fwts_source(self, i_dir): l_msg = 'git://kernel.ubuntu.com/hwe/fwts.git' l_cmd = "git clone %s %s" % (l_msg, i_dir) self.host_run_command("git config --global http.sslverify false") self.host_run_command("rm -rf %s" % i_dir) self.host_run_command("mkdir %s" % i_dir) try: print l_cmd l_res = self.host_run_command(l_cmd) print l_res return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning fwts git repository is failed" print l_msg raise OpTestError(l_msg) ## # @brief This function is used to build fwts tool in the fwts directory # which was cloned in i_dir directory # # @param i_dir @type string: directory where fwts source was cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_build_fwts_tool(self, i_dir): l_cmd = "cd %s/;autoreconf -ivf;./configure; make;" % i_dir print l_cmd l_res = self.host_run_command(l_cmd) l_cmd = "test -f %s/src/fwts; echo $?" % i_dir l_res = self.host_run_command(l_cmd) print l_res l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "Executable binary fwts is available" return BMC_CONST.FW_SUCCESS else: l_msg = "fwts bin file is not present after make" print l_msg raise OpTestError(l_msg) ## # @brief This function is used to get detected pci devices in different user/machine readable formats # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_list_pci_devices(self): self.host_run_command(BMC_CONST.HOST_LIST_PCI_DEVICES1) self.host_run_command(BMC_CONST.HOST_LIST_PCI_DEVICES2) self.host_run_command(BMC_CONST.HOST_LIST_PCI_DEVICES3) self.host_run_command(BMC_CONST.HOST_LIST_PCI_DEVICES4) self.host_run_command(BMC_CONST.HOST_LIST_PCI_DEVICES5) self.host_run_command(BMC_CONST.HOST_LIST_PCI_DEVICES6) self.host_run_command(BMC_CONST.HOST_LIST_PCI_SYSFS_DEVICES) ## # @brief This function is used to get more pci devices info in verbose mode # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_get_pci_verbose_info(self): l_res = self.host_run_command(BMC_CONST.HOST_LIST_PCI_VERBOSE) return l_res ## # @brief This function is used to get minimum usb devices info # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_list_usb_devices(self): self.host_run_command(BMC_CONST.HOST_LIST_USB_DEVICES1) self.host_run_command(BMC_CONST.HOST_LIST_USB_DEVICES2) self.host_run_command(BMC_CONST.HOST_LIST_USB_DEVICES3) ## # @brief This function enable only a single core # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_enable_single_core(self): self.host_run_command("ppc64_cpu --cores-on=1")
class OpTestHost(): ## # @brief Initialize this object # # @param i_hostip @type string: IP Address of the host # @param i_hostuser @type string: Userid to log into the host # @param i_hostpasswd @type string: Password of the userid to log into the host # @param i_bmcip @type string: IP Address of the bmc # def __init__(self, i_hostip, i_hostuser, i_hostpasswd, i_bmcip, i_results_dir, scratch_disk="", proxy="", logfile=sys.stdout): self.ip = i_hostip self.user = i_hostuser self.passwd = i_hostpasswd self.util = OpTestUtil() self.bmcip = i_bmcip parent_dir = os.path.dirname(os.path.abspath(__file__)) self.results_dir = i_results_dir self.logfile = logfile self.ssh = SSHConnection(i_hostip, i_hostuser, i_hostpasswd, logfile=self.logfile) self.scratch_disk = scratch_disk self.proxy = proxy self.scratch_disk_size = None def hostname(self): return self.ip def username(self): return self.user def password(self): return self.passwd def get_scratch_disk(self): return self.scratch_disk def get_scratch_disk_size(self, console=None): if self.scratch_disk_size is not None: return self.scratch_disk_size if console is None: raise Exception( "You need to call get_scratch_disk_size() with a console first" ) console.run_command("stty cols 300") dev_sdX = console.run_command("readlink -f %s" % self.get_scratch_disk()) dev_sdX = dev_sdX[0].replace("/dev/", "") scratch_disk_size = console.run_command("cat /sys/block/%s/size" % dev_sdX) # Use the (undocumented) /size sysfs property of nr 512byte sectors self.scratch_disk_size = int(scratch_disk_size[0]) * 512 def get_proxy(self): return self.proxy def get_ssh_connection(self): return self.ssh ## # @brief Get and Record Ubunto OS level # # @return l_oslevel @type string: OS level of the host provided # or raise OpTestError # def host_get_OS_Level(self): l_oslevel = self.ssh.run_command("cat /etc/os-release", timeout=60) return '\n'.join(l_oslevel) ## # @brief Executes a command on the os of the bmc to protect network setting # # @return OpTestError if failed # def host_protect_network_setting(self): try: l_rc = self.ssh.run_command(BMC_CONST.OS_PRESERVE_NETWORK, timeout=60) except: l_errmsg = "Can't preserve network setting" print l_errmsg raise OpTestError(l_errmsg) ## # @brief Performs a cold reset onto the host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_cold_reset(self): print("Applying Cold reset on host.") l_rc = self.ssh.run_command(BMC_CONST.HOST_COLD_RESET, timeout=60) # TODO: enable once defect SW331585 is fixed '''if BMC_CONST.BMC_PASS_COLD_RESET in l_rc: print l_rc time.sleep(BMC_CONST.BMC_COLD_RESET_DELAY) return BMC_CONST.FW_SUCCESS else: l_msg = "Cold reset Failed" print l_msg raise OpTestError(l_msg)''' self.util.PingFunc(self.bmcip, BMC_CONST.PING_RETRY_FOR_STABILITY) ## # @brief Flashes image using ipmitool # # @param i_image @type string: hpm file including location # @param i_imagecomponent @type string: component to be # update from the hpm file BMC_CONST.BMC_FW_IMAGE_UPDATE # or BMC_CONST.BMC_PNOR_IMAGE # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_code_update(self, i_image, imagecomponent): # Copy the hpm file to the tmp folder in the host try: self.util.copyFilesToDest(i_image, self.user, self.ip, "/tmp/", self.passwd) except: l_msg = "Copying hpm file to host failed" print l_msg raise OpTestError(l_msg) #self.host_protect_network_setting() #writing to host is not stable l_cmd = "\necho y | ipmitool -I usb " + BMC_CONST.BMC_HPM_UPDATE + "/tmp/" \ + i_image.rsplit("/", 1)[-1] + " " + imagecomponent print l_cmd try: l_rc = self.ssh.run_command(l_cmd, timeout=1500) print l_rc self.ssh.run_command("rm -rf /tmp/" + i_image.rsplit("/", 1)[1], timeout=120) except subprocess.CalledProcessError: l_msg = "Code Update Failed" print l_msg raise OpTestError(l_msg) if (l_rc.__contains__("Firmware upgrade procedure successful")): return BMC_CONST.FW_SUCCESS else: l_msg = "Code Update Failed" print l_msg raise OpTestError(l_msg) def host_run_command(self, i_cmd, timeout=1500): return self.ssh.run_command(i_cmd, timeout) ## # @brief It will gather OPAL Message logs and store the copy in a logfile # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_gather_opal_msg_log(self): try: l_data = '\n'.join(self.host_run_command(BMC_CONST.OPAL_MSG_LOG)) except OpTestError: l_msg = "Failed to gather OPAL message logs" raise OpTestError(l_msg) if not self.results_dir: print l_data return l_res = (time.asctime(time.localtime())).replace(" ", "_") l_logFile = "Opal_msglog_%s.log" % l_res fn = os.path.join(self.results_dir, l_logFile) print fn with open(fn, 'w') as f: f.write(l_data) ## # @brief Check if one or more binaries are present on host # # @param i_cmd @type string: binaries to check for # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_check_command(self, *i_cmd): l_cmd = 'which ' + ' '.join(i_cmd) print l_cmd try: l_res = self.host_run_command(l_cmd) except CommandFailed as c: l_msg = "host_check_command: (%s) not present on host. output of '%s': %s" % ( ','.join(i_cmd), l_cmd, '\n'.join(c.output)) print l_msg raise OpTestError(l_msg) return True ## # @brief It will get the linux kernel version on host # # @return l_kernel @type string: kernel version of the host provided # or raise OpTestError # def host_get_kernel_version(self): l_kernel = self.ssh.run_command("uname -a | awk {'print $3'}", timeout=60) l_kernel = ''.join(l_kernel) print l_kernel return l_kernel ## # @brief This function will checks first for config file for a given kernel version on host, # if available then check for config option value and return that value # whether it is y or m...etc. # sample config option values: # CONFIG_CRYPTO_ZLIB=m # CONFIG_CRYPTO_LZO=y # # CONFIG_CRYPTO_842 is not set # # # @param i_kernel @type string: kernel version # @param i_config @type string: Which config option want to check in config file # Ex:CONFIG_SENSORS_IBMPOWERNV # # @return l_val @type string: It will return config option value y or m, # or raise OpTestError if config file is not available on host # or raise OpTestError if config option is not set in file. # def host_check_config(self, i_kernel, i_config): l_file = "/boot/config-%s" % i_kernel try: l_res = self.ssh.run_command("test -e %s" % l_file, timeout=60) except CommandFailed as c: raise NoKernelConfig(i_kernel, l_file) print "Config file is available" l_cmd = "cat %s" % (l_file) l_res = self.ssh.run_command(l_cmd, timeout=60) config_opts = {} for o in l_res: m = re.match('# (.*) is not set', o) if m: config_opts[m.group(0)] = 'n' else: if '=' in o: opt, val = o.split("=") config_opts[opt] = val if config_opts.get(i_config) not in ["y", "m"]: raise KernelConfigNotSet(i_config) return config_opts[i_config] ## # @brief It will return installed package name for given linux command(i_cmd) on host # # @param i_cmd @type string: linux command # @param i_oslevel @type string: OS level # # @return l_pkg @type string: installed package on host # def host_check_pkg_for_utility(self, i_oslevel, i_cmd): if 'Ubuntu' in i_oslevel: return ''.join( self.ssh.run_command("dpkg -S `which %s`" % i_cmd, timeout=60)) else: l_cmd = "rpm -qf `which %s`" % i_cmd return ''.join(self.ssh.run_command(l_cmd, timeout=60)) ## # @brief This function loads ibmpowernv driver only on powernv platform # and also this function works only in root user mode # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_ibmpowernv(self, i_oslevel): if "PowerKVM" not in i_oslevel: o = self.ssh.run_command("modprobe ibmpowernv", timeout=60) cmd = "lsmod | grep -i ibmpowernv" response = self.ssh.run_command(cmd, timeout=60) if "ibmpowernv" not in ''.join(response): l_msg = "ibmpowernv module is not loaded, exiting" raise OpTestError(l_msg) else: print "ibmpowernv module is loaded" print cmd print response return BMC_CONST.FW_SUCCESS ## # @brief This function restarts the lm_sensors service on host using systemctl utility # systemctl utility is not present in ubuntu, This function will work in remaining all # other OS'es i.e redhat, sles and PowerKVM # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_start_lm_sensor_svc(self, i_oslevel): if 'Ubuntu' in i_oslevel: pass else: try: # Start the lm_sensors service cmd = "/bin/systemctl stop lm_sensors.service" self.host_run_command(cmd) cmd = "/bin/systemctl start lm_sensors.service" self.host_run_command(cmd) cmd = "/bin/systemctl status lm_sensors.service" res = self.host_run_command(cmd) return BMC_CONST.FW_SUCCESS except: l_msg = "loading lm_sensors service failed" print l_msg raise OpTestError(l_msg) ## # @brief It will clone latest linux git repository in i_dir directory # # @param i_dir @type string: directory where linux source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_linux_source(self, i_dir): l_msg = 'git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git' l_cmd = "git clone --depth=1 %s %s" % (l_msg, i_dir) self.ssh.run_command("rm -rf %s" % i_dir, timeout=300) self.ssh.run_command("mkdir %s" % i_dir, timeout=60) try: print l_cmd res = self.ssh.run_command(l_cmd, timeout=1500) print res return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning linux git repository is failed" print l_msg raise OpTestError(l_msg) ## # @brief reads getscom data # example: # Chip ID | Rev | Chip type # ---------|-------|-------- # 80000005 | DD2.0 | Centaur memory buffer # 80000004 | DD2.0 | Centaur memory buffer # 00000000 | DD2.0 | P8 (Venice) processor # # @param i_xscom_dir @type string: directory where getscom is installed # # @return @type string: getscom data # else raise OpTestError def host_read_getscom_data(self, i_xscom_dir): try: l_rc = self.ssh.run_command(BMC_CONST.SUDO_COMMAND + i_xscom_dir + BMC_CONST.OS_GETSCOM_LIST, timeout=60) except OpTestError as e: l_errmsg = "Can't get getscom data" print l_errmsg raise OpTestError(l_errmsg) if ("command not found" in l_rc): l_errmsg = "Failed to locate getscom. Make sure it is installed in dir: " + i_xscom_dir print l_errmsg raise OpTestError(l_errmsg) return l_rc ## # @brief injects error using getscom # # @param i_xscom_dir @type string: directory where putscom is installed # param i_error @type string: error to be injected including the location # # @return output generated after executing putscom command or else raise OpTestError # def host_putscom(self, i_xscom_dir, i_error): print('Injecting Error.') l_rc = self._execute_no_return(BMC_CONST.SUDO_COMMAND + i_xscom_dir + BMC_CONST.OS_PUTSCOM_ERROR + i_error) ## # @brief Clears the gard records # # @param i_gard_dir @type string: directory where putscom is installed # # @return BMC_CONST.FW_SUCCESS or else raise OpTestError # def host_clear_gard_records(self, i_gard_dir): l_rc = self.ssh.run_command(BMC_CONST.SUDO_COMMAND + i_gard_dir + BMC_CONST.CLEAR_GARD_CMD, timeout=60) if (BMC_CONST.GARD_CLEAR_SUCCESSFUL not in l_rc): l_msg = l_rc + '. Failed to clear gard' print l_msg raise OpTestError(l_msg) # Check to make sure no gard records were left l_result = self.host_list_gard_records(i_gard_dir) if (BMC_CONST.NO_GARD_RECORDS not in l_result): l_msg = l_rc + '. Gard records still found after clearing them' print l_msg raise OpTestError(l_msg) return BMC_CONST.FW_SUCCESS ## # @brief Lists all gard records # # @param i_gard_dir @type string: directory where putscom is installed # # @return gard records or else raise OpTestError # def host_list_gard_records(self, i_gard_dir): try: return self.ssh.run_command(BMC_CONST.SUDO_COMMAND + i_gard_dir + BMC_CONST.LIST_GARD_CMD, timeout=60) except: l_errmsg = "Can't clear gard records" print l_errmsg raise OpTestError(l_errmsg) ## # @brief Execute a command on the targeted host but don't expect # any return data. # # @param i_cmd: @type str: command to be executed # @param i_timeout: @type int: # # @return BMC_CONST.FW_SUCCESS or else raise OpTestError # def _execute_no_return(self, i_cmd, i_timeout=60): print('Executing command: ' + i_cmd) try: p = pxssh.pxssh() p.login(self.ip, self.user, self.passwd) p.sendline() p.prompt() p.sendline(i_cmd) p.prompt(i_timeout) return BMC_CONST.FW_SUCCESS except: l_msg = "Failed to execute command: " + i_cmd print l_msg raise OpTestError(l_msg) ## # @brief enable/disable cpu states # # @param i_cpu_state @type string: BMC_CONST.CPU_ENABLE_STATE/ # BMC_CONST.CPU_DISABLE_STATE # # @return BMC_CONST.FW_SUCCESS or OpTestError # def host_disable_enable_cpu_states(self, i_cpu_state): try: self.ssh.run_command(BMC_CONST.SUDO_COMMAND + "sh -c 'for i in " + \ BMC_CONST.CPU_IDLEMODE_STATE1 + "; do echo " + \ i_cpu_state + " > $i; done'", timeout=60) self.ssh.run_command(BMC_CONST.SUDO_COMMAND + "sh -c 'for i in " + \ BMC_CONST.CPU_IDLEMODE_STATE2 + "; do echo " + \ i_cpu_state + " > $i; done'", timeout=60) return BMC_CONST.FW_SUCCESS except: l_errmsg = "Could not enable/disable cpu idle states" print l_errmsg raise OpTestError(l_errmsg) ## # @brief It will load the module using modprobe and verify whether it is loaded or not # # @param i_module @type string: module name, which we want to load on host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_module(self, i_module): try: l_res = self.host_run_command("modprobe %s" % i_module) except CommandFailed as c: l_msg = "Error in loading the module %s, modprobe failed: %s" % ( i_module, str(c)) raise OpTestError(l_msg) l_res = self.host_run_command("lsmod | grep -i --color=never %s" % i_module) if re.search(i_module, ''.join(l_res)): print "%s module is loaded" % i_module return BMC_CONST.FW_SUCCESS else: raise KernelModuleNotLoaded(i_module) ## # @brief This function will read real time clock(RTC) time using hwclock utility # # @return l_res @type string: return hwclock value if command execution successfull # else raise OpTestError # def host_read_hwclock(self): print "Reading the hwclock" self.host_run_command("hwclock -r;echo $?") ## # @brief This function will read system time using date utility (This will be mantained by kernel) # # @return l_res @type string: return system time value if command execution successfull # else raise OpTestError # def host_read_systime(self): print "Reading system time using date utility" l_res = self.host_run_command("date") return l_res ## # @brief This function will set hwclock time using the --date option # format should be "2015-01-01 12:12:12" # # @param i_time @type string: this is the time for setting the hwclock # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_set_hwclock_time(self, i_time): print "Setting the hwclock time to %s" % i_time self.host_run_command("hwclock --set --date \'%s\'" % i_time) ## # @brief This function will load driver module on host based on the config option # if config value m: built as a module # y: driver built into kernel itself # else raises OpTestError # # @param i_kernel @type string: kernel version to get config file # i_config @type string: config option to check in config file # i_module @type string: driver module to load on host based on config value # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_module_based_on_config(self, i_kernel, i_config, i_module): l_val = self.host_check_config(i_kernel, i_config) if l_val == 'm': self.host_load_module(i_module) elif l_val == 'y': print "Driver built into kernel itself" elif l_val == 'n': raise KernelConfigNotSet(i_config) ## # @brief It will clone latest skiboot git repository in i_dir directory # # @param i_dir @type string: directory where skiboot source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_skiboot_source(self, i_dir): l_msg = 'https://github.com/open-power/skiboot.git/' l_cmd = "git clone %s %s" % (l_msg, i_dir) self.host_run_command("git config --global http.sslverify false") self.host_run_command("rm -rf %s" % i_dir) self.host_run_command("mkdir %s" % i_dir) try: print l_cmd l_res = self.host_run_command(l_cmd) print l_res return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning skiboot git repository is failed" print l_msg raise OpTestError(l_msg) ## # @brief This function enable only a single core # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_enable_single_core(self): self.host_run_command("ppc64_cpu --cores-on=1") ## # @brief This function is used to get list of PCI PHB domains. # # @return self.pci_domains list of PHB domains @type list or raise OpTestError # def host_get_list_of_pci_domains(self): self.pci_domains = [] self.host_run_command("lspci -mm") res = self.host_run_command('lspci -mm | cut -d":" -f1 | sort | uniq') for domain in res: if not domain: continue if len(domain) != 4: domain = ''.join(("00", domain)) domain = 'PCI' + domain if not self.pci_domains.__contains__(domain): self.pci_domains.append(domain) print self.pci_domains return self.pci_domains ## # @brief This function is used to get the PHB domain of root port where # the filesystem is mounted(We need to skip this in EEH tests as recovery # will fail on this domain is expected) # # @return boot_domain root PHB @type string or raise OpTestError # def host_get_root_phb(self): cmd = "df -h /boot | awk 'END {print $1}'" res = self.host_run_command(cmd) boot_disk = ''.join(res).split("/dev/")[1] boot_disk = boot_disk.replace("\r\n", "") cmd = "ls -l /dev/disk/by-path/ | grep %s | awk '{print $(NF-2)}'" % boot_disk res = self.host_run_command(cmd) matchObj = re.search(r"\d{4}(?!\d)", '\n'.join(res), re.S) if not matchObj: raise OpTestError("Not able to find out root phb domain") boot_domain = 'PCI' + matchObj.group(0) return boot_domain ## # @brief It will gather kernel dmesg logs and store the copy in a logfile # which will be stored in results dir. # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_gather_kernel_log(self): try: l_data = '\n'.join(self.host_run_command("dmesg")) except OpTestError: l_msg = "Failed to gather kernel dmesg log" raise OpTestError(l_msg) if not self.results_dir: print l_data return l_res = (time.asctime(time.localtime())).replace(" ", "_") l_logFile = "Kernel_dmesg_log_%s.log" % l_res fn = os.path.join(self.results_dir, l_logFile) print fn with open(fn, 'w') as f: f.write(l_data) return BMC_CONST.FW_SUCCESS ## # @brief This function starts opal_errd daemon # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_start_opal_errd_daemon(self): self.host_run_command("systemctl start opal_errd") ## # @brief This function stops opal_errd daemon # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_stop_opal_errd_daemon(self): self.host_run_command("systemctl stop opal_errd") ## # @brief This function gets the status of opal_errd daemon # # @return True/False: if opal_errd run/not run or throws exception # if not able to get status # def host_get_status_of_opal_errd_daemon(self): res = self.host_run_command( "ps -ef | grep -v grep | grep opal_errd | wc -l") print res if res[0].strip() == "0": print "Opal_errd daemon is not running" return False elif res[0].strip() == "1": print "Opal_errd daemon is running" return True else: raise OpTestError("Not able to get status of opal errd daemon") ## # @brief This function lists all error logs in host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_list_all_errorlogs(self): self.host_run_command("opal-elog-parse -l") ## # @brief This function lists all service action logs in host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_list_all_service_action_logs(self): self.host_run_command("opal-elog-parse -s") ## # @brief This function gets the number of error logs # # @return res or raise OpTestError # def host_get_number_of_errorlogs(self): res = self.host_run_command("ls %s | wc -l" % BMC_CONST.OPAL_ELOG_DIR) print res return res ## # @brief This function clears/acknowledges all error logs in host # # @return True on success or raise OpTestError # def host_clear_error_logs(self): self.host_run_command("rm -f %s/*" % BMC_CONST.OPAL_ELOG_DIR) res = self.host_run_command("ls %s -1 --color=never" % BMC_CONST.OPAL_ELOG_SYSFS_DIR) print '\n'.join(res) for entry in res: entry = entry.strip() if entry == '': continue self.host_run_command("echo 1 > %s/%s/acknowledge" % (BMC_CONST.OPAL_ELOG_SYSFS_DIR, entry)) return True ## # @brief This function clears/acknowledges all dumps in host # # @return True on success or raise OpTestError # def host_clear_all_dumps(self): self.host_run_command("rm -f %s/*" % BMC_CONST.OPAL_DUMP_DIR) res = self.host_run_command("ls %s -1 --color=never" % BMC_CONST.OPAL_DUMP_SYSFS_DIR) for entry in res: entry = entry.strip() if (entry == "initiate_dump") or (entry == ''): continue else: self.host_run_command("echo 1 > %s/%s/acknowledge" % (BMC_CONST.OPAL_DUMP_SYSFS_DIR, entry)) return True # @brief This function disables kdump service # # @param os_level: string output of /etc/os-release # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_disable_kdump_service(self, os_level): if "Ubuntu" in os_level: self.host_run_command("systemctl stop kdump-tools.service") try: self.host_run_command("systemctl status kdump-tools.service") except CommandFailed as cf: if cf.exitcode == 3: pass else: print str(cf) raise OpTestError("kdump-tools service is failed to stop") else: self.host_run_command("systemctl stop kdump.service") try: self.host_run_command("systemctl status kdump.service") except CommandFailed as cf: if cf.exitcode == 3: pass else: print str(cf) raise OpTestError("kdump service is failed to stop") ## # @brief This function disables kdump service # # @param os_level: string output of /etc/os-release # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_enable_kdump_service(self, os_level): if "Ubuntu" in os_level: self.host_run_command("systemctl stop kdump-tools.service") self.host_run_command("systemctl start kdump-tools.service") self.host_run_command("systemctl status kdump-tools.service") else: self.host_run_command("systemctl stop kdump.service") self.host_run_command("systemctl start kdump.service") self.host_run_command("service status kdump.service") def host_check_sysfs_path_availability(self, path): res = self.host_run_command("ls %s" % path) if "No such file or directory" in res: return False return True def host_check_dt_node_exist(self, node_path): path = "/proc/device-tree/" + node_path res = self.host_run_command("ls %s" % path) if "No such file or directory" in res: return False return True def host_get_list_of_chips(self): res = self.host_run_command("PATH=/usr/local/sbin:$PATH getscom -l") chips = [] for line in res: matchObj = re.search("(\d{8}).*processor", line) if matchObj: chips.append(matchObj.group(1)) if not chips: raise Exception("Getscom failed to list processor chip ids") chips.sort() print chips # ['00000000', '00000001', '00000010'] return chips def host_get_cores(self): proc_gen = self.host_get_proc_gen() core_ids = {} cpu_files = self.host_run_command( "find /sys/devices/system/cpu/ -name 'cpu[0-9]*'") for cpu_file in cpu_files: cpu_id = self.host_run_command("basename %s | tr -dc '0-9'" % cpu_file)[-1] try: pir = self.host_run_command("cat %s/pir" % cpu_file)[-1] except CommandFailed: continue if proc_gen in ["POWER8", "POWER8E"]: core_id = hex((int("0x%s" % pir, 16) >> 3) & 0xf) chip_id = hex((int("0x%s" % pir, 16) >> 7) & 0x3f) elif proc_gen in ["POWER9"]: core_id = hex((int("0x%s" % pir, 16) >> 2) & 0x3f) chip_id = hex((int("0x%s" % pir, 16) >> 8) & 0x7f) else: raise OpTestError("Unknown or new processor type") core_id = core_id.split('x')[1] chip_id = chip_id.split('x')[1] if chip_id in core_ids: core_ids[chip_id].append(core_id) else: core_ids[chip_id] = [core_id] for i in core_ids: core_ids[i] = list(set(core_ids[i])) core_ids = sorted(core_ids.iteritems()) print core_ids return core_ids # Supported on OpenPower and P9 FSP system def host_prd_supported(self, bmc_type): if not "FSP" in bmc_type: return True proc_gen = self.host_get_proc_gen() if proc_gen in ["POWER8", "POWER8E"]: return False return True def host_get_proc_gen(self): try: if self.proc_gen: pass except AttributeError: self.proc_gen = ''.join( self.host_run_command( "grep '^cpu' /proc/cpuinfo |uniq|sed -e 's/^.*: //;s/ .*//;'" )) return self.proc_gen def host_get_smt(self): self.cpu = self.host_get_proc_gen() if self.cpu in ["POWER8", "POWER8E"]: return 8 elif self.cpu in ["POWER9"]: return 4 else: return 1 def host_get_core_count(self): res = self.host_run_command("lscpu --all -e| wc -l") return int(res[0]) / (self.host_get_smt()) def host_gather_debug_logs(self): self.ssh.run_command_ignore_fail( "grep ',[0-4]\]' /sys/firmware/opal/msglog") self.ssh.run_command_ignore_fail( "dmesg -T --level=alert,crit,err,warn") def host_copy_fake_gard(self): path = os.path.abspath(os.path.join("common", os.pardir)) i_image = path + "/test_binaries/fake.gard" # Copy the fake.gard file to the tmp folder in the host try: self.util.copyFilesToDest(i_image, self.user, self.ip, "/tmp/", self.passwd) except: l_msg = "Copying fake.gard file to host failed" print l_msg raise OpTestError(l_msg) def host_pflash_get_partition(self, partition): d = self.host_run_command("pflash --info") for line in d: s = re.search(partition, line) if s: m = re.match( r'ID=\d+\s+\S+\s+((0[xX])?[0-9a-fA-F]+)..(0[xX])?[0-9a-fA-F]+\s+\(actual=((0[xX])?[0-9a-fA-F]+)\).*', line) offset = int(m.group(1), 16) length = int(m.group(4), 16) ret = {'offset': offset, 'length': length} return ret
class OpTestHost(): ## # @brief Initialize this object # # @param i_hostip @type string: IP Address of the host # @param i_hostuser @type string: Userid to log into the host # @param i_hostpasswd @type string: Password of the userid to log into the host # @param i_bmcip @type string: IP Address of the bmc # def __init__(self, i_hostip, i_hostuser, i_hostpasswd, i_bmcip, i_results_dir, scratch_disk="", proxy="", logfile=sys.stdout, check_ssh_keys=False, known_hosts_file=None): self.ip = i_hostip self.user = i_hostuser self.passwd = i_hostpasswd self.util = OpTestUtil() self.bmcip = i_bmcip parent_dir = os.path.dirname(os.path.abspath(__file__)) self.results_dir = i_results_dir self.logfile = logfile self.ssh = OpTestSSH(i_hostip, i_hostuser, i_hostpasswd, logfile=self.logfile, check_ssh_keys=check_ssh_keys, known_hosts_file=known_hosts_file) self.scratch_disk = scratch_disk self.proxy = proxy self.scratch_disk_size = None self.conf = OpTestConfiguration.conf def hostname(self): return self.ip def username(self): return self.user def password(self): return self.passwd def set_system(self, system): self.ssh.set_system(system) def get_scratch_disk(self): return self.scratch_disk def get_scratch_disk_size(self, console=None): if self.scratch_disk_size is not None: return self.scratch_disk_size if console is None: raise Exception("You need to call get_scratch_disk_size() with a console first") dev_sdX = console.run_command("readlink -f %s" % self.get_scratch_disk()) dev_sdX = dev_sdX[0].replace("/dev/","") scratch_disk_size = console.run_command("cat /sys/block/%s/size" % dev_sdX) # Use the (undocumented) /size sysfs property of nr 512byte sectors self.scratch_disk_size = int(scratch_disk_size[0])*512 def get_proxy(self): return self.proxy def get_ssh_connection(self): return self.ssh ## # @brief Get and Record Ubunto OS level # # @return l_oslevel @type string: OS level of the host provided # or raise OpTestError # def host_get_OS_Level(self, console=0): l_oslevel = self.host_run_command("cat /etc/os-release", timeout=60, console=console) return '\n'.join(l_oslevel) ## # @brief Performs a cold reset onto the host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_cold_reset(self): log.debug(("Applying Cold reset on host.")) l_rc = self.ssh.run_command(BMC_CONST.HOST_COLD_RESET, timeout=60) # TODO: enable once defect SW331585 is fixed '''if BMC_CONST.BMC_PASS_COLD_RESET in l_rc: print l_rc time.sleep(BMC_CONST.BMC_COLD_RESET_DELAY) return BMC_CONST.FW_SUCCESS else: l_msg = "Cold reset Failed" print l_msg raise OpTestError(l_msg)''' self.util.PingFunc(self.bmcip, BMC_CONST.PING_RETRY_FOR_STABILITY) ## # @brief Flashes image using ipmitool # # @param i_image @type string: hpm file including location # @param i_imagecomponent @type string: component to be # update from the hpm file BMC_CONST.BMC_FW_IMAGE_UPDATE # or BMC_CONST.BMC_PNOR_IMAGE # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_code_update(self, i_image, imagecomponent): # Copy the hpm file to the tmp folder in the host try: self.util.copyFilesToDest(i_image, self.user, self.ip, "/tmp/", self.passwd) except: l_msg = "Copying hpm file to host failed" log.warning(l_msg) raise OpTestError(l_msg) l_cmd = "\necho y | ipmitool -I usb " + BMC_CONST.BMC_HPM_UPDATE + "/tmp/" \ + i_image.rsplit("/", 1)[-1] + " " + imagecomponent log.debug(l_cmd) try: l_rc = self.ssh.run_command(l_cmd, timeout=1500) log.debug(l_rc) self.ssh.run_command("rm -rf /tmp/" + i_image.rsplit("/", 1)[1],timeout=120) except subprocess.CalledProcessError: l_msg = "Code Update Failed" log.warning(l_msg) raise OpTestError(l_msg) if(l_rc.__contains__("Firmware upgrade procedure successful")): return BMC_CONST.FW_SUCCESS else: l_msg = "Code Update Failed" log.warning(l_msg) raise OpTestError(l_msg) def host_run_command(self, i_cmd, timeout=1500, retry=0, console=0): # if we are QEMU use the system console if isinstance(self.ssh.system.console, OpTestQemu.QemuConsole) or (console == 1): return self.ssh.system.console.run_command(i_cmd, timeout, retry) else: return self.ssh.run_command(i_cmd, timeout, retry) ## # @brief It will gather OPAL Message logs and store the copy in a logfile # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_gather_opal_msg_log(self, console=0): try: l_data = '\n'.join(self.host_run_command(BMC_CONST.OPAL_MSG_LOG, console=console)) except OpTestError: l_msg = "Failed to gather OPAL message logs" raise OpTestError(l_msg) if not self.results_dir: log.debug(l_data) return l_res = (time.asctime(time.localtime())).replace(" ", "_") l_logFile = "Opal_msglog_%s.log" % l_res fn = os.path.join(self.results_dir, l_logFile) log.debug(fn) with open(fn, 'w') as f: f.write(l_data) ## # @brief Check if one or more binaries are present on host # # @param i_cmd @type string: binaries to check for # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_check_command(self, *i_cmd, **kwargs): default_vals = {'console': 0} for key in default_vals: if key not in kwargs.keys(): kwargs[key] = default_vals[key] l_cmd = 'which ' + ' '.join(i_cmd) log.debug(l_cmd) try: l_res = self.host_run_command(l_cmd, console=kwargs['console']) except CommandFailed as c: l_msg = "host_check_command: (%s) not present on host. output of '%s': %s" % (','.join(i_cmd), l_cmd, '\n'.join(c.output)) log.error(l_msg) raise OpTestError(l_msg) return True ## # @brief It will get the linux kernel version on host # # @return l_kernel @type string: kernel version of the host provided # or raise OpTestError # def host_get_kernel_version(self, console=0): l_kernel = self.host_run_command("uname -a | awk {'print $3'}", timeout=60, console=0) l_kernel = ''.join(l_kernel) log.debug(l_kernel) return l_kernel ## # @brief This function will checks first for config file for a given kernel version on host, # if available then check for config option value and return that value # whether it is y or m...etc. # sample config option values: # CONFIG_CRYPTO_ZLIB=m # CONFIG_CRYPTO_LZO=y # # CONFIG_CRYPTO_842 is not set # # # @param i_kernel @type string: kernel version # @param i_config @type string: Which config option want to check in config file # Ex:CONFIG_SENSORS_IBMPOWERNV # # @return l_val @type string: It will return config option value y or m, # or raise OpTestError if config file is not available on host # or raise OpTestError if config option is not set in file. # def host_check_config(self, i_kernel, i_config, console=0): l_file = "/boot/config-%s" % i_kernel try: l_res = self.host_run_command("test -e %s" % l_file, timeout=60, console=console) except CommandFailed as c: raise NoKernelConfig(i_kernel, l_file) log.debug("Config file is available") l_cmd = "cat %s | grep -i --color=never %s" % (l_file, i_config) l_res = self.host_run_command(l_cmd, timeout=60, console=console) log.debug(l_res) config_opts = {} for o in l_res: m = re.match('# (.*) is not set', o) if m: config_opts[m.group(0)]='n' else: if '=' in o: opt, val = o.split("=") config_opts[opt] = val if config_opts.get(i_config) not in ["y","m"]: raise KernelConfigNotSet(i_config) return config_opts[i_config] ## # @brief It will return installed package name for given linux command(i_cmd) on host # # @param i_cmd @type string: linux command # @param i_oslevel @type string: OS level # # @return l_pkg @type string: installed package on host # def host_check_pkg_for_utility(self, i_oslevel, i_cmd, console=0): if 'Ubuntu' in i_oslevel: return ''.join(self.host_run_command("dpkg -S `which %s`" % i_cmd, timeout=60, console=console)) else: l_cmd = "rpm -qf `which %s`" % i_cmd return ''.join(self.host_run_command(l_cmd, timeout=60, console=console)) ## # @brief This function loads ibmpowernv driver only on powernv platform # and also this function works only in root user mode # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_ibmpowernv(self, i_oslevel): if "PowerKVM" not in i_oslevel: o = self.ssh.run_command("modprobe ibmpowernv",timeout=60) cmd = "lsmod | grep -i ibmpowernv" response = self.ssh.run_command(cmd, timeout=60) if "ibmpowernv" not in ''.join(response): l_msg = "ibmpowernv module is not loaded, exiting" raise OpTestError(l_msg) else: log.debug("ibmpowernv module is loaded") log.debug(cmd) log.debug(response) return BMC_CONST.FW_SUCCESS ## # @brief This function restarts the lm_sensors service on host using systemctl utility # systemctl utility is not present in ubuntu, This function will work in remaining all # other OS'es i.e redhat, sles and PowerKVM # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_start_lm_sensor_svc(self, i_oslevel, console=0): if 'Ubuntu' in i_oslevel: pass else: try: # Start the lm_sensors service cmd = "/bin/systemctl stop lm_sensors.service" self.host_run_command(cmd, console=console) cmd = "/bin/systemctl start lm_sensors.service" self.host_run_command(cmd, console=console) cmd = "/bin/systemctl status lm_sensors.service" res = self.host_run_command(cmd, console=console) return BMC_CONST.FW_SUCCESS except: l_msg = "loading lm_sensors service failed" log.error(l_msg) raise OpTestError(l_msg) ## # @brief It will clone latest linux git repository in i_dir directory # # @param i_dir @type string: directory where linux source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_linux_source(self, i_dir): l_msg = 'git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git' l_cmd = "git clone --depth=1 %s %s" % (l_msg, i_dir) self.ssh.run_command("rm -rf %s" % i_dir, timeout=300) self.ssh.run_command("mkdir %s" % i_dir, timeout=60) try: log.debug(l_cmd) res = self.ssh.run_command(l_cmd, timeout=1500) log.debug(res) return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning linux git repository is failed" log.error(l_msg) raise OpTestError(l_msg) ## # @brief It will load the module using modprobe and verify whether it is loaded or not # # @param i_module @type string: module name, which we want to load on host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_module(self, i_module, console=0): try: l_res = self.host_run_command("modprobe %s" % i_module, console=console) except CommandFailed as c: l_msg = "Error in loading the module %s, modprobe failed: %s" % (i_module,str(c)) raise OpTestError(l_msg) l_res = self.host_run_command("lsmod | grep -i --color=never %s" % i_module, console=console) if re.search(i_module, ''.join(l_res)): log.debug("%s module is loaded" % i_module) return BMC_CONST.FW_SUCCESS else: raise KernelModuleNotLoaded(i_module) ## # @brief This function will read real time clock(RTC) time using hwclock utility # # @return l_res @type string: return hwclock value if command execution successfull # else raise OpTestError # def host_read_hwclock(self, console=0): log.debug("Reading the hwclock") self.host_run_command("hwclock -r;echo $?", console=console) ## # @brief This function will read system time using date utility (This will be mantained by kernel) # # @return l_res @type string: return system time value if command execution successfull # else raise OpTestError # def host_read_systime(self, console=0): log.debug("Reading system time using date utility") l_res = self.host_run_command("date", console=console) return l_res ## # @brief This function will set hwclock time using the --date option # format should be "2015-01-01 12:12:12" # # @param i_time @type string: this is the time for setting the hwclock # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_set_hwclock_time(self, i_time, console=0): log.debug("Setting the hwclock time to %s" % i_time) self.host_run_command("hwclock --set --date \'%s\'" % i_time, console=console) ## # @brief This function will load driver module on host based on the config option # if config value m: built as a module # y: driver built into kernel itself # else raises OpTestError # # @param i_kernel @type string: kernel version to get config file # i_config @type string: config option to check in config file # i_module @type string: driver module to load on host based on config value # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_module_based_on_config(self, i_kernel, i_config, i_module, console=0): l_val = self.host_check_config(i_kernel, i_config, console=console) if l_val == 'm': self.host_load_module(i_module, console=console) elif l_val == 'y': log.debug("Driver built into kernel itself") elif l_val == 'n': raise KernelConfigNotSet(i_config) ## # @brief It will clone latest skiboot git repository in i_dir directory # # @param i_dir @type string: directory where skiboot source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_skiboot_source(self, i_dir, console=0): l_msg = 'https://github.com/open-power/skiboot.git/' l_cmd = "git clone %s %s" % (l_msg, i_dir) self.host_run_command("git config --global http.sslverify false", console=console) self.host_run_command("rm -rf %s" % i_dir, console=console) self.host_run_command("mkdir %s" % i_dir, console=console) try: log.debug(l_cmd) l_res = self.host_run_command(l_cmd, console=console) log.debug(l_res) return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning skiboot git repository is failed" log.debug(l_msg) raise OpTestError(l_msg) ## # @brief This function enable only a single core # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_enable_single_core(self, console=0): self.host_run_command("ppc64_cpu --cores-on=1", console=console) def host_enable_all_cores(self, console=0): self.host_run_command("ppc64_cpu --cores-on=all", console=console) ## # @brief This function is used to get list of PCI PHB domains. # # @return self.pci_domains list of PHB domains @type list or raise OpTestError # def host_get_list_of_pci_domains(self, console=0): self.pci_domains = [] self.host_run_command("lspci -mm", console=console) res = self.host_run_command('lspci -mm | cut -d":" -f1 | sort | uniq', console=console) for domain in res: if not domain: continue if len(domain) != 4: domain = ''.join(("00", domain)) domain = 'PCI' + domain if not self.pci_domains.__contains__(domain): self.pci_domains.append(domain) log.debug(self.pci_domains) return self.pci_domains ## # @brief This function is used to get the PHB domain of root port where # the filesystem is mounted(We need to skip this in EEH tests as recovery # will fail on this domain is expected) # # @return boot_domain root PHB @type string or raise OpTestError # def host_get_root_phb(self, console=0): cmd = "df -h /boot | awk 'END {print $1}'" res = self.host_run_command(cmd, console=console) boot_disk = ''.join(res).split("/dev/")[1] boot_disk = boot_disk.replace("\r\n", "") cmd = "ls -l /dev/disk/by-path/ | grep %s | awk '{print $(NF-2)}'" % boot_disk res = self.host_run_command(cmd, console=console) matchObj = re.search(r"\d{4}(?!\d)", '\n'.join(res), re.S) if not matchObj: raise OpTestError("Not able to find out root phb domain") boot_domain = 'PCI' + matchObj.group(0) return boot_domain ## # @brief It will gather kernel dmesg logs and store the copy in a logfile # which will be stored in results dir. # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_gather_kernel_log(self, console=0): try: l_data = '\n'.join(self.host_run_command("dmesg", console=console)) except OpTestError: l_msg = "Failed to gather kernel dmesg log" raise OpTestError(l_msg) if not self.results_dir: log.debug(l_data) return l_res = (time.asctime(time.localtime())).replace(" ", "_") l_logFile = "Kernel_dmesg_log_%s.log" % l_res fn = os.path.join(self.results_dir, l_logFile) log.debug(fn) with open(fn, 'w') as f: f.write(l_data) return BMC_CONST.FW_SUCCESS ## # @brief This function starts opal_errd daemon # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_start_opal_errd_daemon(self, console=0): self.host_run_command("systemctl start opal_errd", console=console) ## # @brief This function stops opal_errd daemon # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_stop_opal_errd_daemon(self, console=0): self.host_run_command("systemctl stop opal_errd", console=console) ## # @brief This function gets the status of opal_errd daemon # # @return True/False: if opal_errd run/not run or throws exception # if not able to get status # def host_get_status_of_opal_errd_daemon(self, console=0): res = self.host_run_command("ps -ef | grep -v grep | grep opal_errd | wc -l", console=console) log.debug(res) if res[0].strip() == "0": log.warning("Opal_errd daemon is not running") return False elif res[0].strip() == "1": log.debug("Opal_errd daemon is running") return True else: raise OpTestError("Not able to get status of opal errd daemon") ## # @brief This function lists all error logs in host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_list_all_errorlogs(self, console=0): self.host_run_command("opal-elog-parse -l", console=console) ## # @brief This function lists all service action logs in host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_list_all_service_action_logs(self, console=0): self.host_run_command("opal-elog-parse -s", console=console) ## # @brief This function gets the number of error logs # # @return res or raise OpTestError # def host_get_number_of_errorlogs(self, console=0): res = self.host_run_command("ls %s | wc -l" % BMC_CONST.OPAL_ELOG_DIR, console=console) log.debug(res) return res ## # @brief This function clears/acknowledges all error logs in host # # @return True on success or raise OpTestError # def host_clear_error_logs(self, console=0): self.host_run_command("rm -f %s/*" % BMC_CONST.OPAL_ELOG_DIR, console=console) res = self.host_run_command("ls %s -1 --color=never" % BMC_CONST.OPAL_ELOG_SYSFS_DIR, console=console) log.debug('\n'.join(res)) for entry in res: entry = entry.strip() if entry == '': continue self.host_run_command("echo 1 > %s/%s/acknowledge" % (BMC_CONST.OPAL_ELOG_SYSFS_DIR, entry), console=console) return True ## # @brief This function clears/acknowledges all dumps in host # # @return True on success or raise OpTestError # def host_clear_all_dumps(self, console=0): self.host_run_command("rm -f %s/*" % BMC_CONST.OPAL_DUMP_DIR, console=console) res = self.host_run_command("ls %s -1 --color=never" % BMC_CONST.OPAL_DUMP_SYSFS_DIR, console=console) for entry in res: entry = entry.strip() if (entry == "initiate_dump") or (entry == ''): continue else: self.host_run_command("echo 1 > %s/%s/acknowledge" % (BMC_CONST.OPAL_DUMP_SYSFS_DIR, entry), console=console) return True # @brief This function disables kdump service # # @param os_level: string output of /etc/os-release # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_disable_kdump_service(self, os_level, console=0): if "Ubuntu" in os_level: self.host_run_command("systemctl stop kdump-tools.service", console=console) try: self.host_run_command("systemctl status kdump-tools.service", console=console) except CommandFailed as cf: if cf.exitcode == 3: pass else: log.debug(str(cf)) raise OpTestError("kdump-tools service is failed to stop") else: self.host_run_command("systemctl stop kdump.service", console=console) try: self.host_run_command("systemctl status kdump.service", console=console) except CommandFailed as cf: if cf.exitcode == 3: pass else: log.debug(str(cf)) raise OpTestError("kdump service is failed to stop") ## # @brief This function disables kdump service # # @param os_level: string output of /etc/os-release # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_enable_kdump_service(self, os_level, console=0): if "Ubuntu" in os_level: self.host_run_command("systemctl stop kdump-tools.service", console=console) self.host_run_command("systemctl start kdump-tools.service", console=console) self.host_run_command("systemctl status kdump-tools.service", console=console) else: self.host_run_command("systemctl stop kdump.service", console=console) self.host_run_command("systemctl start kdump.service", console=console) self.host_run_command("systemctl status kdump.service", console=console) def host_check_sysfs_path_availability(self, path, console=0): res = self.host_run_command("ls --color=never %s" % path, console=console) if "No such file or directory" in res: return False return True def host_check_dt_node_exist(self, node_path, console=0): path = "/proc/device-tree/" + node_path res = self.host_run_command("ls %s" % path, console=console) if "No such file or directory" in res: return False return True def host_get_list_of_chips(self, console=0): res = self.host_run_command("PATH=/usr/local/sbin:$PATH getscom -l", console=console) chips = [] for line in res: matchObj = re.search("(\d{8}).*processor", line) if matchObj: chips.append(matchObj.group(1)) if not chips: raise Exception("Getscom failed to list processor chip ids") chips.sort() log.debug(chips) # ['00000000', '00000001', '00000010'] return chips def host_get_cores(self, console=0): proc_gen = self.host_get_proc_gen(console=console) core_ids = {} cpu_pirs = self.host_run_command("find /sys/devices/system/cpu/*/pir -exec cat {} \;", console=console) for pir in cpu_pirs: if proc_gen in ["POWER8", "POWER8E"]: core_id = hex((int("0x%s" % pir, 16) >> 3 ) & 0xf) chip_id = hex((int("0x%s" % pir, 16) >> 7 ) & 0x3f) elif proc_gen in ["POWER9"]: core_id =hex((int("0x%s" % pir, 16) >> 2 ) & 0x3f) chip_id = hex((int("0x%s" % pir, 16) >> 8 ) & 0x7f) else: raise OpTestError("Unknown or new processor type") core_id = core_id.split('x')[1] chip_id = chip_id.split('x')[1] if chip_id in core_ids: core_ids[chip_id].append(core_id) else: core_ids[chip_id] = [core_id] for i in core_ids: core_ids[i] = list(set(core_ids[i])) core_ids = sorted(core_ids.iteritems()) log.debug(core_ids) return core_ids # Supported on OpenPower and P9 FSP system def host_prd_supported(self, bmc_type, console=0): if not "FSP" in bmc_type: return True proc_gen = self.host_get_proc_gen(console=console) if proc_gen in ["POWER8", "POWER8E"]: return False return True def host_get_proc_gen(self, console=0): try: if self.proc_gen: pass except AttributeError: self.proc_gen = ''.join(self.host_run_command("grep '^cpu' /proc/cpuinfo |uniq|sed -e 's/^.*: //;s/[,]* .*//;'", console=console)) return self.proc_gen def host_get_smt(self, console=0): self.cpu = self.host_get_proc_gen(console=console) if self.cpu in ["POWER8", "POWER8E"]: return 8 elif self.cpu in ["POWER9"]: return 4 else: return 1 def host_get_core_count(self, console=0): res = self.host_run_command("lscpu --all -e| wc -l", console=console) return int(res[0])/(self.host_get_smt(console=console)) def host_gather_debug_logs(self, console=0): self.host_run_command("grep ',[0-4]\]' /sys/firmware/opal/msglog", console=console) self.host_run_command("dmesg -T --level=alert,crit,err,warn", console=console) def host_copy_fake_gard(self): i_image = os.path.join(self.conf.basedir, "test_binaries", "fake.gard") # Copy the fake.gard file to the tmp folder in the host try: self.util.copyFilesToDest(i_image, self.user, self.ip, "/tmp/", self.passwd) except: l_msg = "Copying fake.gard file to host failed" log.error(l_msg) raise OpTestError(l_msg) def copy_test_file_to_host(self, filename): i_image = os.path.join(self.conf.basedir, "test_binaries", filename) try: self.util.copyFilesToDest(i_image, self.user, self.ip, "/tmp/", self.passwd) except subprocess.CalledProcessError as e: l_msg = "Copying %s file to host failed" % filename log.error(l_msg) raise OpTestError(l_msg + str(e)) def copy_files_from_host(self, sourcepath="", destpath="/tmp/"): if sourcepath == "": sourcepath = self.conf.output try: self.util.copyFilesFromDest(self.user, self.ip, destpath, self.passwd, sourcepath) except subprocess.CalledProcessError as e: l_msg = "Copying %s file(s) from host failed" % destpath log.debug(str(e)) log.error(l_msg) raise OpTestError(l_msg + str(e)) def host_pflash_get_partition(self, partition, console=0): d = self.host_run_command("pflash --info", console=console) for line in d: s = re.search(partition, line) if s: m = re.match(r'ID=\d+\s+\S+\s+((0[xX])?[0-9a-fA-F]+)..(0[xX])?[0-9a-fA-F]+\s+\(actual=((0[xX])?[0-9a-fA-F]+)\)\s(\[)?([A-Za-z-]+)?(\])?.*', line) if not m: continue offset = int(m.group(1), 16) length = int(m.group(4), 16) ret = {'offset': offset, 'length': length } flags = m.group(7) if flags: ret['flags'] = [x for x in list(flags) if x != '-'] return ret ## # @brief Check that host has a CAPI FPGA card # # @return True or False # def host_has_capi_fpga_card(self, console=0): l_cmd = "lspci -d \"1014:0477\"" l_res = self.host_run_command(l_cmd, console=console) l_res = " ".join(l_res) if (l_res.__contains__('IBM Device 0477')): l_msg = "Host has a CAPI FPGA card" log.debug(l_msg) return True else: l_msg = "Host has no CAPI FPGA card; skipping test" log.warning(l_msg) return False ## # @brief Clone latest cxl-tests git repository in i_dir directory # # @param i_dir @type string: directory where cxl-tests will be cloned # # @return True or False # def host_clone_cxl_tests(self, i_dir, console=0): l_msg = "https://github.com/ibm-capi/cxl-tests.git" l_cmd = "git clone %s %s" % (l_msg, i_dir) self.host_run_command("git config --global http.sslverify false", console=console) self.host_run_command("rm -rf %s" % i_dir, console=console) self.host_run_command("mkdir %s" % i_dir, console=console) try: l_res = self.host_run_command(l_cmd, console=console) return True except: l_msg = "Cloning cxl-tests git repository is failed" return False def host_build_cxl_tests(self, i_dir, console=0): l_cmd = "cd %s; make" % i_dir self.host_run_command(l_cmd, console=console) l_cmd = "test -x %s/libcxl/libcxl.so" % i_dir self.host_run_command(l_cmd, console=console) l_cmd = "test -x %s/libcxl_tests; echo $?" % i_dir self.host_run_command(l_cmd, console=console) l_cmd = "test -x %s/memcpy_afu_ctx; echo $?" % i_dir self.host_run_command(l_cmd, console=console) def host_check_binary(self, i_dir, i_file, console=0): l_cmd = "test -x %s/%s;" % (i_dir, i_file) try: self.host_run_command(l_cmd, console=console) l_msg = "Executable file %s/%s is available" % (i_dir, i_file) log.debug(l_msg) return True except CommandFailed: l_msg = "Executable file %s/%s is not present" % (i_dir, i_file) log.debug(l_msg) return False
class OpTestHost(): ## # @brief Initialize this object # # @param i_hostip @type string: IP Address of the host # @param i_hostuser @type string: Userid to log into the host # @param i_hostpasswd @type string: Password of the userid to log into the host # @param i_bmcip @type string: IP Address of the bmc # @param i_ffdcDir @type string:specifies the directory under which to save all FFDC data # def __init__(self, i_hostip, i_hostuser, i_hostpasswd, i_bmcip, i_ffdcDir=None): self.ip = i_hostip self.user = i_hostuser self.passwd = i_hostpasswd self.util = OpTestUtil() self.bmcip = i_bmcip self.cv_ffdcDir = i_ffdcDir ## # @brief This method executes the command(i_cmd) on the host using a ssh session # # @param i_cmd: @type string: Command to be executed on host through a ssh session # @return command output if command execution is successful else raises OpTestError # def _ssh_execute(self, i_cmd): l_host = self.ip l_user = self.user l_pwd = self.passwd l_output = '' ssh_ver = '-2' # Flush everything out prior to forking sys.stdout.flush() # Connect the child controlling terminal to a pseudo-terminal try: pid, fd = pty.fork() except OSError as e: # Explicit chain of errors l_msg = "Got OSError attempting to fork a pty session for ssh." raise OpTestError(l_msg) if pid == 0: # In child process. Issue attempt ssh connection to remote host arglist = ('/usr/bin/ssh -o StrictHostKeyChecking=no', l_host, ssh_ver, '-k', '-l', l_user, i_cmd) try: os.execv('/usr/bin/ssh', arglist) except Exception as e: # Explicit chain of errors l_msg = "Can not spawn os.execv for ssh." print l_msg raise OpTestError(l_msg) else: # In parent process # Polling child process for output poll = select.poll() poll.register(fd, select.POLLIN) start_time = time.time() # time.sleep(1) while True: try: evt = poll.poll() x = os.read(fd, 1024) #print "ssh x= " + x end_time = time.time() if(end_time - start_time > 1500): if(i_cmd.__contains__('updlic') or i_cmd.__contains__('update_flash')): continue else: l_msg = "Timeout occured/SSH request " \ "un-responded even after 25 minutes" print l_msg raise OpTestError(l_msg) if(x.__contains__('(yes/no)')): l_res = "yes\r\n" os.write(fd, l_res) if(x.__contains__('s password:'******'' os.write(fd, l_pwd + '\r\n') if(x.__contains__('Password:'******'' os.write(fd, l_pwd + '\r\n') if(x.__contains__('password')): response = l_pwd + "\r\n" os.write(fd, response) if(x.__contains__('yes')): response = '1' + "\r\n" os.write(fd, response) if(x.__contains__('Connection refused')): print x raise OpTestError(x) if(x.__contains__('Received disconnect from')): self.ssh_ver = '-1' if(x.__contains__('Connection closed by')): print (x) raise OpTestError(x) if(x.__contains__("WARNING: POSSIBLE DNS SPOOFING DETECTED")): print (x) raise OpTestError("Its a RSA key problem : \n" + x) if(x.__contains__("WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED")): print (x) raise OpTestError("Its a RSA key problem : \n" + x) if(x.__contains__("Permission denied")): l_msg = "Wrong Login or Password(" + l_user + "/" + l_pwd + ") :" + x print (l_msg) raise OpTestError(l_msg) if(x.__contains__("Rebooting") or \ (x.__contains__("rebooting the system"))): l_output = l_output + x raise OpTestError(l_output) if(x.__contains__("Connection timed out")): l_msg = "Connection timed out/" + \ l_host + " is not pingable" print (x) raise OpTestError(l_msg) if(x.__contains__("could not connect to CLI daemon")): print(x) raise OpTestError("Director server is not up/running(" "Do smstop then smstart to restart)") if((x.__contains__("Error:")) and (i_cmd.__contains__('rmsys'))): print(x) raise OpTestError("Error removing:" + l_host) if((x.__contains__("Bad owner or permissions on /root/.ssh/config"))): print(x) raise OpTestError("Bad owner or permissions on /root/.ssh/config," "Try 'chmod -R 600 /root/.ssh' & retry operation") l_output = l_output + x # time.sleep(1) except OSError: break if l_output.__contains__("Name or service not known"): reason = 'SSH Failed for :' + l_host + \ "\n Please provide a valid Hostname" print reason raise OpTestError(reason) # Gather child process status to freeup zombie and # Close child file descriptor before return if (fd): os.waitpid(pid, 0) os.close(fd) return l_output ## # @brief Get and Record Ubunto OS level # # @return l_oslevel @type string: OS level of the host provided # or raise OpTestError # def host_get_OS_Level(self): l_oslevel = self._ssh_execute(BMC_CONST.BMC_GET_OS_RELEASE) print l_oslevel return l_oslevel ## # @brief Executes a command on the os of the bmc to protect network setting # # @return OpTestError if failed # def host_protect_network_setting(self): try: l_rc = self._ssh_execute(BMC_CONST.OS_PRESERVE_NETWORK) except: l_errmsg = "Can't preserve network setting" print l_errmsg raise OpTestError(l_errmsg) ## # @brief Performs a cold reset onto the host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_cold_reset(self): print ("Applying Cold reset on host.") l_rc = self._ssh_execute(BMC_CONST.HOST_COLD_RESET) # TODO: enable once defect SW331585 is fixed '''if BMC_CONST.BMC_PASS_COLD_RESET in l_rc: print l_rc time.sleep(BMC_CONST.BMC_COLD_RESET_DELAY) return BMC_CONST.FW_SUCCESS else: l_msg = "Cold reset Failed" print l_msg raise OpTestError(l_msg)''' self.util.PingFunc(self.bmcip, BMC_CONST.PING_RETRY_FOR_STABILITY) ## # @brief Flashes image using ipmitool # # @param i_image @type string: hpm file including location # @param i_imagecomponent @type string: component to be # update from the hpm file BMC_CONST.BMC_FW_IMAGE_UPDATE # or BMC_CONST.BMC_PNOR_IMAGE # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_code_update(self, i_image, imagecomponent): # Copy the hpm file to the tmp folder in the host try: self.util.copyFilesToDest(i_image, self.user, self.ip, "/tmp/", self.passwd) except: l_msg = "Copying hpm file to host failed" print l_msg raise OpTestError(l_msg) #self.host_protect_network_setting() #writing to host is not stable l_cmd = "\necho y | ipmitool -I usb " + BMC_CONST.BMC_HPM_UPDATE + "/tmp/" \ + i_image.rsplit("/", 1)[-1] + " " + imagecomponent print l_cmd try: l_rc = self._ssh_execute(l_cmd) print l_rc self._ssh_execute("rm -rf /tmp/" + i_image.rsplit("/", 1)[1]) except subprocess.CalledProcessError: l_msg = "Code Update Failed" print l_msg raise OpTestError(l_msg) if(l_rc.__contains__("Firmware upgrade procedure successful")): return BMC_CONST.FW_SUCCESS else: l_msg = "Code Update Failed" print l_msg raise OpTestError(l_msg) ## # @brief It will run linux command(i_cmd) on host using private interface _ssh_execute() # making this interface is public # # @param i_cmd @type string: linux command # # @return command output if command execution is successful else raises OpTestError # def host_run_command(self, i_cmd): try: l_res = self._ssh_execute(i_cmd) except: l_msg = "Command execution on host failed" print l_msg print sys.exc_info() raise OpTestError(l_msg) print l_res return l_res # @brief It will gather OPAL Message logs and store the copy in a logfile # which will be stored in FFDC dir. # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_gather_opal_msg_log(self): try: l_data = self.host_run_command(BMC_CONST.OPAL_MSG_LOG) except OpTestError: l_msg = "Failed to gather OPAL message logs" raise OpTestError(l_msg) l_res = commands.getstatusoutput("date +%Y%m%d_%H%M") l_logFile = "Opal_msglog_%s.log" % l_res[1] fn = self.cv_ffdcDir + "/" + l_logFile with open(fn, 'w') as f: f.write(l_data) return BMC_CONST.FW_SUCCESS ## # @brief Check if one or more binaries are present on host # # @param i_cmd @type string: binaries to check for # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_check_command(self, *i_cmd): l_cmd = 'which ' + ' '.join(i_cmd) + '; echo $?' print l_cmd l_res = self.host_run_command(l_cmd) l_res = l_res.splitlines() if (int(l_res[-1]) == 0): return BMC_CONST.FW_SUCCESS else: l_msg = "host_check_command: (%s) not present on host. output of '%s': %s" % (','.join(i_cmd), l_cmd, '\n'.join(l_res)) print l_msg raise OpTestError(l_msg) ## # @brief It will get the linux kernel version on host # # @return l_kernel @type string: kernel version of the host provided # or raise OpTestError # def host_get_kernel_version(self): l_kernel = self._ssh_execute("uname -a | awk {'print $3'}") l_kernel = l_kernel.replace("\r\n", "") print l_kernel return l_kernel ## # @brief This function will checks first for config file for a given kernel version on host, # if available then check for config option value and return that value # whether it is y or m...etc. # sample config option values: # CONFIG_CRYPTO_ZLIB=m # CONFIG_CRYPTO_LZO=y # # CONFIG_CRYPTO_842 is not set # # # @param i_kernel @type string: kernel version # @param i_config @type string: Which config option want to check in config file # Ex:CONFIG_SENSORS_IBMPOWERNV # # @return l_val @type string: It will return config option value y or m, # or raise OpTestError if config file is not available on host # or raise OpTestError if config option is not set in file. # def host_check_config(self, i_kernel, i_config): l_file = "/boot/config-%s" % i_kernel l_res = self._ssh_execute("test -e %s; echo $?" % l_file) l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "Config file is available" else: l_msg = "Config file %s is not available on host" % l_file print l_msg raise OpTestError(l_msg) l_cmd = "cat %s | grep -i --color=never %s" % (l_file, i_config) print l_cmd l_res = self._ssh_execute(l_cmd) print l_res try: l_val = ((l_res.split("=")[1]).replace("\r\n", "")) except: print l_val l_msg = "config option is not set,exiting..." print l_msg raise OpTestError(l_msg) return l_val ## # @brief It will return installed package name for given linux command(i_cmd) on host # # @param i_cmd @type string: linux command # @param i_oslevel @type string: OS level # # @return l_pkg @type string: installed package on host # def host_check_pkg_for_utility(self, i_oslevel, i_cmd): if 'Ubuntu' in i_oslevel: l_res = self._ssh_execute("dpkg -S `which %s`" % i_cmd) return l_res else: l_cmd = "rpm -qf `which %s`" % i_cmd l_res = self._ssh_execute(l_cmd) l_pkg = l_res.replace("\r\n", "") print l_pkg return l_pkg ## # @brief It will check whether a package is installed in a host OS # # @param i_oslevel @type string: OS level # @param i_package @type string: package name # # @return BMC_CONST.FW_SUCCESS if package is available # raise OpTestError if package is not available # def host_check_pkg_availability(self, i_oslevel, i_package): if 'Ubuntu' in i_oslevel: l_res = self.host_run_command("dpkg -l %s;echo $?" % i_package) else: l_cmd = "rpm -qa | grep -i %s" % i_package l_res = self.host_run_command(l_cmd) l_res = l_res.splitlines() if (int(l_res[-1]) == 0): return BMC_CONST.FW_SUCCESS else: l_msg = "Package %s is not there in host OS" % i_package raise OpTestError(l_msg) ## # @brief This function loads ibmpowernv driver only on powernv platform # and also this function works only in root user mode # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_ibmpowernv(self, i_oslevel): if "PowerKVM" not in i_oslevel: l_rc = self._ssh_execute("modprobe ibmpowernv; echo $?") l_rc = l_rc.replace("\r\n", "") if int(l_rc) == 0: cmd = "lsmod | grep -i ibmpowernv" response = self._ssh_execute(cmd) if "ibmpowernv" not in response: l_msg = "ibmpowernv module is not loaded, exiting" raise OpTestError(l_msg) else: print "ibmpowernv module is loaded" print cmd print response return BMC_CONST.FW_SUCCESS else: l_msg = "modprobe failed while loading ibmpowernv,exiting..." print l_msg raise OpTestError(l_msg) else: return BMC_CONST.FW_SUCCESS ## # @brief This function restarts the lm_sensors service on host using systemctl utility # systemctl utility is not present in ubuntu, This function will work in remaining all # other OS'es i.e redhat, sles and PowerKVM # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_start_lm_sensor_svc(self, i_oslevel): if 'Ubuntu' in i_oslevel: pass else: try: # Start the lm_sensors service cmd = "/bin/systemctl stop lm_sensors.service" self.host_run_command(cmd) cmd = "/bin/systemctl start lm_sensors.service" self.host_run_command(cmd) cmd = "/bin/systemctl status lm_sensors.service" res = self.host_run_command(cmd) return BMC_CONST.FW_SUCCESS except: l_msg = "loading lm_sensors service failed" print l_msg raise OpTestError(l_msg) ## # @brief It will clone latest linux git repository in i_dir directory # # @param i_dir @type string: directory where linux source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_linux_source(self, i_dir): l_msg = 'git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git' l_cmd = "git clone %s %s" % (l_msg, i_dir) self._ssh_execute("rm -rf %s" % i_dir) self._ssh_execute("mkdir %s" % i_dir) try: print l_cmd res = self._ssh_execute(l_cmd) print res return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning linux git repository is failed" print l_msg raise OpTestError(l_msg) ## # @brief reads msglog for getting Chip and Core information # # @return @type string: Chip and Core information # else raise OpTestError def host_read_msglog_core(self): try: return self._ssh_execute(BMC_CONST.OS_READ_MSGLOG_CORE) except: l_errmsg = "Can't get msglog data" print l_errmsg raise OpTestError(l_errmsg) ## # @brief reads getscom data # example: # Chip ID | Rev | Chip type # ---------|-------|-------- # 80000005 | DD2.0 | Centaur memory buffer # 80000004 | DD2.0 | Centaur memory buffer # 00000000 | DD2.0 | P8 (Venice) processor # # @param i_xscom_dir @type string: directory where getscom is installed # # @return @type string: getscom data # else raise OpTestError def host_read_getscom_data(self, i_xscom_dir): try: l_rc = self._ssh_execute(BMC_CONST.SUDO_COMMAND + i_xscom_dir + BMC_CONST.OS_GETSCOM_LIST) except OpTestError as e: l_errmsg = "Can't get getscom data" print l_errmsg raise OpTestError(l_errmsg) if("command not found" in l_rc): l_errmsg = "Failed to locate getscom. Make sure it is installed in dir: " + i_xscom_dir print l_errmsg raise OpTestError(l_errmsg) return l_rc ## # @brief injects error using getscom # # @param i_xscom_dir @type string: directory where putscom is installed # param i_error @type string: error to be injected including the location # # @return output generated after executing putscom command or else raise OpTestError # def host_putscom(self, i_xscom_dir, i_error): print('Injecting Error.') l_rc = self._execute_no_return(BMC_CONST.SUDO_COMMAND + i_xscom_dir + BMC_CONST.OS_PUTSCOM_ERROR + i_error) ## # @brief Clears the gard records # # @param i_gard_dir @type string: directory where putscom is installed # # @return BMC_CONST.FW_SUCCESS or else raise OpTestError # def host_clear_gard_records(self, i_gard_dir): l_rc = self._ssh_execute(BMC_CONST.SUDO_COMMAND + i_gard_dir + BMC_CONST.CLEAR_GARD_CMD) if(BMC_CONST.GARD_CLEAR_SUCCESSFUL not in l_rc): l_msg = l_rc + '. Failed to clear gard' print l_msg raise OpTestError(l_msg) # Check to make sure no gard records were left l_result = self.host_list_gard_records(i_gard_dir) if(BMC_CONST.NO_GARD_RECORDS not in l_result): l_msg = l_rc + '. Gard records still found after clearing them' print l_msg raise OpTestError(l_msg) return BMC_CONST.FW_SUCCESS ## # @brief Lists all gard records # # @param i_gard_dir @type string: directory where putscom is installed # # @return gard records or else raise OpTestError # def host_list_gard_records(self, i_gard_dir): try: return self._ssh_execute(BMC_CONST.SUDO_COMMAND + i_gard_dir + BMC_CONST.LIST_GARD_CMD) except: l_errmsg = "Can't clear gard records" print l_errmsg raise OpTestError(l_errmsg) ## # @brief Execute a command on the targeted host but don't expect # any return data. # # @param i_cmd: @type str: command to be executed # @param i_timeout: @type int: # # @return BMC_CONST.FW_SUCCESS or else raise OpTestError # def _execute_no_return(self, i_cmd, i_timeout=60): print('Executing command: ' + i_cmd) try: p = pxssh.pxssh() p.login(self.ip, self.user, self.passwd) p.sendline() p.prompt() p.sendline(i_cmd) p.prompt(i_timeout) return BMC_CONST.FW_SUCCESS except: l_msg = "Failed to execute command: " + i_cmd print l_msg raise OpTestError(l_msg) ## # @brief enable/disable cpu states # # @param i_cpu_state @type string: BMC_CONST.CPU_ENABLE_STATE/ # BMC_CONST.CPU_DISABLE_STATE # # @return BMC_CONST.FW_SUCCESS or OpTestError # def host_disable_enable_cpu_states(self, i_cpu_state): try: self._ssh_execute(BMC_CONST.SUDO_COMMAND + "sh -c 'for i in " + \ BMC_CONST.CPU_IDLEMODE_STATE1 + "; do echo " + \ i_cpu_state + " > $i; done'") self._ssh_execute(BMC_CONST.SUDO_COMMAND + "sh -c 'for i in " + \ BMC_CONST.CPU_IDLEMODE_STATE2 + "; do echo " + \ i_cpu_state + " > $i; done'") return BMC_CONST.FW_SUCCESS except: l_errmsg = "Could not enable/disable cpu idle states" print l_errmsg raise OpTestError(l_errmsg) ## # @brief It will get the linux kernel version on host # # @return l_kernel @type string: kernel version of the host provided # or raise OpTestError # def host_get_kernel_version(self): l_kernel = self._ssh_execute("uname -a | awk {'print $3'}") l_kernel = l_kernel.replace("\r\n", "") print l_kernel return l_kernel ## # @brief This function will checks first for config file for a given kernel version on host, # if available then check for config option value and return that value # whether it is y or m...etc. # sample config option values: # CONFIG_CRYPTO_ZLIB=m # CONFIG_CRYPTO_LZO=y # # CONFIG_CRYPTO_842 is not set # # # @param i_kernel @type string: kernel version # @param i_config @type string: Which config option want to check in config file # Ex:CONFIG_SENSORS_IBMPOWERNV # # @return l_val @type string: It will return config option value y or m, # or raise OpTestError if config file is not available on host # or raise OpTestError if config option is not set in file. # def host_check_config(self, i_kernel, i_config): l_file = "/boot/config-%s" % i_kernel l_res = self._ssh_execute("test -e %s; echo $?" % l_file) l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "Config file is available" else: l_msg = "Config file %s is not available on host" % l_file print l_msg raise OpTestError(l_msg) l_cmd = "cat %s | grep -i --color=never %s" % (l_file, i_config) print l_cmd l_res = self._ssh_execute(l_cmd) print l_res try: l_val = ((l_res.split("=")[1]).replace("\r\n", "")) except: print l_val l_msg = "config option is not set,exiting..." print l_msg raise OpTestError(l_msg) return l_val ## # @brief It will return installed package name for given linux command(i_cmd) on host # # @param i_cmd @type string: linux command # @param i_oslevel @type string: OS level # # @return l_pkg @type string: installed package on host # def host_check_pkg_for_utility(self, i_oslevel, i_cmd): if 'Ubuntu' in i_oslevel: l_res = self._ssh_execute("dpkg -S `which %s`" % i_cmd) return l_res else: l_cmd = "rpm -qf `which %s`" % i_cmd l_res = self._ssh_execute(l_cmd) l_pkg = l_res.replace("\r\n", "") print l_pkg return l_pkg ## # @brief This function loads ibmpowernv driver only on powernv platform # and also this function works only in root user mode # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_ibmpowernv(self, i_oslevel): if "PowerKVM" not in i_oslevel: l_rc = self._ssh_execute("modprobe ibmpowernv; echo $?") l_rc = l_rc.replace("\r\n", "") if int(l_rc) == 0: cmd = "lsmod | grep -i ibmpowernv" response = self._ssh_execute(cmd) if "ibmpowernv" not in response: l_msg = "ibmpowernv module is not loaded, exiting" raise OpTestError(l_msg) else: print "ibmpowernv module is loaded" print cmd print response return BMC_CONST.FW_SUCCESS else: l_msg = "modprobe failed while loading ibmpowernv,exiting..." print l_msg raise OpTestError(l_msg) else: return BMC_CONST.FW_SUCCESS ## # @brief This function restarts the lm_sensors service on host using systemctl utility # systemctl utility is not present in ubuntu, This function will work in remaining all # other OS'es i.e redhat, sles and PowerKVM # # @param i_oslevel @type string: OS level # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_start_lm_sensor_svc(self, i_oslevel): if 'Ubuntu' in i_oslevel: pass else: try: # Start the lm_sensors service cmd = "/bin/systemctl stop lm_sensors.service" self.host_run_command(cmd) cmd = "/bin/systemctl start lm_sensors.service" self.host_run_command(cmd) cmd = "/bin/systemctl status lm_sensors.service" res = self.host_run_command(cmd) return BMC_CONST.FW_SUCCESS except: l_msg = "loading lm_sensors service failed" print l_msg raise OpTestError(l_msg) ## # @brief It will clone latest linux git repository in i_dir directory # # @param i_dir @type string: directory where linux source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_linux_source(self, i_dir): l_msg = 'git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git' l_cmd = "git clone %s %s" % (l_msg, i_dir) self._ssh_execute("rm -rf %s" % i_dir) self._ssh_execute("mkdir %s" % i_dir) try: print l_cmd res = self._ssh_execute(l_cmd) print res return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning linux git repository is failed" print l_msg raise OpTestError(l_msg) ## # @brief It will load the module using modprobe and verify whether it is loaded or not # # @param i_module @type string: module name, which we want to load on host # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_module(self, i_module): l_res = self.host_run_command("modprobe %s; echo $?" % i_module) l_res = l_res.splitlines() if int(l_res[-1]) == 0: pass else: l_msg = "Error in loading the module %s, modprobe failed" % i_module print l_msg raise OpTestError(l_msg) l_res = self.host_run_command("lsmod | grep -i --color=never %s" % i_module) if l_res.__contains__(i_module): print "%s module is loaded" % i_module return BMC_CONST.FW_SUCCESS else: l_msg = " %s module is not loaded" % i_module print l_msg raise OpTestError(l_msg) ## # @brief This function will read real time clock(RTC) time using hwclock utility # # @return l_res @type string: return hwclock value if command execution successfull # else raise OpTestError # def host_read_hwclock(self): print "Reading the hwclock" l_res = self.host_run_command("hwclock -r;echo $?") l_res = l_res.splitlines() if int(l_res[-1]) == 0: return l_res else: l_msg = "Reading the hwclock failed" print l_msg raise OpTestError(l_msg) ## # @brief This function will read system time using date utility (This will be mantained by kernel) # # @return l_res @type string: return system time value if command execution successfull # else raise OpTestError # def host_read_systime(self): print "Reading system time using date utility" l_res = self.host_run_command("date;echo $?") l_res = l_res.splitlines() if int(l_res[-1]) == 0: return l_res else: l_msg = "Reading the system time failed" print l_msg raise OpTestError(l_msg) ## # @brief This function will set hwclock time using the --date option # format should be "2015-01-01 12:12:12" # # @param i_time @type string: this is the time for setting the hwclock # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_set_hwclock_time(self, i_time): print "Setting the hwclock time to %s" % i_time l_res = self.host_run_command("hwclock --set --date \'%s\';echo $?" % i_time) l_res = l_res.splitlines() if int(l_res[-1]) == 0: return BMC_CONST.FW_SUCCESS else: l_msg = "Setting the hwclock failed" print l_msg raise OpTestError(l_msg) ## # @brief This function will load driver module on host based on the config option # if config value m: built as a module # y: driver built into kernel itself # else raises OpTestError # # @param i_kernel @type string: kernel version to get config file # i_config @type string: config option to check in config file # i_module @type string: driver module to load on host based on config value # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_module_based_on_config(self, i_kernel, i_config, i_module): l_val = self.host_check_config(i_kernel, i_config) if l_val == 'm': self.host_load_module(i_module) elif l_val == 'y': print "Driver built into kernel itself" else: l_msg = "Config value is changed" print l_msg raise OpTestError(l_msg) return BMC_CONST.FW_SUCCESS ## # @brief This function will return the list of installed i2c buses on host in two formats # list-by number Ex: ["0","1","2",....] # list-by-name Ex: ["i2c-0","i2c-1","i2c-2"....] # # @return l_list @type list: list of i2c buses by number # l_list1 @type list: list of i2c buses by name # or raise OpTestError if not able to get list of i2c buses # def host_get_list_of_i2c_buses(self): l_res = self.host_run_command("i2cdetect -l;echo $?") l_res = l_res.splitlines() if int(l_res[-1]) == 0: pass else: l_msg = "Not able to get list of i2c buses" print l_msg raise OpTestError(l_msg) l_res = self.host_run_command("i2cdetect -l | awk '{print $1}'") l_res = l_res.splitlines() # list by number Ex: ["0","1","2",....] l_list = [] # list by name Ex: ["i2c-0","i2c-1"...] l_list1 = [] for l_bus in l_res: matchObj = re.search("(i2c)-(\d{1,})", l_bus) if matchObj: l_list.append(matchObj.group(2)) l_list1.append(l_bus) else: pass return l_list, l_list1 ## # @brief This function will get information of EEPROM chips attached to the i2c buses # # @return l_res @type string: return EEPROM chips information # else raise OpTestError # def host_get_info_of_eeprom_chips(self): print "Getting the information of EEPROM chips" l_res = self.host_run_command("dmesg | grep -i --color=never at24") if l_res.__contains__("at24"): pass else: l_res = self.host_run_command("dmesg -C") self.host_run_command("rmmod at24") self.host_load_module("at24") l_res = self.host_run_command("dmesg | grep -i --color=never at24") if l_res.__contains__("at24"): pass else: l_msg = "Not able to get at24 info" raise OpTestError(l_msg) return l_res ## # @brief It will return list with elements having pairs of eeprom chip addresses and # corresponding i2c bus where the chip is attached. This information is getting # through sysfs interface. format is ["0 0x50","0 0x51","1 0x51","1 0x52"....] # # @return l_chips @type list: list having pairs of i2c bus number and eeprom chip address. # else raise OpTestError # def host_get_list_of_eeprom_chips(self): l_res = self.host_run_command("find /sys/ -name eeprom;echo $?") l_res = l_res.splitlines() if int(l_res[-1]) == 0: pass else: l_msg = "Not able to get list of eeprom chip addresses through sysfs interface" print l_msg raise OpTestError(l_msg) l_chips = [] for l_line in l_res: if l_line.__contains__("eeprom"): matchObj = re.search("/(\d{1,}-\d{4})/eeprom", l_line) if matchObj: l_line = matchObj.group(1) i_args = (l_line.replace("-", " ")) print i_args else: continue i_args = re.sub(" 00", " 0x", i_args) l_chips.append(i_args) print i_args return l_chips ## # @brief The hexdump utility is used to display the specified files. # This function will display in both ASCII+hexadecimal format. # # @param i_dev @type string: this is the file used as a input to hexdump for display info # Example file:"/sys/devices/platform/3fc0000000000.xscom:i2cm@a0000:i2c-bus@1/i2c-3/3-0050/eeprom" # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # # def host_hexdump(self, i_dev): l_res = self.host_run_command("hexdump -C %s;echo $?" % i_dev) l_res = l_res.splitlines() if int(l_res[-1]) == 0: return BMC_CONST.FW_SUCCESS else: l_msg = "hexdump failed for device %s" % i_dev print l_msg raise OpTestError(l_msg) ## # @brief It will clone latest skiboot git repository in i_dir directory # # @param i_dir @type string: directory where skiboot source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_skiboot_source(self, i_dir): l_msg = 'https://github.com/open-power/skiboot.git/' l_cmd = "git clone %s %s" % (l_msg, i_dir) self.host_run_command("git config --global http.sslverify false") self.host_run_command("rm -rf %s" % i_dir) self.host_run_command("mkdir %s" % i_dir) try: print l_cmd l_res = self.host_run_command(l_cmd) print l_res return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning skiboot git repository is failed" print l_msg raise OpTestError(l_msg) ## # @brief It will compile xscom-utils in the skiboot directory which was cloned in i_dir directory # # @param i_dir @type string: directory where skiboot source was cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_compile_xscom_utilities(self, i_dir): l_cmd = "cd %s/external/xscom-utils; make;" % i_dir print l_cmd l_res = self.host_run_command(l_cmd) l_cmd = "test -f %s/external/xscom-utils/getscom; echo $?" % i_dir l_res = self.host_run_command(l_cmd) l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "Executable binary getscom is available" else: l_msg = "getscom bin file is not present after make" print l_msg raise OpTestError(l_msg) l_cmd = "test -f %s/external/xscom-utils/putscom; echo $?" % i_dir l_res = self.host_run_command(l_cmd) l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "Executable binary putscom is available" return BMC_CONST.FW_SUCCESS else: l_msg = "putscom bin file is not present after make" print l_msg raise OpTestError(l_msg) ## # @brief It will compile gard utility in the skiboot directory which was cloned in i_dir directory # # @param i_dir @type string: directory where skiboot source was cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_compile_gard_utility(self, i_dir): l_cmd = "cd %s/external/gard; make;" % i_dir print l_cmd l_res = self.host_run_command(l_cmd) l_cmd = "test -f %s/external/gard/gard; echo $?" % i_dir l_res = self.host_run_command(l_cmd) l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "Executable binary gard is available" return BMC_CONST.FW_SUCCESS else: l_msg = "gard bin file is not present after make" print l_msg raise OpTestError(l_msg) ## # @brief This function generates olog.json file from skiboot which is used for # fwts olog test: Run OLOG scan and analysis checks. # # @param i_dir @type string: directory where skiboot source was cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_generate_fwts_olog_json(self, i_dir): l_cmd = "%s/external/fwts/generate-fwts-olog %s/ -o %s/olog.json" % (i_dir, i_dir, i_dir) print l_cmd l_res = self.host_run_command(l_cmd) l_cmd = "test -f %s/olog.json; echo $?" % i_dir l_res = self.host_run_command(l_cmd) l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "olog.json is available in working directory %s" % i_dir return BMC_CONST.FW_SUCCESS else: l_msg = "olog.json file is failed to create from skiboot" print l_msg raise OpTestError(l_msg) ## # @brief It will clone latest fwts git repository in i_dir directory # # @param i_dir @type string: directory where fwts source will be cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_clone_fwts_source(self, i_dir): l_msg = 'git://kernel.ubuntu.com/hwe/fwts.git' l_cmd = "git clone %s %s" % (l_msg, i_dir) self.host_run_command("git config --global http.sslverify false") self.host_run_command("rm -rf %s" % i_dir) self.host_run_command("mkdir %s" % i_dir) try: print l_cmd l_res = self.host_run_command(l_cmd) print l_res return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning fwts git repository is failed" print l_msg raise OpTestError(l_msg) ## # @brief This function is used to build fwts tool in the fwts directory # which was cloned in i_dir directory # # @param i_dir @type string: directory where fwts source was cloned # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_build_fwts_tool(self, i_dir): l_cmd = "cd %s/;autoreconf -ivf;./configure; make;" % i_dir print l_cmd l_res = self.host_run_command(l_cmd) l_cmd = "test -f %s/src/fwts; echo $?" % i_dir l_res = self.host_run_command(l_cmd) print l_res l_res = l_res.replace("\r\n", "") if int(l_res) == 0: print "Executable binary fwts is available" return BMC_CONST.FW_SUCCESS else: l_msg = "fwts bin file is not present after make" print l_msg raise OpTestError(l_msg) ## # @brief This function is used to get detected pci devices in different user/machine readable formats # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_list_pci_devices(self): self.host_run_command(BMC_CONST.HOST_LIST_PCI_DEVICES1) self.host_run_command(BMC_CONST.HOST_LIST_PCI_DEVICES2) self.host_run_command(BMC_CONST.HOST_LIST_PCI_DEVICES3) self.host_run_command(BMC_CONST.HOST_LIST_PCI_DEVICES4) self.host_run_command(BMC_CONST.HOST_LIST_PCI_DEVICES5) self.host_run_command(BMC_CONST.HOST_LIST_PCI_DEVICES6) self.host_run_command(BMC_CONST.HOST_LIST_PCI_SYSFS_DEVICES) ## # @brief This function is used to get more pci devices info in verbose mode # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_get_pci_verbose_info(self): l_res = self.host_run_command(BMC_CONST.HOST_LIST_PCI_VERBOSE) return l_res ## # @brief This function is used to get minimum usb devices info # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_list_usb_devices(self): self.host_run_command(BMC_CONST.HOST_LIST_USB_DEVICES1) self.host_run_command(BMC_CONST.HOST_LIST_USB_DEVICES2) self.host_run_command(BMC_CONST.HOST_LIST_USB_DEVICES3) ## # @brief This function enable only a single core # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_enable_single_core(self): self.host_run_command("ppc64_cpu --cores-on=1")
class OpTestLpar(): ## # @brief Initialize this object # # @param i_lparip @type string: IP Address of the lpar # @param i_lparuser @type string: Userid to log into the lpar # @param i_lparpasswd @type string: Password of the userid to log into the lpar # def __init__(self, i_lparip, i_lparuser, i_lparpasswd): self.ip = i_lparip self.user = i_lparuser self.passwd = i_lparpasswd self.util = OpTestUtil() ## # @brief This method executes the command(i_cmd) on the host using a ssh session # # @param i_cmd: @type string: Command to be executed on host through a ssh session # @return command output if command execution is successful else raises OpTestError # def _ssh_execute(self, i_cmd): l_host = self.ip l_user = self.user l_pwd = self.passwd l_output = '' ssh_ver = '-2' self.util.PingFunc(l_host, BMC_CONST.PING_RETRY_FOR_STABILITY) # Flush everything out prior to forking sys.stdout.flush() # Connect the child controlling terminal to a pseudo-terminal try: pid, fd = pty.fork() except OSError as e: # Explicit chain of errors l_msg = "Got OSError attempting to fork a pty session for ssh." raise OpTestError(l_msg) if pid == 0: # In child process. Issue attempt ssh connection to remote host arglist = ('/usr/bin/ssh -o StrictHostKeyChecking=no', l_host, ssh_ver, '-k', '-l', l_user, i_cmd) try: os.execv('/usr/bin/ssh', arglist) except Exception as e: # Explicit chain of errors l_msg = "Can not spawn os.execv for ssh." print l_msg raise OpTestError(l_msg) else: # In parent process # Polling child process for output poll = select.poll() poll.register(fd, select.POLLIN) start_time = time.time() # time.sleep(1) while True: try: evt = poll.poll() x = os.read(fd, 1024) #print "ssh x= " + x end_time = time.time() if(end_time - start_time > 1500): if(i_cmd.__contains__('updlic') or i_cmd.__contains__('update_flash')): continue else: l_msg = "Timeout occured/SSH request " \ "un-responded even after 25 minutes" print l_msg raise OpTestError(l_msg) if(x.__contains__('(yes/no)')): l_res = "yes\r\n" os.write(fd, l_res) if(x.__contains__('s password:'******'' os.write(fd, l_pwd + '\r\n') if(x.__contains__('Password:'******'' os.write(fd, l_pwd + '\r\n') if(x.__contains__('password')): response = l_pwd + "\r\n" os.write(fd, response) if(x.__contains__('yes')): response = '1' + "\r\n" os.write(fd, response) if(x.__contains__('Connection refused')): print x raise OpTestError(x) if(x.__contains__('Received disconnect from')): self.ssh_ver = '-1' if(x.__contains__('Connection closed by')): print (x) raise OpTestError(x) if(x.__contains__("WARNING: POSSIBLE DNS SPOOFING DETECTED")): print (x) raise OpTestError("Its a RSA key problem : \n" + x) if(x.__contains__("WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED")): print (x) raise OpTestError("Its a RSA key problem : \n" + x) if(x.__contains__("Permission denied")): l_msg = "Wrong Login or Password(" + l_user + "/" + l_pwd + ") :" + x print (l_msg) raise OpTestError(l_msg) if(x.__contains__("Rebooting") or \ (x.__contains__("rebooting the system"))): l_output = l_output + x raise OpTestError(l_output) if(x.__contains__("Connection timed out")): l_msg = "Connection timed out/" + \ l_host + " is not pingable" print (x) raise OpTestError(l_msg) if(x.__contains__("could not connect to CLI daemon")): print(x) raise OpTestError("Director server is not up/running(" "Do smstop then smstart to restart)") if((x.__contains__("Error:")) and (i_cmd.__contains__('rmsys'))): print(x) raise OpTestError("Error removing:" + l_host) if((x.__contains__("Bad owner or permissions on /root/.ssh/config"))): print(x) raise OpTestError("Bad owner or permissions on /root/.ssh/config," "Try 'chmod -R 600 /root/.ssh' & retry operation") l_output = l_output + x # time.sleep(1) except OSError: break if l_output.__contains__("Name or service not known"): reason = 'SSH Failed for :' + l_host + \ "\n Please provide a valid Hostname" print reason raise OpTestError(reason) # Gather child process status to freeup zombie and # Close child file descriptor before return if (fd): os.waitpid(pid, 0) os.close(fd) return l_output ## # @brief Get and Record Ubunto OS level # # @return l_oslevel @type string: OS level of the partition provided # or raise OpTestError # def lpar_get_OS_Level(self): l_oslevel = self._ssh_execute(BMC_CONST.BMC_GET_OS_RELEASE) print l_oslevel return l_oslevel ## # @brief Executes a command on the os of the bmc to protect network setting # # @return OpTestError if failed # def lpar_protect_network_setting(self): try: l_rc = self._ssh_execute(BMC_CONST.OS_PRESERVE_NETWORK) except: l_errmsg = "Can't preserve network setting" print l_errmsg raise OpTestError(l_errmsg) ## # @brief Performs a cold reset onto the lpar # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def lpar_cold_reset(self): # TODO: cold reset command to os is not too stable l_cmd = BMC_CONST.LPAR_COLD_RESET print ("Applying Cold reset. Wait for " + str(BMC_CONST.BMC_COLD_RESET_DELAY) + "sec") l_rc = self._ssh_execute(l_cmd) if BMC_CONST.BMC_PASS_COLD_RESET in l_rc: print l_rc time.sleep(BMC_CONST.BMC_COLD_RESET_DELAY) return BMC_CONST.FW_SUCCESS else: l_msg = "Cold reset Failed" print l_msg raise OpTestError(l_msg) ## # @brief Flashes image using ipmitool # # @param i_image @type string: hpm file including location # @param i_imagecomponent @type string: component to be # update from the hpm file BMC_CONST.BMC_FW_IMAGE_UPDATE # or BMC_CONST.BMC_PNOR_IMAGE # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def lpar_code_update(self, i_image, imagecomponent): # Copy the hpm file to the tmp folder in the partition try: self.util.copyFilesToDest(i_image, self.user, self.ip, "/tmp/", self.passwd) except: l_msg = "Copying hpm file to lpar failed" print l_msg raise OpTestError(l_msg) #self.lpar_protect_network_setting() #writing to partition is not stable l_cmd = "\necho y | ipmitool -I usb " + BMC_CONST.BMC_HPM_UPDATE + "/tmp/" \ + i_image.rsplit("/", 1)[-1] + imagecomponent print l_cmd try: l_rc = self._ssh_execute(l_cmd) print l_rc except subprocess.CalledProcessError: l_msg = "Code Update Failed" print l_msg raise OpTestError(l_msg) if(l_rc.__contains__("Firmware upgrade procedure successful")): return BMC_CONST.FW_SUCCESS else: l_msg = "Code Update Failed" print l_msg raise OpTestError(l_msg)
class OpTestLpar(): ## # @brief Initialize this object # # @param i_lparip @type string: IP Address of the lpar # @param i_lparuser @type string: Userid to log into the lpar # @param i_lparpasswd @type string: Password of the userid to log into the lpar # def __init__(self, i_lparip, i_lparuser, i_lparpasswd): self.ip = i_lparip self.user = i_lparuser self.passwd = i_lparpasswd self.util = OpTestUtil() ## # @brief This method executes the command(i_cmd) on the host using a ssh session # # @param i_cmd: @type string: Command to be executed on host through a ssh session # @return command output if command execution is successful else raises OpTestError # def _ssh_execute(self, i_cmd): l_host = self.ip l_user = self.user l_pwd = self.passwd l_output = '' ssh_ver = '-2' self.util.PingFunc(l_host, BMC_CONST.PING_RETRY_FOR_STABILITY) # Flush everything out prior to forking sys.stdout.flush() # Connect the child controlling terminal to a pseudo-terminal try: pid, fd = pty.fork() except OSError as e: # Explicit chain of errors l_msg = "Got OSError attempting to fork a pty session for ssh." raise OpTestError(l_msg) if pid == 0: # In child process. Issue attempt ssh connection to remote host arglist = ('/usr/bin/ssh -o StrictHostKeyChecking=no', l_host, ssh_ver, '-k', '-l', l_user, i_cmd) try: os.execv('/usr/bin/ssh', arglist) except Exception as e: # Explicit chain of errors l_msg = "Can not spawn os.execv for ssh." print l_msg raise OpTestError(l_msg) else: # In parent process # Polling child process for output poll = select.poll() poll.register(fd, select.POLLIN) start_time = time.time() # time.sleep(1) while True: try: evt = poll.poll() x = os.read(fd, 1024) #print "ssh x= " + x end_time = time.time() if (end_time - start_time > 1500): if (i_cmd.__contains__('updlic') or i_cmd.__contains__('update_flash')): continue else: l_msg = "Timeout occured/SSH request " \ "un-responded even after 25 minutes" print l_msg raise OpTestError(l_msg) if (x.__contains__('(yes/no)')): l_res = "yes\r\n" os.write(fd, l_res) if (x.__contains__('s password:'******'' os.write(fd, l_pwd + '\r\n') if (x.__contains__('Password:'******'' os.write(fd, l_pwd + '\r\n') if (x.__contains__('password')): response = l_pwd + "\r\n" os.write(fd, response) if (x.__contains__('yes')): response = '1' + "\r\n" os.write(fd, response) if (x.__contains__('Connection refused')): print x raise OpTestError(x) if (x.__contains__('Received disconnect from')): self.ssh_ver = '-1' if (x.__contains__('Connection closed by')): print(x) raise OpTestError(x) if (x.__contains__( "WARNING: POSSIBLE DNS SPOOFING DETECTED")): print(x) raise OpTestError("Its a RSA key problem : \n" + x) if (x.__contains__( "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED") ): print(x) raise OpTestError("Its a RSA key problem : \n" + x) if (x.__contains__("Permission denied")): l_msg = "Wrong Login or Password(" + l_user + "/" + l_pwd + ") :" + x print(l_msg) raise OpTestError(l_msg) if(x.__contains__("Rebooting") or \ (x.__contains__("rebooting the system"))): l_output = l_output + x raise OpTestError(l_output) if (x.__contains__("Connection timed out")): l_msg = "Connection timed out/" + \ l_host + " is not pingable" print(x) raise OpTestError(l_msg) if (x.__contains__("could not connect to CLI daemon")): print(x) raise OpTestError("Director server is not up/running(" "Do smstop then smstart to restart)") if ((x.__contains__("Error:")) and (i_cmd.__contains__('rmsys'))): print(x) raise OpTestError("Error removing:" + l_host) if ((x.__contains__( "Bad owner or permissions on /root/.ssh/config"))): print(x) raise OpTestError( "Bad owner or permissions on /root/.ssh/config," "Try 'chmod -R 600 /root/.ssh' & retry operation") l_output = l_output + x # time.sleep(1) except OSError: break if l_output.__contains__("Name or service not known"): reason = 'SSH Failed for :' + l_host + \ "\n Please provide a valid Hostname" print reason raise OpTestError(reason) # Gather child process status to freeup zombie and # Close child file descriptor before return if (fd): os.waitpid(pid, 0) os.close(fd) return l_output ## # @brief Get and Record Ubunto OS level # # @return l_oslevel @type string: OS level of the partition provided # or raise OpTestError # def lpar_get_OS_Level(self): l_oslevel = self._ssh_execute(BMC_CONST.BMC_GET_OS_RELEASE) print l_oslevel return l_oslevel ## # @brief Executes a command on the os of the bmc to protect network setting # # @return OpTestError if failed # def lpar_protect_network_setting(self): try: l_rc = self._ssh_execute(BMC_CONST.OS_PRESERVE_NETWORK) except: l_errmsg = "Can't preserve network setting" print l_errmsg raise OpTestError(l_errmsg) ## # @brief Performs a cold reset onto the lpar # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def lpar_cold_reset(self): # TODO: cold reset command to os is not too stable l_cmd = BMC_CONST.LPAR_COLD_RESET print("Applying Cold reset. Wait for " + str(BMC_CONST.BMC_COLD_RESET_DELAY) + "sec") l_rc = self._ssh_execute(l_cmd) if BMC_CONST.BMC_PASS_COLD_RESET in l_rc: print l_rc time.sleep(BMC_CONST.BMC_COLD_RESET_DELAY) return BMC_CONST.FW_SUCCESS else: l_msg = "Cold reset Failed" print l_msg raise OpTestError(l_msg) ## # @brief Flashes image using ipmitool # # @param i_image @type string: hpm file including location # @param i_imagecomponent @type string: component to be # update from the hpm file BMC_CONST.BMC_FW_IMAGE_UPDATE # or BMC_CONST.BMC_PNOR_IMAGE # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def lpar_code_update(self, i_image, imagecomponent): # Copy the hpm file to the tmp folder in the partition try: self.util.copyFilesToDest(i_image, self.user, self.ip, "/tmp/", self.passwd) except: l_msg = "Copying hpm file to lpar failed" print l_msg raise OpTestError(l_msg) #self.lpar_protect_network_setting() #writing to partition is not stable l_cmd = "\necho y | ipmitool -I usb " + BMC_CONST.BMC_HPM_UPDATE + "/tmp/" \ + i_image.rsplit("/", 1)[-1] + imagecomponent print l_cmd try: l_rc = self._ssh_execute(l_cmd) print l_rc except subprocess.CalledProcessError: l_msg = "Code Update Failed" print l_msg raise OpTestError(l_msg) if (l_rc.__contains__("Firmware upgrade procedure successful")): return BMC_CONST.FW_SUCCESS else: l_msg = "Code Update Failed" print l_msg raise OpTestError(l_msg)
class OpTestHost(): ''' An object to manipulate and run things on the host. ''' def __init__(self, i_hostip, i_hostuser, i_hostpasswd, i_bmcip, i_results_dir, scratch_disk="", proxy="", logfile=sys.stdout, check_ssh_keys=False, known_hosts_file=None): self.ip = i_hostip self.user = i_hostuser self.passwd = i_hostpasswd self.util = OpTestUtil() self.bmcip = i_bmcip self.results_dir = i_results_dir self.logfile = logfile self.ssh = OpTestSSH(i_hostip, i_hostuser, i_hostpasswd, logfile=self.logfile, check_ssh_keys=check_ssh_keys, known_hosts_file=known_hosts_file) self.scratch_disk = scratch_disk self.proxy = proxy self.scratch_disk_size = None self.conf = OpTestConfiguration.conf self.check_ssh_keys = check_ssh_keys self.known_hosts_file = known_hosts_file def hostname(self): return self.ip def username(self): return self.user def password(self): return self.passwd def set_system(self, system): self.ssh.set_system(system) def get_scratch_disk(self): return self.scratch_disk def get_scratch_disk_size(self, console=None): if self.scratch_disk_size is not None: return self.scratch_disk_size if console is None: raise Exception("You need to call get_scratch_disk_size() with a console first") dev_sdX = console.run_command("readlink -f %s" % self.get_scratch_disk()) dev_sdX = dev_sdX[0].replace("/dev/","") scratch_disk_size = console.run_command("cat /sys/block/%s/size" % dev_sdX) # Use the (undocumented) /size sysfs property of nr 512byte sectors self.scratch_disk_size = int(scratch_disk_size[0])*512 def get_proxy(self): return self.proxy def get_ssh_connection(self): return self.ssh def get_new_ssh_connection(self, name="temp"): #time.sleep(1) outsuffix = time.strftime("%Y%m%d%H%M%S") filename = "%s-%s.log" % (outsuffix, name) logfile = os.path.join(self.results_dir,filename) print "Log file: %s" % logfile logcmd = "tee %s" % (logfile) logcmd = logcmd + "| sed -u -e 's/\\r$//g'|cat -v" print "logcmd: %s" % logcmd logfile_proc = subprocess.Popen(logcmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) print repr(logfile_proc) logfile = logfile_proc.stdin print "Log file: %s" % logfile OpTestLogger.optest_logger_glob.setUpCustomLoggerDebugFile(name, filename) ssh = OpTestSSH(self.ip, self.user, self.passwd, logfile=logfile, check_ssh_keys=self.check_ssh_keys, known_hosts_file=self.known_hosts_file, use_parent_logger=False) ssh.set_system(self.conf.op_system) return ssh def host_get_OS_Level(self, console=0): ''' Get the OS version. ''' l_oslevel = self.host_run_command("cat /etc/os-release", timeout=60, console=console) return '\n'.join(l_oslevel) def host_cold_reset(self): ''' Cold reboot the host ''' log.debug(("Applying Cold reset on host.")) l_rc = self.ssh.run_command(BMC_CONST.HOST_COLD_RESET, timeout=60) self.util.PingFunc(self.bmcip, totalSleepTime=BMC_CONST.PING_RETRY_FOR_STABILITY) def host_code_update(self, i_image, imagecomponent): ''' Flash firmware (HPM image) using ipmitool. i_image hpm file i_imagecomponent component to be updated from the HPM file. Probably BMC_CONST.BMC_FW_IMAGE_UPDATE or BMC_CONST.BMC_PNOR_IMAGE ''' # Copy the hpm file to the tmp folder in the host try: self.util.copyFilesToDest(i_image, self.user, self.ip, "/tmp/", self.passwd) except: l_msg = "Copying hpm file to host failed" log.warning(l_msg) raise OpTestError(l_msg) l_cmd = "\necho y | ipmitool -I usb " + BMC_CONST.BMC_HPM_UPDATE + "/tmp/" \ + i_image.rsplit("/", 1)[-1] + " " + imagecomponent log.debug(l_cmd) try: l_rc = self.ssh.run_command(l_cmd, timeout=1500) log.debug(l_rc) self.ssh.run_command("rm -rf /tmp/" + i_image.rsplit("/", 1)[1],timeout=120) except subprocess.CalledProcessError: l_msg = "Code Update Failed" log.warning(l_msg) raise OpTestError(l_msg) if(l_rc.__contains__("Firmware upgrade procedure successful")): return BMC_CONST.FW_SUCCESS else: l_msg = "Code Update Failed" log.warning(l_msg) raise OpTestError(l_msg) def host_run_command(self, i_cmd, timeout=1500, retry=0, console=0): # if we are QEMU use the system console if isinstance(self.ssh.system.console, OpTestQemu.QemuConsole) or (console == 1): return self.ssh.system.console.run_command(i_cmd, timeout, retry) else: return self.ssh.run_command(i_cmd, timeout, retry) def host_gather_opal_msg_log(self, console=0): ''' Gather OPAL logs (from the host) and store in a file ''' try: l_data = '\n'.join(self.host_run_command(BMC_CONST.OPAL_MSG_LOG, console=console)) except OpTestError: l_msg = "Failed to gather OPAL message logs" raise OpTestError(l_msg) if not self.results_dir: log.debug(l_data) return l_res = (time.asctime(time.localtime())).replace(" ", "_") l_logFile = "Opal_msglog_%s.log" % l_res fn = os.path.join(self.results_dir, l_logFile) log.debug(fn) with open(fn, 'w') as f: f.write(l_data) def host_check_command(self, *i_cmd, **kwargs): ''' Check if one or more binaries are present on host ''' default_vals = {'console': 0} for key in default_vals: if key not in kwargs.keys(): kwargs[key] = default_vals[key] l_cmd = 'which ' + ' '.join(i_cmd) log.debug(l_cmd) try: l_res = self.host_run_command(l_cmd, console=kwargs['console']) except CommandFailed as c: l_msg = "host_check_command: (%s) not present on host. output of '%s': %s" % (','.join(i_cmd), l_cmd, '\n'.join(c.output)) log.error(l_msg) raise OpTestError(l_msg) return True def host_get_kernel_version(self, console=0): ''' Get Linux kernel version running on the host (using uname). ''' l_kernel = self.host_run_command("uname -a | awk {'print $3'}", timeout=60, console=0) l_kernel = ''.join(l_kernel) log.debug(l_kernel) return l_kernel def host_check_config(self, i_kernel, i_config, console=0): ''' This function will checks first for config file for a given kernel version on host, if available then check for config option value and return that value whether it is y or m...etc. sample config option values: :: CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=y # CONFIG_CRYPTO_842 is not set i_kernel kernel version i_config Which config option want to check in config file. e.g. `CONFIG_SENSORS_IBMPOWERNV` It will return config option value y or m, or raise OpTestError if config file is not available on host or raise OpTestError if config option is not set in file. ''' l_file = "/boot/config-%s" % i_kernel try: l_res = self.host_run_command("test -e %s" % l_file, timeout=60, console=console) except CommandFailed: raise NoKernelConfig(i_kernel, l_file) log.debug("Config file is available") l_cmd = "cat %s | grep -i --color=never %s" % (l_file, i_config) l_res = self.host_run_command(l_cmd, timeout=60, console=console) log.debug(l_res) config_opts = {} for o in l_res: m = re.match('# (.*) is not set', o) if m: config_opts[m.group(0)]='n' else: if '=' in o: opt, val = o.split("=") config_opts[opt] = val if config_opts.get(i_config) not in ["y","m"]: raise KernelConfigNotSet(i_config) return config_opts[i_config] def host_check_pkg_for_utility(self, i_oslevel, i_cmd, console=0): ''' Check if a package is installed on the host. The `i_oslevel` is used to determine if we should use `dpkg` or `rpm` to search for the package name. ''' if 'Ubuntu' in i_oslevel: return ''.join(self.host_run_command("dpkg -S `which %s`" % i_cmd, timeout=60, console=console)) else: l_cmd = "rpm -qf `which %s`" % i_cmd return ''.join(self.host_run_command(l_cmd, timeout=60, console=console)) def host_load_ibmpowernv(self, i_oslevel): ''' This function loads ibmpowernv driver only on powernv platform and also this function works only in root user mode ''' if "PowerKVM" not in i_oslevel: o = self.ssh.run_command("modprobe ibmpowernv",timeout=60) cmd = "lsmod | grep -i ibmpowernv" response = self.ssh.run_command(cmd, timeout=60) if "ibmpowernv" not in ''.join(response): l_msg = "ibmpowernv module is not loaded, exiting" raise OpTestError(l_msg) else: log.debug("ibmpowernv module is loaded") log.debug(cmd) log.debug(response) return BMC_CONST.FW_SUCCESS def host_start_lm_sensor_svc(self, i_oslevel, console=0): ''' This function restarts the lm_sensors service on host using systemctl utility systemctl utility is not present in ubuntu, This function will work in remaining all other OS'es i.e redhat, sles and PowerKVM ''' if 'Ubuntu' in i_oslevel: pass else: try: # Start the lm_sensors service cmd = "/bin/systemctl stop lm_sensors.service" self.host_run_command(cmd, console=console) cmd = "/bin/systemctl start lm_sensors.service" self.host_run_command(cmd, console=console) cmd = "/bin/systemctl status lm_sensors.service" res = self.host_run_command(cmd, console=console) return BMC_CONST.FW_SUCCESS except: l_msg = "loading lm_sensors service failed" log.error(l_msg) raise OpTestError(l_msg) def host_clone_linux_source(self, i_dir): ''' It will clone latest linux git repository in i_dir directory. i_dir directory where linux source will be cloned. ''' l_msg = 'git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git' l_cmd = "git clone --depth=1 %s %s" % (l_msg, i_dir) self.ssh.run_command("rm -rf %s" % i_dir, timeout=300) self.ssh.run_command("mkdir %s" % i_dir, timeout=60) try: log.debug(l_cmd) res = self.ssh.run_command(l_cmd, timeout=1500) log.debug(res) return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning linux git repository is failed" log.error(l_msg) raise OpTestError(l_msg) def host_load_module(self, i_module, console=0): ''' It will load the module using modprobe and verify whether it is loaded or not ''' try: l_res = self.host_run_command("modprobe %s" % i_module, console=console) except CommandFailed as c: l_msg = "Error in loading the module %s, modprobe failed: %s" % (i_module,str(c)) raise OpTestError(l_msg) l_res = self.host_run_command("lsmod | grep -i --color=never %s" % i_module, console=console) if re.search(i_module, ''.join(l_res)): log.debug("%s module is loaded" % i_module) return BMC_CONST.FW_SUCCESS else: raise KernelModuleNotLoaded(i_module) def host_read_hwclock(self, console=0): ''' This function will read real time clock(RTC) time using hwclock utility. ''' log.debug("Reading the hwclock") self.host_run_command("hwclock -r;echo $?", console=console) def host_read_systime(self, console=0): ''' This function will read system time using date utility (This will be mantained by kernel). ''' log.debug("Reading system time using date utility") l_res = self.host_run_command("date", console=console) return l_res def host_set_hwclock_time(self, i_time, console=0): ''' This function will set hwclock time using the --date option format should be "2015-01-01 12:12:12" ''' log.debug("Setting the hwclock time to %s" % i_time) self.host_run_command("hwclock --set --date \'%s\'" % i_time, console=console) ## # # @return BMC_CONST.FW_SUCCESS or raise OpTestError # def host_load_module_based_on_config(self, i_kernel, i_config, i_module, console=0): ''' This function will load driver module on host based on the config option if config value m built as a module y driver built into kernel itself else raises OpTestError i_kernel kernel version to get config file i_config config option to check in config file i_module driver module to load on host based on config value ''' l_val = self.host_check_config(i_kernel, i_config, console=console) if l_val == 'm': self.host_load_module(i_module, console=console) elif l_val == 'y': log.debug("Driver built into kernel itself") elif l_val == 'n': raise KernelConfigNotSet(i_config) def host_clone_skiboot_source(self, i_dir, console=0): ''' It will clone latest skiboot git repository in i_dir directory i_dir directory where skiboot source will be cloned ''' l_msg = 'https://github.com/open-power/skiboot.git/' l_cmd = "git clone %s %s" % (l_msg, i_dir) self.host_run_command("git config --global http.sslverify false", console=console) self.host_run_command("rm -rf %s" % i_dir, console=console) self.host_run_command("mkdir %s" % i_dir, console=console) try: log.debug(l_cmd) l_res = self.host_run_command(l_cmd, console=console) log.debug(l_res) return BMC_CONST.FW_SUCCESS except: l_msg = "Cloning skiboot git repository is failed" log.debug(l_msg) raise OpTestError(l_msg) def host_enable_single_core(self, console=0): ''' This function enable only a single core ''' self.host_run_command("ppc64_cpu --cores-on=1", console=console) def host_enable_all_cores(self, console=0): ''' Enables all cores ''' self.host_run_command("ppc64_cpu --cores-on=all", console=console) def host_get_list_of_pci_domains(self, console=0): ''' This function is used to get list of PCI PHB domains. ''' self.pci_domains = [] self.host_run_command("lspci -mm", console=console) res = self.host_run_command('lspci -mm | cut -d":" -f1 | sort | uniq', console=console) for domain in res: if not domain: continue if len(domain) != 4: domain = ''.join(("00", domain)) domain = 'PCI' + domain if not self.pci_domains.__contains__(domain): self.pci_domains.append(domain) log.debug(self.pci_domains) return self.pci_domains def host_get_root_phb(self, console=0): ''' This function is used to get the PHB domain of root port where the filesystem is mounted(We need to skip this in EEH tests as recovery will fail on this domain is expected) ''' cmd = "df -h /boot | awk 'END {print $1}'" res = self.host_run_command(cmd, console=console) boot_disk = ''.join(res).split("/dev/")[1] boot_disk = boot_disk.replace("\r\n", "") cmd = "ls -l /dev/disk/by-path/ | grep %s | awk '{print $(NF-2)}'" % boot_disk res = self.host_run_command(cmd, console=console) matchObj = re.search(r"\d{4}(?!\d)", '\n'.join(res), re.S) if not matchObj: raise OpTestError("Not able to find out root phb domain") boot_domain = 'PCI' + matchObj.group(0) return boot_domain def host_gather_kernel_log(self, console=0): ''' It will gather kernel dmesg logs and store the copy in a logfile which will be stored in results dir. ''' try: l_data = '\n'.join(self.host_run_command("dmesg", console=console)) except OpTestError: l_msg = "Failed to gather kernel dmesg log" raise OpTestError(l_msg) if not self.results_dir: log.debug(l_data) return l_res = (time.asctime(time.localtime())).replace(" ", "_") l_logFile = "Kernel_dmesg_log_%s.log" % l_res fn = os.path.join(self.results_dir, l_logFile) log.debug(fn) with open(fn, 'w') as f: f.write(l_data) return BMC_CONST.FW_SUCCESS def host_start_opal_errd_daemon(self, console=0): ''' starts opal_errd daemon ''' self.host_run_command("systemctl start opal_errd", console=console) def host_stop_opal_errd_daemon(self, console=0): ''' stops opal_errd daemon ''' self.host_run_command("systemctl stop opal_errd", console=console) def host_get_status_of_opal_errd_daemon(self, console=0): ''' This function gets the status of opal_errd daemon. Raises an exception if not running. ''' res = self.host_run_command("ps -ef | grep -v grep | grep opal_errd | wc -l", console=console) log.debug(res) if res[0].strip() == "0": log.warning("Opal_errd daemon is not running") return False elif res[0].strip() == "1": log.debug("Opal_errd daemon is running") return True else: raise OpTestError("Not able to get status of opal errd daemon") def host_list_all_errorlogs(self, console=0): ''' This function lists all error logs in host ''' self.host_run_command("opal-elog-parse -l", console=console) def host_list_all_service_action_logs(self, console=0): ''' This function lists all service action logs in host. ''' self.host_run_command("opal-elog-parse -s", console=console) def host_get_number_of_errorlogs(self, console=0): ''' This function gets the number of error logs ''' res = self.host_run_command("ls %s | wc -l" % BMC_CONST.OPAL_ELOG_DIR, console=console) log.debug(res) return res def host_clear_error_logs(self, console=0): ''' This function clears/acknowledges all error logs in host ''' self.host_run_command("rm -f %s/*" % BMC_CONST.OPAL_ELOG_DIR, console=console) res = self.host_run_command("ls %s -1 --color=never" % BMC_CONST.OPAL_ELOG_SYSFS_DIR, console=console) log.debug('\n'.join(res)) for entry in res: entry = entry.strip() if entry == '': continue self.host_run_command("echo 1 > %s/%s/acknowledge" % (BMC_CONST.OPAL_ELOG_SYSFS_DIR, entry), console=console) return True def host_clear_all_dumps(self, console=0): ''' This function clears/acknowledges all dumps in host. ''' self.host_run_command("rm -f %s/*" % BMC_CONST.OPAL_DUMP_DIR, console=console) res = self.host_run_command("ls %s -1 --color=never" % BMC_CONST.OPAL_DUMP_SYSFS_DIR, console=console) for entry in res: entry = entry.strip() if (entry == "initiate_dump") or (entry == ''): continue else: self.host_run_command("echo 1 > %s/%s/acknowledge" % (BMC_CONST.OPAL_DUMP_SYSFS_DIR, entry), console=console) return True def host_disable_kdump_service(self, os_level, console=0): ''' This function disables kdump service. Needs the OS version (from `/etc/os-release`) to know if we should use systemd commands or not. ''' if "Ubuntu" in os_level: self.host_run_command("systemctl stop kdump-tools.service", console=console) try: self.host_run_command("systemctl status kdump-tools.service", console=console) except CommandFailed as cf: if cf.exitcode == 3: pass else: log.debug(str(cf)) raise OpTestError("kdump-tools service is failed to stop") else: self.host_run_command("systemctl stop kdump.service", console=console) try: self.host_run_command("systemctl status kdump.service", console=console) except CommandFailed as cf: if cf.exitcode == 3: pass else: log.debug(str(cf)) raise OpTestError("kdump service is failed to stop") def host_enable_kdump_service(self, os_level, console=0): ''' disables kdump service, needs `/etc/os-release` to work out service name. ''' if "Ubuntu" in os_level: self.host_run_command("systemctl stop kdump-tools.service", console=console) self.host_run_command("systemctl start kdump-tools.service", console=console) self.host_run_command("systemctl status kdump-tools.service", console=console) else: self.host_run_command("systemctl stop kdump.service", console=console) self.host_run_command("systemctl start kdump.service", console=console) self.host_run_command("systemctl status kdump.service", console=console) def host_check_sysfs_path_availability(self, path, console=0): res = self.host_run_command("ls --color=never %s" % path, console=console) if "No such file or directory" in res: return False return True def host_check_dt_node_exist(self, node_path, console=0): path = "/proc/device-tree/" + node_path res = self.host_run_command("ls %s" % path, console=console) if "No such file or directory" in res: return False return True def host_get_list_of_chips(self, console=0): res = self.host_run_command("PATH=/usr/local/sbin:$PATH getscom -l", console=console) chips = [] for line in res: matchObj = re.search("(\d{8}).*processor", line) if matchObj: chips.append(matchObj.group(1)) if not chips: raise Exception("Getscom failed to list processor chip ids") chips.sort() log.debug(chips) # ['00000000', '00000001', '00000010'] return chips def host_get_cores(self, console=0): proc_gen = self.host_get_proc_gen(console=console) core_ids = {} cpu_pirs = self.host_run_command("find /sys/devices/system/cpu/*/pir -exec cat {} \;", console=console) for pir in cpu_pirs: if proc_gen in ["POWER8", "POWER8E"]: core_id = hex((int("0x%s" % pir, 16) >> 3 ) & 0xf) chip_id = hex((int("0x%s" % pir, 16) >> 7 ) & 0x3f) elif proc_gen in ["POWER9"]: core_id =hex((int("0x%s" % pir, 16) >> 2 ) & 0x3f) chip_id = hex((int("0x%s" % pir, 16) >> 8 ) & 0x7f) else: raise OpTestError("Unknown or new processor type") core_id = core_id.split('x')[1] chip_id = chip_id.split('x')[1] if chip_id in core_ids: core_ids[chip_id].append(core_id) else: core_ids[chip_id] = [core_id] for i in core_ids: core_ids[i] = list(set(core_ids[i])) core_ids = sorted(core_ids.iteritems()) log.debug(core_ids) return core_ids # Supported on OpenPower and P9 FSP system def host_prd_supported(self, bmc_type, console=0): if not "FSP" in bmc_type: return True proc_gen = self.host_get_proc_gen(console=console) if proc_gen in ["POWER8", "POWER8E"]: return False return True def host_get_proc_gen(self, console=0): try: if self.proc_gen: pass except AttributeError: self.proc_gen = ''.join(self.host_run_command("grep '^cpu' /proc/cpuinfo |uniq|sed -e 's/^.*: //;s/[,]* .*//;'", console=console)) return self.proc_gen def host_get_smt(self, console=0): self.cpu = self.host_get_proc_gen(console=console) if self.cpu in ["POWER8", "POWER8E"]: return 8 elif self.cpu in ["POWER9"]: return 4 else: return 1 def host_get_core_count(self, console=0): res = self.host_run_command("lscpu --all -e| wc -l", console=console) return int(res[0])/(self.host_get_smt(console=console)) def host_gather_debug_logs(self, console=0): self.host_run_command("grep ',[0-4]\]' /sys/firmware/opal/msglog", console=console) self.host_run_command("dmesg -T --level=alert,crit,err,warn", console=console) def host_copy_fake_gard(self): i_image = os.path.join(self.conf.basedir, "test_binaries", "fake.gard") # Copy the fake.gard file to the tmp folder in the host try: self.util.copyFilesToDest(i_image, self.user, self.ip, "/tmp/", self.passwd) except: l_msg = "Copying fake.gard file to host failed" log.error(l_msg) raise OpTestError(l_msg) def copy_test_file_to_host(self, filename, sourcedir="test_binaries", dstdir="/tmp/"): i_image = os.path.join(self.conf.basedir, sourcedir, filename) try: self.util.copyFilesToDest(i_image, self.user, self.ip, dstdir, self.passwd) except subprocess.CalledProcessError as e: l_msg = "Copying %s file to host failed" % filename log.error(l_msg) raise OpTestError(l_msg + str(e)) def copy_files_from_host(self, sourcepath="", destpath="/tmp/"): if sourcepath == "": sourcepath = self.conf.output try: self.util.copyFilesFromDest(self.user, self.ip, destpath, self.passwd, sourcepath) except subprocess.CalledProcessError as e: l_msg = "Copying %s file(s) from host failed" % destpath log.debug(str(e)) log.error(l_msg) raise OpTestError(l_msg + str(e)) def host_pflash_get_partition(self, partition, console=0): d = self.host_run_command("pflash --info", console=console) for line in d: s = re.search(partition, line) if s: m = re.match(r'ID=\d+\s+\S+\s+((0[xX])?[0-9a-fA-F]+)..(0[xX])?[0-9a-fA-F]+\s+\(actual=((0[xX])?[0-9a-fA-F]+)\)\s(\[)?([A-Za-z-]+)?(\])?.*', line) if not m: continue offset = int(m.group(1), 16) length = int(m.group(4), 16) ret = {'offset': offset, 'length': length } flags = m.group(7) if flags: ret['flags'] = [x for x in list(flags) if x != '-'] return ret def host_has_capi_fpga_card(self, console=0): ''' Check that host has a CAPI FPGA card ''' l_cmd = "lspci -d \"1014::1200\"" l_res = self.host_run_command(l_cmd, console=console) l_res = " ".join(l_res) if (l_res.__contains__('IBM Device')): l_msg = "Host has a CAPI FPGA card" log.debug(l_msg) return True else: l_msg = "Host has no CAPI FPGA card; skipping test" log.warning(l_msg) return False def host_clone_cxl_tests(self, i_dir, console=0): ''' Clone latest cxl-tests git repository in i_dir directory. i_dir directory where cxl-tests will be cloned ''' l_msg = "https://github.com/ibm-capi/cxl-tests.git" l_cmd = "git clone %s %s" % (l_msg, i_dir) self.host_run_command("git config --global http.sslverify false", console=console) self.host_run_command("rm -rf %s" % i_dir, console=console) self.host_run_command("mkdir %s" % i_dir, console=console) try: l_res = self.host_run_command(l_cmd, console=console) return True except: l_msg = "Cloning cxl-tests git repository is failed" return False def host_build_cxl_tests(self, i_dir, console=0): l_cmd = "cd %s; make" % i_dir self.host_run_command(l_cmd, console=console) l_cmd = "test -x %s/libcxl/libcxl.so" % i_dir self.host_run_command(l_cmd, console=console) l_cmd = "test -x %s/libcxl_tests; echo $?" % i_dir self.host_run_command(l_cmd, console=console) l_cmd = "test -x %s/memcpy_afu_ctx; echo $?" % i_dir self.host_run_command(l_cmd, console=console) def host_check_binary(self, i_dir, i_file, console=0): l_cmd = "test -x %s/%s;" % (i_dir, i_file) try: self.host_run_command(l_cmd, console=console) l_msg = "Executable file %s/%s is available" % (i_dir, i_file) log.debug(l_msg) return True except CommandFailed: l_msg = "Executable file %s/%s is not present" % (i_dir, i_file) log.debug(l_msg) return False