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