1#!/usr/bin/env python3 2 3r""" 4This file contains functions which are useful for processing BMC dumps. 5""" 6 7import gen_print as gp 8import gen_misc as gm 9import gen_robot_keyword as grk 10import bmc_ssh_utils as bsu 11import var_funcs as vf 12import os 13from robot.libraries.BuiltIn import BuiltIn 14import sys 15import os 16import imp 17base_path = os.path.dirname(os.path.dirname( 18 imp.find_module("gen_robot_print")[1])) + os.sep 19sys.path.append(base_path + "data/") 20import variables as var 21 22 23def get_dump_dict(quiet=None): 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 31 Rprint Vars dump_dict 32 33 Example output: 34 35 dump_dict: 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 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)) 51 cmd_buf = "dump_dir_path=" + var.DUMP_DIR_PATH + " ; " \ 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" 55 output, stderr, rc = bsu.bmc_execute_command(cmd_buf, quiet=quiet) 56 57 return vf.key_value_outbuf_to_dict(output) 58 59 60def valid_dump(dump_id, 61 dump_dict=None, 62 quiet=None): 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)) 97 98 99def scp_dumps(targ_dir_path, 100 targ_file_prefix="", 101 dump_dict=None, 102 quiet=None): 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 = [] 128 for dump_id, source_file_path in dump_dict.items(): 129 targ_file_path = targ_dir_path + targ_file_prefix \ 130 + os.path.basename(source_file_path) 131 status, ret_values = grk.run_key("scp.Get File " + source_file_path 132 + " " + targ_file_path, quiet=quiet) 133 dump_file_list.append(targ_file_path) 134 135 return dump_file_list 136 137 138def 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 169def 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 208def 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 245