|  | #!/usr/bin/env python | 
|  |  | 
|  | r""" | 
|  | This module is the python counterpart to openbmc_ffdc.robot.. | 
|  | """ | 
|  |  | 
|  | import os | 
|  |  | 
|  | import gen_print as gp | 
|  | import gen_valid as gv | 
|  | import gen_robot_keyword as grk | 
|  | import state as st | 
|  |  | 
|  | from robot.libraries.BuiltIn import BuiltIn | 
|  |  | 
|  |  | 
|  | def ffdc(ffdc_dir_path=None, | 
|  | ffdc_prefix=None, | 
|  | ffdc_function_list=""): | 
|  | r""" | 
|  | Gather First Failure Data Capture (FFDC). | 
|  |  | 
|  | This includes: | 
|  | - Set global FFDC_TIME. | 
|  | - Create FFDC work space directory. | 
|  | - Write test info details. | 
|  | - Call BMC methods to write/collect FFDC data. | 
|  |  | 
|  | Description of arguments: | 
|  | ffdc_dir_path       The dir path where FFDC data should be put. | 
|  | ffdc_prefix         The prefix to be given to each FFDC file name | 
|  | generated. | 
|  | ffdc_function_list  A colon-delimited list of all the types of FFDC data | 
|  | you wish to have collected.  A blank value means that | 
|  | all possible kinds of FFDC are to be collected.  See | 
|  | FFDC_METHOD_CALL object in lib/openbmc_ffdc_list.py | 
|  | for possible choices. | 
|  | """ | 
|  |  | 
|  | ffdc_file_list = [] | 
|  |  | 
|  | # Check if Ping and SSH connection is alive | 
|  | OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}") | 
|  |  | 
|  | state = st.get_state(req_states=['ping', 'uptime', 'rest']) | 
|  | gp.qprint_var(state) | 
|  | if not int(state['ping']): | 
|  | gp.print_error("BMC is not ping-able.  Terminating FFDC collection.\n") | 
|  | return ffdc_file_list | 
|  |  | 
|  | if not int(state['rest']): | 
|  | gp.print_error("REST commands to the BMC are failing." | 
|  | + "  Terminating FFDC collection.\n") | 
|  | return ffdc_file_list | 
|  |  | 
|  | if state['uptime'] == "": | 
|  | gp.print_error("BMC is not communicating via ssh.  Terminating FFDC" | 
|  | + " collection.\n") | 
|  | return ffdc_file_list | 
|  |  | 
|  | gp.qprint_timen("Collecting FFDC.") | 
|  |  | 
|  | # Get default values for arguments. | 
|  | ffdc_dir_path, ffdc_prefix = set_ffdc_defaults(ffdc_dir_path, ffdc_prefix) | 
|  | gp.qprint_var(ffdc_dir_path) | 
|  | gp.qprint_var(ffdc_prefix) | 
|  |  | 
|  | # LOG_PREFIX is used by subordinate functions. | 
|  | LOG_PREFIX = ffdc_dir_path + ffdc_prefix | 
|  | BuiltIn().set_global_variable("${LOG_PREFIX}", LOG_PREFIX) | 
|  |  | 
|  | cmd_buf = ["Create Directory", ffdc_dir_path] | 
|  | gp.qprint_issuing(cmd_buf) | 
|  | status, output = BuiltIn().run_keyword_and_ignore_error(*cmd_buf) | 
|  | if status != "PASS": | 
|  | error_message = gp.sprint_error_report("Create Directory failed" | 
|  | + " with the following" | 
|  | + " error:\n" + output) | 
|  | BuiltIn().fail(error_message) | 
|  |  | 
|  | # FFDC_FILE_PATH is used by Header Message. | 
|  | FFDC_FILE_PATH = ffdc_dir_path + ffdc_prefix + "BMC_general.txt" | 
|  | BuiltIn().set_global_variable("${FFDC_FILE_PATH}", FFDC_FILE_PATH) | 
|  |  | 
|  | status, ffdc_file_list = grk.run_key("Header Message") | 
|  | status, ffdc_file_sub_list = \ | 
|  | grk.run_key_u("Call FFDC Methods  ffdc_function_list=" | 
|  | + ffdc_function_list) | 
|  |  | 
|  | # Combine lists, remove duplicates and sort. | 
|  | ffdc_file_list = sorted(set(ffdc_file_list + ffdc_file_sub_list)) | 
|  |  | 
|  | gp.qprint_timen("Finished collecting FFDC.") | 
|  |  | 
|  | return ffdc_file_list | 
|  |  | 
|  |  | 
|  | def set_ffdc_defaults(ffdc_dir_path=None, | 
|  | ffdc_prefix=None): | 
|  | r""" | 
|  | Set a default value for ffdc_dir_path and ffdc_prefix if they don't | 
|  | already have values.  Return both values. | 
|  |  | 
|  | Description of arguments: | 
|  | ffdc_dir_path  The dir path where FFDC data should be put. | 
|  | ffdc_prefix    The prefix to be given to each FFDC file name generated. | 
|  |  | 
|  | NOTE: If global variable ffdc_dir_path_style is set to ${1}, this function | 
|  | will create default values in a newer way.  Otherwise, its behavior | 
|  | will remain unchanged. | 
|  | """ | 
|  |  | 
|  | # Note: Several subordinate functions like 'Get Test Dir and Name' and | 
|  | # 'Header Message' expect global variable FFDC_TIME to be set. | 
|  | cmd_buf = ["Get Current Time Stamp"] | 
|  | gp.dprint_issuing(cmd_buf) | 
|  | FFDC_TIME = BuiltIn().run_keyword(*cmd_buf) | 
|  | BuiltIn().set_global_variable("${FFDC_TIME}", FFDC_TIME) | 
|  |  | 
|  | ffdc_dir_path_style = BuiltIn().get_variable_value( | 
|  | "${ffdc_dir_path_style}") | 
|  |  | 
|  | if ffdc_dir_path is None: | 
|  | if ffdc_dir_path_style: | 
|  | try: | 
|  | ffdc_dir_path = os.environ['FFDC_DIR_PATH'] | 
|  | except KeyError: | 
|  | ffdc_dir_path = os.path.dirname( | 
|  | BuiltIn().get_variable_value("${LOG_FILE}")) + "/" | 
|  | else: | 
|  | FFDC_LOG_PATH = os.getcwd() + "/logs/" | 
|  | if FFDC_LOG_PATH is None: | 
|  | FFDC_LOG_PATH = "" | 
|  | if FFDC_LOG_PATH == "": | 
|  | FFDC_LOG_PATH = os.path.dirname( | 
|  | BuiltIn().get_variable_value("${LOG_FILE}")) + "/" | 
|  | error_message = gv.svalid_value(FFDC_LOG_PATH, | 
|  | var_name="FFDC_LOG_PATH") | 
|  | if error_message != "": | 
|  | error_message = gp.sprint_error_report(error_message) | 
|  | BuiltIn().fail(error_message) | 
|  | FFDC_LOG_PATH = os.path.normpath(FFDC_LOG_PATH) + os.sep | 
|  |  | 
|  | cmd_buf = ["Get Test Dir and Name"] | 
|  | gp.print_issuing(cmd_buf) | 
|  | suitename, testname = BuiltIn().run_keyword(*cmd_buf) | 
|  |  | 
|  | ffdc_dir_path = FFDC_LOG_PATH + suitename + "/" + testname + "/" | 
|  |  | 
|  | # Add trailing slash. | 
|  | ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep | 
|  |  | 
|  | if ffdc_prefix is None: | 
|  | FFDC_TIME = BuiltIn().get_variable_value("${FFDC_TIME}") | 
|  | if ffdc_prefix is None: | 
|  | if ffdc_dir_path_style: | 
|  | OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}") | 
|  | OPENBMC_NICKNAME = BuiltIn().get_variable_value( | 
|  | "${OPENBMC_NICKNAME}", default=OPENBMC_HOST) | 
|  | ffdc_prefix = OPENBMC_NICKNAME + "." + FFDC_TIME[2:8] + "." +\ | 
|  | FFDC_TIME[8:14] + "." | 
|  | else: | 
|  | ffdc_prefix = FFDC_TIME + "_" | 
|  |  | 
|  | BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path) | 
|  | BuiltIn().set_global_variable("${FFDC_PREFIX}", ffdc_prefix) | 
|  |  | 
|  | return ffdc_dir_path, ffdc_prefix |