| George Keishing | e7e9171 | 2021-09-03 11:28:44 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python3 | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 2 |  | 
|  | 3 | r""" | 
|  | 4 | This module is the python counterpart to openbmc_ffdc.robot.. | 
|  | 5 | """ | 
|  | 6 |  | 
|  | 7 | import os | 
|  | 8 |  | 
| Michael Walsh | e4a093d | 2017-10-30 15:03:18 -0500 | [diff] [blame] | 9 | import gen_print as gp | 
| George Keishing | e635ddc | 2022-12-08 07:38:02 -0600 | [diff] [blame] | 10 | import gen_robot_keyword as grk | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 11 | import gen_valid as gv | 
| Michael Walsh | e4a093d | 2017-10-30 15:03:18 -0500 | [diff] [blame] | 12 | import state as st | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 13 | from robot.libraries.BuiltIn import BuiltIn | 
|  | 14 |  | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 15 | redfish_support_trans_state = int( | 
|  | 16 | os.environ.get("REDFISH_SUPPORT_TRANS_STATE", 0) | 
|  | 17 | ) or int( | 
|  | 18 | BuiltIn().get_variable_value("${REDFISH_SUPPORT_TRANS_STATE}", default=0) | 
|  | 19 | ) | 
| Michael Shepos | e177517 | 2021-02-11 16:59:08 -0600 | [diff] [blame] | 20 |  | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 21 |  | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 22 | def ffdc( | 
|  | 23 | ffdc_dir_path=None, | 
|  | 24 | ffdc_prefix=None, | 
|  | 25 | ffdc_function_list="", | 
|  | 26 | comm_check=True, | 
|  | 27 | ): | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 28 | r""" | 
|  | 29 | Gather First Failure Data Capture (FFDC). | 
|  | 30 |  | 
|  | 31 | This includes: | 
|  | 32 | - Set global FFDC_TIME. | 
|  | 33 | - Create FFDC work space directory. | 
|  | 34 | - Write test info details. | 
|  | 35 | - Call BMC methods to write/collect FFDC data. | 
|  | 36 |  | 
|  | 37 | Description of arguments: | 
| Michael Walsh | da8b394 | 2020-03-23 10:39:52 -0500 | [diff] [blame] | 38 | ffdc_dir_path                   The dir path where FFDC data should be put. | 
|  | 39 | ffdc_prefix                     The prefix to be given to each FFDC file name generated. | 
|  | 40 | ffdc_function_list              A colon-delimited list of all the types of FFDC data you wish to have | 
|  | 41 | collected.  A blank value means that all possible kinds of FFDC are to be | 
|  | 42 | collected.  See FFDC_METHOD_CALL object in lib/openbmc_ffdc_list.py for | 
|  | 43 | possible choices. | 
|  | 44 | comm_check                      Do a communications check prior to collecting FFDC.  If commincation to | 
|  | 45 | the BMC can't be established, abort the FFDC collection. | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 46 | """ | 
|  | 47 |  | 
| Michael Walsh | e4a093d | 2017-10-30 15:03:18 -0500 | [diff] [blame] | 48 | ffdc_file_list = [] | 
|  | 49 |  | 
| George Keishing | 3f7f12c | 2017-03-02 06:14:41 -0600 | [diff] [blame] | 50 | # Check if Ping and SSH connection is alive | 
|  | 51 | OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}") | 
| George Keishing | 3f7f12c | 2017-03-02 06:14:41 -0600 | [diff] [blame] | 52 |  | 
| Michael Walsh | da8b394 | 2020-03-23 10:39:52 -0500 | [diff] [blame] | 53 | if comm_check: | 
| Michael Shepos | e177517 | 2021-02-11 16:59:08 -0600 | [diff] [blame] | 54 | if not redfish_support_trans_state: | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 55 | interface = "rest" | 
| Michael Shepos | e177517 | 2021-02-11 16:59:08 -0600 | [diff] [blame] | 56 | else: | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 57 | interface = "redfish" | 
| Michael Shepos | e177517 | 2021-02-11 16:59:08 -0600 | [diff] [blame] | 58 |  | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 59 | state = st.get_state(req_states=["ping", "uptime", interface]) | 
| Michael Walsh | da8b394 | 2020-03-23 10:39:52 -0500 | [diff] [blame] | 60 | gp.qprint_var(state) | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 61 | if not int(state["ping"]): | 
|  | 62 | gp.print_error( | 
|  | 63 | "BMC is not ping-able.  Terminating FFDC collection.\n" | 
|  | 64 | ) | 
| Michael Walsh | da8b394 | 2020-03-23 10:39:52 -0500 | [diff] [blame] | 65 | return ffdc_file_list | 
| Michael Walsh | e4a093d | 2017-10-30 15:03:18 -0500 | [diff] [blame] | 66 |  | 
| Michael Shepos | e177517 | 2021-02-11 16:59:08 -0600 | [diff] [blame] | 67 | if not int(state[interface]): | 
| George Keishing | b1b6f13 | 2022-02-15 01:30:29 -0600 | [diff] [blame] | 68 | gp.print_error("%s commands to the BMC are failing." % interface) | 
| Michael Walsh | 2bfc48e | 2018-10-24 15:23:17 -0500 | [diff] [blame] | 69 |  | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 70 | if state["uptime"] == "": | 
| George Keishing | b1b6f13 | 2022-02-15 01:30:29 -0600 | [diff] [blame] | 71 | gp.print_error("BMC is not communicating via ssh.\n") | 
|  | 72 |  | 
|  | 73 | # If SSH and Redfish connection doesn't works, abort. | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 74 | if not int(state[interface]) and state["uptime"] == "": | 
|  | 75 | gp.print_error( | 
|  | 76 | "BMC is not communicating via ssh or Redfish.  Terminating" | 
| George Keishing | 7899a45 | 2023-02-15 02:46:54 -0600 | [diff] [blame] | 77 | " FFDC" + " collection.\n" | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 78 | ) | 
| Michael Walsh | da8b394 | 2020-03-23 10:39:52 -0500 | [diff] [blame] | 79 | return ffdc_file_list | 
| Michael Walsh | e4a093d | 2017-10-30 15:03:18 -0500 | [diff] [blame] | 80 |  | 
|  | 81 | gp.qprint_timen("Collecting FFDC.") | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 82 |  | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 83 | # Get default values for arguments. | 
|  | 84 | ffdc_dir_path, ffdc_prefix = set_ffdc_defaults(ffdc_dir_path, ffdc_prefix) | 
| Michael Walsh | e4a093d | 2017-10-30 15:03:18 -0500 | [diff] [blame] | 85 | gp.qprint_var(ffdc_dir_path) | 
|  | 86 | gp.qprint_var(ffdc_prefix) | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 87 |  | 
|  | 88 | # LOG_PREFIX is used by subordinate functions. | 
|  | 89 | LOG_PREFIX = ffdc_dir_path + ffdc_prefix | 
|  | 90 | BuiltIn().set_global_variable("${LOG_PREFIX}", LOG_PREFIX) | 
|  | 91 |  | 
|  | 92 | cmd_buf = ["Create Directory", ffdc_dir_path] | 
| Michael Walsh | edb5c94 | 2019-03-28 12:40:50 -0500 | [diff] [blame] | 93 | gp.qprint_issuing(cmd_buf) | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 94 | status, output = BuiltIn().run_keyword_and_ignore_error(*cmd_buf) | 
|  | 95 | if status != "PASS": | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 96 | error_message = gp.sprint_error_report( | 
|  | 97 | "Create Directory failed" | 
|  | 98 | + " with the following" | 
|  | 99 | + " error:\n" | 
|  | 100 | + output | 
|  | 101 | ) | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 102 | BuiltIn().fail(error_message) | 
|  | 103 |  | 
|  | 104 | # FFDC_FILE_PATH is used by Header Message. | 
|  | 105 | FFDC_FILE_PATH = ffdc_dir_path + ffdc_prefix + "BMC_general.txt" | 
|  | 106 | BuiltIn().set_global_variable("${FFDC_FILE_PATH}", FFDC_FILE_PATH) | 
|  | 107 |  | 
| Michael Walsh | fdde258 | 2019-04-18 11:05:11 -0500 | [diff] [blame] | 108 | status, ffdc_file_list = grk.run_key_u("Header Message") | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 109 | status, ffdc_file_sub_list = grk.run_key_u( | 
|  | 110 | "Call FFDC Methods  ffdc_function_list=" + ffdc_function_list | 
|  | 111 | ) | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 112 |  | 
| Michael Walsh | e4a093d | 2017-10-30 15:03:18 -0500 | [diff] [blame] | 113 | # Combine lists, remove duplicates and sort. | 
| Joy Onyerikwu | 004ad3c | 2018-06-11 16:29:56 -0500 | [diff] [blame] | 114 | ffdc_file_list = sorted(set(ffdc_file_list + ffdc_file_sub_list)) | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 115 |  | 
| Michael Walsh | e4a093d | 2017-10-30 15:03:18 -0500 | [diff] [blame] | 116 | gp.qprint_timen("Finished collecting FFDC.") | 
|  | 117 |  | 
|  | 118 | return ffdc_file_list | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 119 |  | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 120 |  | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 121 | def set_ffdc_defaults(ffdc_dir_path=None, ffdc_prefix=None): | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 122 | r""" | 
|  | 123 | Set a default value for ffdc_dir_path and ffdc_prefix if they don't | 
|  | 124 | already have values.  Return both values. | 
|  | 125 |  | 
|  | 126 | Description of arguments: | 
|  | 127 | ffdc_dir_path  The dir path where FFDC data should be put. | 
|  | 128 | ffdc_prefix    The prefix to be given to each FFDC file name generated. | 
|  | 129 |  | 
|  | 130 | NOTE: If global variable ffdc_dir_path_style is set to ${1}, this function | 
|  | 131 | will create default values in a newer way.  Otherwise, its behavior | 
|  | 132 | will remain unchanged. | 
|  | 133 | """ | 
|  | 134 |  | 
| Michael Walsh | fa9f70f | 2017-04-21 16:00:18 -0500 | [diff] [blame] | 135 | # Note: Several subordinate functions like 'Get Test Dir and Name' and | 
|  | 136 | # 'Header Message' expect global variable FFDC_TIME to be set. | 
|  | 137 | cmd_buf = ["Get Current Time Stamp"] | 
| Michael Walsh | edb5c94 | 2019-03-28 12:40:50 -0500 | [diff] [blame] | 138 | gp.dprint_issuing(cmd_buf) | 
| Michael Walsh | fa9f70f | 2017-04-21 16:00:18 -0500 | [diff] [blame] | 139 | FFDC_TIME = BuiltIn().run_keyword(*cmd_buf) | 
|  | 140 | BuiltIn().set_global_variable("${FFDC_TIME}", FFDC_TIME) | 
|  | 141 |  | 
| Michael Walsh | a0364ae | 2017-01-10 11:24:42 -0600 | [diff] [blame] | 142 | ffdc_dir_path_style = BuiltIn().get_variable_value( | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 143 | "${ffdc_dir_path_style}" | 
|  | 144 | ) | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 145 |  | 
|  | 146 | if ffdc_dir_path is None: | 
|  | 147 | if ffdc_dir_path_style: | 
|  | 148 | try: | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 149 | ffdc_dir_path = os.environ["FFDC_DIR_PATH"] | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 150 | except KeyError: | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 151 | ffdc_dir_path = ( | 
|  | 152 | os.path.dirname( | 
|  | 153 | BuiltIn().get_variable_value("${LOG_FILE}") | 
|  | 154 | ) | 
|  | 155 | + "/" | 
|  | 156 | ) | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 157 | else: | 
| George Keishing | 58a13f5 | 2017-06-21 14:04:42 -0500 | [diff] [blame] | 158 | FFDC_LOG_PATH = os.getcwd() + "/logs/" | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 159 | if FFDC_LOG_PATH is None: | 
|  | 160 | FFDC_LOG_PATH = "" | 
|  | 161 | if FFDC_LOG_PATH == "": | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 162 | FFDC_LOG_PATH = ( | 
|  | 163 | os.path.dirname( | 
|  | 164 | BuiltIn().get_variable_value("${LOG_FILE}") | 
|  | 165 | ) | 
|  | 166 | + "/" | 
|  | 167 | ) | 
|  | 168 | error_message = gv.valid_value( | 
|  | 169 | FFDC_LOG_PATH, var_name="FFDC_LOG_PATH" | 
|  | 170 | ) | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 171 | if error_message != "": | 
| Michael Walsh | edb5c94 | 2019-03-28 12:40:50 -0500 | [diff] [blame] | 172 | error_message = gp.sprint_error_report(error_message) | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 173 | BuiltIn().fail(error_message) | 
|  | 174 | FFDC_LOG_PATH = os.path.normpath(FFDC_LOG_PATH) + os.sep | 
|  | 175 |  | 
|  | 176 | cmd_buf = ["Get Test Dir and Name"] | 
| Michael Walsh | edb5c94 | 2019-03-28 12:40:50 -0500 | [diff] [blame] | 177 | gp.print_issuing(cmd_buf) | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 178 | suitename, testname = BuiltIn().run_keyword(*cmd_buf) | 
|  | 179 |  | 
|  | 180 | ffdc_dir_path = FFDC_LOG_PATH + suitename + "/" + testname + "/" | 
|  | 181 |  | 
|  | 182 | # Add trailing slash. | 
|  | 183 | ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep | 
|  | 184 |  | 
|  | 185 | if ffdc_prefix is None: | 
|  | 186 | FFDC_TIME = BuiltIn().get_variable_value("${FFDC_TIME}") | 
|  | 187 | if ffdc_prefix is None: | 
|  | 188 | if ffdc_dir_path_style: | 
|  | 189 | OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}") | 
| Michael Walsh | a0364ae | 2017-01-10 11:24:42 -0600 | [diff] [blame] | 190 | OPENBMC_NICKNAME = BuiltIn().get_variable_value( | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 191 | "${OPENBMC_NICKNAME}", default=OPENBMC_HOST | 
|  | 192 | ) | 
|  | 193 | ffdc_prefix = ( | 
|  | 194 | OPENBMC_NICKNAME | 
|  | 195 | + "." | 
|  | 196 | + FFDC_TIME[2:8] | 
|  | 197 | + "." | 
|  | 198 | + FFDC_TIME[8:14] | 
|  | 199 | + "." | 
|  | 200 | ) | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 201 | else: | 
|  | 202 | ffdc_prefix = FFDC_TIME + "_" | 
|  | 203 |  | 
| Michael Walsh | fa9f70f | 2017-04-21 16:00:18 -0500 | [diff] [blame] | 204 | BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path) | 
|  | 205 | BuiltIn().set_global_variable("${FFDC_PREFIX}", ffdc_prefix) | 
|  | 206 |  | 
| Michael Walsh | 769c2a1 | 2016-12-13 15:45:17 -0600 | [diff] [blame] | 207 | return ffdc_dir_path, ffdc_prefix |