1#!/usr/bin/env python 2 3r""" 4This module is the python counterpart to openbmc_ffdc.robot.. 5""" 6 7import os 8 9import gen_print as gp 10import gen_robot_print as grp 11import gen_valid as gv 12import gen_robot_keyword as grk 13import state as st 14 15from robot.libraries.BuiltIn import BuiltIn 16 17 18def ffdc(ffdc_dir_path=None, 19 ffdc_prefix=None, 20 ffdc_function_list=""): 21 r""" 22 Gather First Failure Data Capture (FFDC). 23 24 This includes: 25 - Set global FFDC_TIME. 26 - Create FFDC work space directory. 27 - Write test info details. 28 - Call BMC methods to write/collect FFDC data. 29 30 Description of arguments: 31 ffdc_dir_path The dir path where FFDC data should be put. 32 ffdc_prefix The prefix to be given to each FFDC file name 33 generated. 34 ffdc_function_list A colon-delimited list of all the types of FFDC data 35 you wish to have collected. A blank value means that 36 all possible kinds of FFDC are to be collected. See 37 FFDC_METHOD_CALL object in lib/openbmc_ffdc_list.py 38 for possible choices. 39 """ 40 41 ffdc_file_list = [] 42 43 # Check if Ping and SSH connection is alive 44 OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}") 45 46 state = st.get_state(req_states=['ping', 'uptime']) 47 gp.qprint_var(state) 48 if not int(state['ping']): 49 gp.print_error("BMC is not ping-able. Terminating FFDC collection.\n") 50 return ffdc_file_list 51 52 if state['uptime'] == "": 53 gp.print_error("BMC is not communicating. Terminating FFDC" 54 + " collection.\n") 55 return ffdc_file_list 56 57 gp.qprint_timen("Collecting FFDC.") 58 59 # Get default values for arguments. 60 ffdc_dir_path, ffdc_prefix = set_ffdc_defaults(ffdc_dir_path, ffdc_prefix) 61 gp.qprint_var(ffdc_dir_path) 62 gp.qprint_var(ffdc_prefix) 63 64 # LOG_PREFIX is used by subordinate functions. 65 LOG_PREFIX = ffdc_dir_path + ffdc_prefix 66 BuiltIn().set_global_variable("${LOG_PREFIX}", LOG_PREFIX) 67 68 cmd_buf = ["Create Directory", ffdc_dir_path] 69 grp.rqpissuing_keyword(cmd_buf) 70 status, output = BuiltIn().run_keyword_and_ignore_error(*cmd_buf) 71 if status != "PASS": 72 error_message = grp.sprint_error_report("Create Directory failed" 73 + " with the following" 74 + " error:\n" + output) 75 BuiltIn().fail(error_message) 76 77 # FFDC_FILE_PATH is used by Header Message. 78 FFDC_FILE_PATH = ffdc_dir_path + ffdc_prefix + "BMC_general.txt" 79 BuiltIn().set_global_variable("${FFDC_FILE_PATH}", FFDC_FILE_PATH) 80 81 status, ffdc_file_list = grk.run_key("Header Message") 82 status, ffdc_file_sub_list = \ 83 grk.run_key_u("Call FFDC Methods ffdc_function_list=" 84 + ffdc_function_list) 85 86 # Combine lists, remove duplicates and sort. 87 ffdc_file_list = sorted(set(ffdc_file_list + ffdc_file_sub_list)) 88 89 gp.qprint_timen("Finished collecting FFDC.") 90 91 return ffdc_file_list 92 93 94def set_ffdc_defaults(ffdc_dir_path=None, 95 ffdc_prefix=None): 96 r""" 97 Set a default value for ffdc_dir_path and ffdc_prefix if they don't 98 already have values. Return both values. 99 100 Description of arguments: 101 ffdc_dir_path The dir path where FFDC data should be put. 102 ffdc_prefix The prefix to be given to each FFDC file name generated. 103 104 NOTE: If global variable ffdc_dir_path_style is set to ${1}, this function 105 will create default values in a newer way. Otherwise, its behavior 106 will remain unchanged. 107 """ 108 109 # Note: Several subordinate functions like 'Get Test Dir and Name' and 110 # 'Header Message' expect global variable FFDC_TIME to be set. 111 cmd_buf = ["Get Current Time Stamp"] 112 grp.rdpissuing_keyword(cmd_buf) 113 FFDC_TIME = BuiltIn().run_keyword(*cmd_buf) 114 BuiltIn().set_global_variable("${FFDC_TIME}", FFDC_TIME) 115 116 ffdc_dir_path_style = BuiltIn().get_variable_value( 117 "${ffdc_dir_path_style}") 118 119 if ffdc_dir_path is None: 120 if ffdc_dir_path_style: 121 try: 122 ffdc_dir_path = os.environ['FFDC_DIR_PATH'] 123 except KeyError: 124 ffdc_dir_path = os.path.dirname( 125 BuiltIn().get_variable_value("${LOG_FILE}")) + "/" 126 else: 127 FFDC_LOG_PATH = os.getcwd() + "/logs/" 128 if FFDC_LOG_PATH is None: 129 FFDC_LOG_PATH = "" 130 if FFDC_LOG_PATH == "": 131 FFDC_LOG_PATH = os.path.dirname( 132 BuiltIn().get_variable_value("${LOG_FILE}")) + "/" 133 error_message = gv.svalid_value(FFDC_LOG_PATH, 134 var_name="FFDC_LOG_PATH") 135 if error_message != "": 136 error_message = grp.sprint_error_report(error_message) 137 BuiltIn().fail(error_message) 138 FFDC_LOG_PATH = os.path.normpath(FFDC_LOG_PATH) + os.sep 139 140 cmd_buf = ["Get Test Dir and Name"] 141 grp.rpissuing_keyword(cmd_buf) 142 suitename, testname = BuiltIn().run_keyword(*cmd_buf) 143 144 ffdc_dir_path = FFDC_LOG_PATH + suitename + "/" + testname + "/" 145 146 # Add trailing slash. 147 ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep 148 149 if ffdc_prefix is None: 150 FFDC_TIME = BuiltIn().get_variable_value("${FFDC_TIME}") 151 if ffdc_prefix is None: 152 if ffdc_dir_path_style: 153 OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}") 154 OPENBMC_NICKNAME = BuiltIn().get_variable_value( 155 "${OPENBMC_NICKNAME}", default=OPENBMC_HOST) 156 ffdc_prefix = OPENBMC_NICKNAME + "." + FFDC_TIME[2:8] + "." +\ 157 FFDC_TIME[8:14] + "." 158 else: 159 ffdc_prefix = FFDC_TIME + "_" 160 161 BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path) 162 BuiltIn().set_global_variable("${FFDC_PREFIX}", ffdc_prefix) 163 164 return ffdc_dir_path, ffdc_prefix 165