Michael Walsh | e11a136 | 2017-10-19 15:35:26 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | r""" |
| 4 | This file contains functions which are useful for processing BMC dumps. |
| 5 | """ |
| 6 | |
| 7 | import gen_print as gp |
Michael Walsh | 4f3ce17 | 2017-10-19 17:28:49 -0500 | [diff] [blame] | 8 | import gen_misc as gm |
| 9 | import gen_robot_keyword as grk |
Michael Walsh | e11a136 | 2017-10-19 15:35:26 -0500 | [diff] [blame] | 10 | import bmc_ssh_utils as bsu |
| 11 | import var_funcs as vf |
Michael Walsh | 4f3ce17 | 2017-10-19 17:28:49 -0500 | [diff] [blame] | 12 | import os |
Michael Walsh | e11a136 | 2017-10-19 15:35:26 -0500 | [diff] [blame] | 13 | from robot.libraries.BuiltIn import BuiltIn |
| 14 | import sys |
| 15 | import os |
| 16 | import imp |
| 17 | base_path = os.path.dirname(os.path.dirname( |
| 18 | imp.find_module("gen_robot_print")[1])) + os.sep |
| 19 | sys.path.append(base_path + "data/") |
| 20 | import variables as var |
| 21 | |
| 22 | |
| 23 | def get_dump_dict(quiet=None): |
Michael Walsh | e11a136 | 2017-10-19 15:35:26 -0500 | [diff] [blame] | 24 | r""" |
| 25 | Get dump information and return as an ordered dictionary where the keys |
| 26 | are the dump IDs and the values are the full path names of the dumps. |
| 27 | |
| 28 | Example robot program call: |
| 29 | |
| 30 | ${dump_dict}= Get Dump Dict |
Michael Walsh | 39c0051 | 2019-07-17 10:54:06 -0500 | [diff] [blame] | 31 | Rprint Vars dump_dict |
Michael Walsh | e11a136 | 2017-10-19 15:35:26 -0500 | [diff] [blame] | 32 | |
| 33 | Example output: |
| 34 | |
| 35 | dump_dict: |
Joy Onyerikwu | 004ad3c | 2018-06-11 16:29:56 -0500 | [diff] [blame] | 36 | [1]: |
| 37 | /var/lib/phosphor-debug-collector/dumps/1/obmcdump_1_1508255216.tar.xz |
| 38 | [2]: |
| 39 | /var/lib/phosphor-debug-collector/dumps/2/obmcdump_2_1508255245.tar.xz |
| 40 | [3]: |
| 41 | /var/lib/phosphor-debug-collector/dumps/3/obmcdump_3_1508255267.tar.xz |
| 42 | [4]: |
| 43 | /var/lib/phosphor-debug-collector/dumps/4/obmcdump_4_1508255283.tar.xz |
Michael Walsh | e11a136 | 2017-10-19 15:35:26 -0500 | [diff] [blame] | 44 | |
| 45 | Description of argument(s): |
| 46 | quiet If quiet is set to 1, this function will |
| 47 | NOT write status messages to stdout. |
| 48 | """ |
| 49 | |
| 50 | quiet = int(gp.get_var_value(quiet, 1)) |
Michael Walsh | 4f3ce17 | 2017-10-19 17:28:49 -0500 | [diff] [blame] | 51 | cmd_buf = "dump_dir_path=" + var.DUMP_DIR_PATH + " ; " \ |
Michael Walsh | 723482b | 2019-02-01 16:51:32 -0600 | [diff] [blame] | 52 | + "for dump_id in $(ls ${dump_dir_path} | sort -n) ; do " \ |
| 53 | + "file_path=$(ls ${dump_dir_path}${dump_id}/* 2>/dev/null)" \ |
| 54 | + " || continue ; echo ${dump_id}:${file_path} ; done" |
Michael Walsh | e11a136 | 2017-10-19 15:35:26 -0500 | [diff] [blame] | 55 | output, stderr, rc = bsu.bmc_execute_command(cmd_buf, quiet=quiet) |
| 56 | |
| 57 | return vf.key_value_outbuf_to_dict(output) |
| 58 | |
| 59 | |
| 60 | def valid_dump(dump_id, |
| 61 | dump_dict=None, |
| 62 | quiet=None): |
Michael Walsh | e11a136 | 2017-10-19 15:35:26 -0500 | [diff] [blame] | 63 | r""" |
| 64 | Verify that dump_id is a valid. If it is not valid, issue robot failure |
| 65 | message. |
| 66 | |
| 67 | A dump is valid if the indicated dump_id refers to an existing dump with a |
| 68 | valid associated dump file. |
| 69 | |
| 70 | Description of argument(s): |
| 71 | dump_id A dump ID (e.g. "1", "2", etc.) |
| 72 | dump_dict A dump dictionary such as the one returned |
| 73 | by get_dump_dict. If this value is None, |
| 74 | this function will call get_dump_dict on |
| 75 | the caller's behalf. |
| 76 | quiet If quiet is set to 1, this function will |
| 77 | NOT write status messages to stdout. |
| 78 | """ |
| 79 | |
| 80 | if dump_dict is None: |
| 81 | dump_dict = get_dump_dict(quiet=quiet) |
| 82 | |
| 83 | if dump_id not in dump_dict: |
| 84 | message = "The specified dump ID was not found among the existing" \ |
| 85 | + " dumps:\n" |
| 86 | message += gp.sprint_var(dump_id) |
| 87 | message += gp.sprint_var(dump_dict) |
| 88 | BuiltIn().fail(gp.sprint_error(message)) |
| 89 | |
| 90 | if not dump_dict[dump_id].endswith("tar.xz"): |
| 91 | message = "There is no \"tar.xz\" file associated with the given" \ |
| 92 | + " dump_id:\n" |
| 93 | message += gp.sprint_var(dump_id) |
| 94 | dump_file_path = dump_dict[dump_id] |
| 95 | message += gp.sprint_var(dump_file_path) |
| 96 | BuiltIn().fail(gp.sprint_error(message)) |
Michael Walsh | 4f3ce17 | 2017-10-19 17:28:49 -0500 | [diff] [blame] | 97 | |
| 98 | |
| 99 | def scp_dumps(targ_dir_path, |
| 100 | targ_file_prefix="", |
| 101 | dump_dict=None, |
| 102 | quiet=None): |
Michael Walsh | 4f3ce17 | 2017-10-19 17:28:49 -0500 | [diff] [blame] | 103 | r""" |
| 104 | SCP all dumps from the BMC to the indicated directory on the local system |
| 105 | and return a list of the new files. |
| 106 | |
| 107 | Description of argument(s): |
| 108 | targ_dir_path The path of the directory to receive the |
| 109 | dump files. |
| 110 | targ_file_prefix Prefix which will be pre-pended to each |
| 111 | target file's name. |
| 112 | dump_dict A dump dictionary such as the one returned |
| 113 | by get_dump_dict. If this value is None, |
| 114 | this function will call get_dump_dict on |
| 115 | the caller's behalf. |
| 116 | quiet If quiet is set to 1, this function will |
| 117 | NOT write status messages to stdout. |
| 118 | """ |
| 119 | |
| 120 | targ_dir_path = gm.add_trailing_slash(targ_dir_path) |
| 121 | |
| 122 | if dump_dict is None: |
| 123 | dump_dict = get_dump_dict(quiet=quiet) |
| 124 | |
| 125 | status, ret_values = grk.run_key("Open Connection for SCP", quiet=quiet) |
| 126 | |
| 127 | dump_file_list = [] |
George Keishing | 36efbc0 | 2018-12-12 10:18:23 -0600 | [diff] [blame] | 128 | for dump_id, source_file_path in dump_dict.items(): |
Michael Walsh | 4f3ce17 | 2017-10-19 17:28:49 -0500 | [diff] [blame] | 129 | targ_file_path = targ_dir_path + targ_file_prefix \ |
| 130 | + os.path.basename(source_file_path) |
Joy Onyerikwu | 004ad3c | 2018-06-11 16:29:56 -0500 | [diff] [blame] | 131 | status, ret_values = grk.run_key("scp.Get File " + source_file_path |
| 132 | + " " + targ_file_path, quiet=quiet) |
Michael Walsh | 4f3ce17 | 2017-10-19 17:28:49 -0500 | [diff] [blame] | 133 | dump_file_list.append(targ_file_path) |
| 134 | |
| 135 | return dump_file_list |
George Keishing | 1165a02 | 2021-05-19 06:23:13 -0500 | [diff] [blame] | 136 | |
| 137 | |
| 138 | def get_dump_hb_dict(quiet=None): |
| 139 | r""" |
| 140 | Get dump information and return as an ordered dictionary where the keys |
| 141 | are the dump IDs and the values are the full path names of the dumps. |
| 142 | |
| 143 | Example robot program call: |
| 144 | |
| 145 | ${dump_dict}= Get Dump HB Dict |
| 146 | Rprint Vars dump_hb_dict |
| 147 | |
| 148 | Example output: |
| 149 | |
| 150 | dump__hb_dict: |
| 151 | [1]: |
| 152 | /var/lib/phosphor-debug-collector/hostbootdump/1/hbdump_1_1621421112.tar.gz |
| 153 | |
| 154 | Description of argument(s): |
| 155 | quiet If quiet is set to 1, this function will |
| 156 | NOT write status messages to stdout. |
| 157 | """ |
| 158 | |
| 159 | quiet = int(gp.get_var_value(quiet, 1)) |
| 160 | cmd_buf = "dump_hb_dir_path=" + var.DUMP_HB_DIR_PATH + " ; " \ |
| 161 | + "for dump_id in $(ls ${dump_hb_dir_path} | sort -n) ; do " \ |
| 162 | + "file_path=$(ls ${dump_hb_dir_path}${dump_id}/* 2>/dev/null)" \ |
| 163 | + " || continue ; echo ${dump_id}:${file_path} ; done" |
| 164 | output, stderr, rc = bsu.bmc_execute_command(cmd_buf, quiet=quiet) |
| 165 | |
| 166 | return vf.key_value_outbuf_to_dict(output) |
| 167 | |
| 168 | |
| 169 | def valid_dump_hb(dump_id, |
| 170 | dump_dict=None, |
| 171 | quiet=None): |
| 172 | r""" |
| 173 | Verify that dump_id is a valid. If it is not valid, issue robot failure |
| 174 | message. |
| 175 | |
| 176 | A dump is valid if the indicated dump_id refers to an existing dump with a |
| 177 | valid associated dump file. |
| 178 | |
| 179 | Description of argument(s): |
| 180 | dump_id A dump ID (e.g. "1", "2", etc.) |
| 181 | dump_dict A dump dictionary such as the one returned |
| 182 | by get_dump_hb_dict. If this value is None, |
| 183 | this function will call get_dump_hb_dict on |
| 184 | the caller's behalf. |
| 185 | quiet If quiet is set to 1, this function will |
| 186 | NOT write status messages to stdout. |
| 187 | """ |
| 188 | |
| 189 | if dump_dict is None: |
| 190 | dump_dict = get_dump_hb_dict(quiet=quiet) |
| 191 | |
| 192 | if dump_id not in dump_dict: |
| 193 | message = "The specified dump ID was not found among the existing" \ |
| 194 | + " dumps:\n" |
| 195 | message += gp.sprint_var(dump_id) |
| 196 | message += gp.sprint_var(dump_dict) |
| 197 | BuiltIn().fail(gp.sprint_error(message)) |
| 198 | |
| 199 | if not dump_dict[dump_id].endswith("tar.gz"): |
| 200 | message = "There is no \"tar.gz\" file associated with the given" \ |
| 201 | + " dump_id:\n" |
| 202 | message += gp.sprint_var(dump_id) |
| 203 | dump_file_path = dump_dict[dump_id] |
| 204 | message += gp.sprint_var(dump_file_path) |
| 205 | BuiltIn().fail(gp.sprint_error(message)) |
| 206 | |
| 207 | |
| 208 | def scp_dumps_hb(targ_dir_path, |
| 209 | targ_file_prefix="", |
| 210 | dump_dict=None, |
| 211 | quiet=None): |
| 212 | r""" |
| 213 | SCP all dumps from the BMC to the indicated directory on the local system |
| 214 | and return a list of the new files. |
| 215 | |
| 216 | Description of argument(s): |
| 217 | targ_dir_path The path of the directory to receive the |
| 218 | dump files. |
| 219 | targ_file_prefix Prefix which will be pre-pended to each |
| 220 | target file's name. |
| 221 | dump_dict A dump dictionary such as the one returned |
| 222 | by get_dump_dict. If this value is None, |
| 223 | this function will call get_dump_dict on |
| 224 | the caller's behalf. |
| 225 | quiet If quiet is set to 1, this function will |
| 226 | NOT write status messages to stdout. |
| 227 | """ |
| 228 | |
| 229 | targ_dir_path = gm.add_trailing_slash(targ_dir_path) |
| 230 | |
| 231 | if dump_dict is None: |
| 232 | dump_dict = get_dump_hb_dict(quiet=quiet) |
| 233 | |
| 234 | status, ret_values = grk.run_key("Open Connection for SCP", quiet=quiet) |
| 235 | |
| 236 | dump_file_list = [] |
| 237 | for dump_id, source_file_path in dump_dict.items(): |
| 238 | targ_file_path = targ_dir_path + targ_file_prefix \ |
| 239 | + os.path.basename(source_file_path) |
| 240 | status, ret_values = grk.run_key("scp.Get File " + source_file_path |
| 241 | + " " + targ_file_path, quiet=quiet) |
| 242 | dump_file_list.append(targ_file_path) |
| 243 | |
| 244 | return dump_file_list |