1*** Settings *** 2Documentation This module provides general keywords for dump. 3 4Library bmc_ssh_utils.py 5 6*** Variables *** 7 8*** Keywords *** 9 10Create User Initiated Dump 11 [Documentation] Generate user initiated dump and return 12 ... the dump id number (e.g., "5"). Optionally return EMPTY 13 ... if out of dump space. 14 [Arguments] ${check_out_of_space}=${False} 15 16 # Description of Argument(s): 17 # check_out_of_space If ${False}, a dump will be created and 18 # its dump_id will be returned. 19 # If ${True}, either the dump_id will be 20 # returned, or the value ${EMPTY} will be 21 # returned if out of dump space was 22 # detected when creating the dump. 23 24 ${resp}= OpenBMC Get Request ${REST_DUMP_URI} 25 Run Keyword If '${resp.status_code}' == '${HTTP_NOT_FOUND}' 26 ... Set Global Variable ${REST_DUMP_URI} /xyz/openbmc_project/dump/ 27 28 ${data}= Create Dictionary data=@{EMPTY} 29 ${resp}= OpenBMC Post Request 30 ... ${REST_DUMP_URI}action/CreateDump data=${data} quiet=${1} 31 32 Run Keyword If '${check_out_of_space}' == '${False}' 33 ... Run Keyword And Return Get The Dump Id ${resp} 34 ... ELSE 35 ... Run Keyword And Return Check For Too Many Dumps ${resp} 36 37 38Get The Dump Id 39 [Documentation] Wait for the dump to be created. Return the 40 ... dump id number (e.g., "5"). 41 [Arguments] ${resp} 42 43 # Description of Argument(s): 44 # resp Response object from action/Create Dump attempt. 45 # Example object: 46 # { 47 # "data": 5, 48 # "message": "200 OK", 49 # "status": "ok" 50 # }, 51 # The "data" field conveys the id number of the created dump. 52 53 Should Be Equal As Strings ${resp.status_code} ${HTTP_OK} 54 55 Run Keyword If ${resp.json()["data"]} == ${None} 56 ... Fail Dump id returned null. 57 58 ${dump_id}= Set Variable ${json["data"]} 59 60 Wait Until Keyword Succeeds 3 min 15 sec Check Dump Existence 61 ... ${dump_id} 62 63 [Return] ${dump_id} 64 65 66Check For Too Many Dumps 67 [Documentation] Return the dump_id number, or return ${EMPTY} if dump 68 ... creation failed due to too many dumps. 69 [Arguments] ${resp} 70 71 # Description of Argument(s): 72 # resp Response object from action/Create Dump attempt. 73 # Example object if there are too many dumps: 74 # { 75 # "data": { 76 # "description": "xyz.openbmc_project.Dump.Create.Error.QuotaExceeded" 77 # }, 78 # "message": "Dump not captured due to a cap.", 79 # "status": "error" 80 # } 81 82 # If dump was created normally, return the dump_id number. 83 Run Keyword If '${resp.status_code}' == '${HTTP_OK}' 84 ... Run Keyword And Return Get The Dump Id ${resp} 85 86 ${exception}= Set Variable ${resp.json()["message"]} 87 ${at_capacity}= Set Variable Dump not captured due to a cap 88 ${too_many_dumps}= Evaluate $at_capacity in $exception 89 Printn 90 Rprint Vars exception too_many_dumps 91 # If there are too many dumps, return ${EMPTY}, otherwise Fail. 92 ${status}= Run Keyword If ${too_many_dumps} Set Variable ${EMPTY} 93 ... ELSE Fail msg=${exception}. 94 95 [Return] ${status} 96 97 98Verify No Dump In Progress 99 [Documentation] Verify no dump in progress. 100 101 ${dump_progress} ${stderr} ${rc}= BMC Execute Command ls /tmp 102 Should Not Contain ${dump_progress} obmcdump 103 104 105Check Dump Existence 106 [Documentation] Verify if given dump exist. 107 [Arguments] ${dump_id} 108 109 # Description of Argument(s): 110 # dump_id An integer value that identifies a particular dump 111 # object(e.g. 1, 3, 5). 112 113 ${resp}= OpenBMC Get Request ${REST_DUMP_URI} 114 Run Keyword If '${resp.status_code}' == '${HTTP_NOT_FOUND}' 115 ... Set Global Variable ${DUMP_ENTRY_URI} /xyz/openbmc_project/dump/entry/ 116 117 ${resp}= OpenBMC Get Request ${DUMP_ENTRY_URI}${dump_id} 118 Should Be Equal As Strings ${resp.status_code} ${HTTP_OK} 119 120 121Delete BMC Dump 122 [Documentation] Deletes a given bmc dump. 123 [Arguments] ${dump_id} 124 125 # Description of Argument(s): 126 # dump_id An integer value that identifies a particular dump (e.g. 1, 3). 127 128 ${resp}= OpenBMC Get Request ${REST_DUMP_URI} 129 Run Keyword If '${resp.status_code}' == '${HTTP_NOT_FOUND}' 130 ... Set Global Variable ${DUMP_ENTRY_URI} /xyz/openbmc_project/dump/entry/ 131 132 ${args}= Set Variable {"data": []} 133 ${resp}= OpenBMC Post Request 134 ... ${DUMP_ENTRY_URI}${dump_id}/action/Delete data=${args} 135 136 Should Be Equal As Strings ${resp.status_code} ${HTTP_OK} 137 138Delete All Dumps 139 [Documentation] Delete all dumps. 140 141 ${resp}= OpenBMC Get Request ${REST_DUMP_URI} 142 Run Keyword If '${resp.status_code}' == '${HTTP_NOT_FOUND}' 143 ... Set Global Variable ${DUMP_ENTRY_URI} /xyz/openbmc_project/dump/entry/ 144 145 # Check if dump entries exist, if not return. 146 ${resp}= OpenBMC Get Request ${DUMP_ENTRY_URI}list quiet=${1} 147 Return From Keyword If ${resp.status_code} == ${HTTP_NOT_FOUND} 148 149 # Get the list of dump entries and delete them all. 150 ${dump_entries}= Get URL List ${DUMP_ENTRY_URI} 151 FOR ${entry} IN @{dump_entries} 152 ${dump_id}= Fetch From Right ${entry} / 153 Delete BMC Dump ${dump_id} 154 END 155 156 157Redfish Delete BMC Dump 158 [Documentation] Deletes a given BMC dump via Redfish.. 159 [Arguments] ${dump_id} 160 161 # Description of Argument(s): 162 # dump_id An integer value that identifies a particular dump (e.g. 1, 3). 163 164 Redfish.Delete /redfish/v1/Managers/bmc/LogServices/Dump/Entries/${dump_id} 165 166 167Redfish Delete All BMC Dumps 168 [Documentation] Delete all BMC dumps via Redfish. 169 170 # Check if dump entries exist, if not return. 171 ${resp}= Redfish.Get /redfish/v1/Managers/bmc/LogServices/Dump/Entries 172 Return From Keyword If ${resp.dict["Members@odata.count"]} == ${0} 173 174 Redfish.Post /redfish/v1/Managers/bmc/LogServices/Dump/Actions/LogService.ClearLog 175 176 177Redfish Delete All System Dumps 178 [Documentation] Delete all system dumps via Redfish. 179 180 Redfish.Post /redfish/v1/Systems/system/LogServices/Dump/Actions/LogService.ClearLog 181 182 183Delete All BMC Dump 184 [Documentation] Delete all BMC dump entries using "DeleteAll" interface. 185 186 ${resp}= OpenBMC Get Request ${REST_DUMP_URI} 187 Run Keyword If '${resp.status_code}' == '${HTTP_NOT_FOUND}' 188 ... Set Global Variable ${REST_DUMP_URI} /xyz/openbmc_project/dump/ 189 190 ${args}= Set Variable {"data": []} 191 ${resp}= Openbmc Post Request ${REST_DUMP_URI}action/DeleteAll data=${args} 192 Should Be Equal As Strings ${resp.status_code} ${HTTP_OK} 193 194Dump Should Not Exist 195 [Documentation] Verify that BMC dumps do not exist. 196 197 ${resp}= OpenBMC Get Request ${REST_DUMP_URI} 198 Run Keyword If '${resp.status_code}' == '${HTTP_NOT_FOUND}' 199 ... Set Global Variable ${DUMP_ENTRY_URI} /xyz/openbmc_project/dump/entry/ 200 201 ${resp}= OpenBMC Get Request ${DUMP_ENTRY_URI}list quiet=${1} 202 Should Be Equal As Strings ${resp.status_code} ${HTTP_NOT_FOUND} 203 204Check Existence Of BMC Dump File 205 [Documentation] Verify existence of BMC dump file. 206 [Arguments] ${dump_id} 207 208 # Description of argument(s): 209 # dump_id BMC dump identifier 210 211 ${dump_check_cmd}= Set Variable 212 ... ls /var/lib/phosphor-debug-collector/dumps 213 214 # Output of sample BMC Execute command with '2' as dump id is as follows 215 # ls /var/lib/phosphor-debug-collector/dumps/2 216 # obmcdump_2_XXXXXXXXXX.tar.xz 217 ${file_there} ${stderr} ${rc}= BMC Execute Command 218 ... ${dump_check_cmd}/${dump_id} 219 Should End With ${file_there} tar.xz msg=BMC dump file not found. 220 221Get Dump Entries 222 [Documentation] Return dump entries list. 223 224 ${resp}= OpenBMC Get Request ${REST_DUMP_URI} 225 Run Keyword If '${resp.status_code}' == '${HTTP_NOT_FOUND}' 226 ... Set Global Variable ${DUMP_ENTRY_URI} /xyz/openbmc_project/dump/entry/ 227 228 ${dump_entries}= Get URL List ${DUMP_ENTRY_URI} 229 [Return] ${dump_entries} 230 231Trigger Core Dump 232 [Documentation] Trigger core dump. 233 234 # Find the pid of the active ipmid and kill it. 235 ${cmd_buf}= Catenate kill -s SEGV $(ps | egrep ' ipmid$' | 236 ... egrep -v grep | \ cut -c1-6) 237 238 ${cmd_output} ${stderr} ${rc}= BMC Execute Command ${cmd_buf} 239 Should Be Empty ${stderr} msg=BMC execute command error. 240 Should Be Equal As Integers ${rc} ${0} 241 ... msg=BMC execute command return code is not zero. 242 243Initiate BMC Dump Using Redfish And Return Task Id 244 [Documentation] Initiate BMC dump via Redfish and return its task ID. 245 246 ${payload}= Create Dictionary DiagnosticDataType=Manager 247 ${resp}= Redfish.Post 248 ... /redfish/v1/Managers/bmc/LogServices/Dump/Actions/LogService.CollectDiagnosticData 249 ... body=${payload} valid_status_codes=[${HTTP_ACCEPTED}] 250 251 # Example of response from above Redfish POST request. 252 # "@odata.id": "/redfish/v1/TaskService/Tasks/0", 253 # "@odata.type": "#Task.v1_4_3.Task", 254 # "Id": "0", 255 # "TaskState": "Running", 256 # "TaskStatus": "OK" 257 258 [Return] ${resp.dict['Id']} 259 260Create User Initiated BMC Dump Via Redfish 261 [Documentation] Generate user initiated BMC dump via Redfish and return the dump id number (e.g., "5"). 262 263 ${payload}= Create Dictionary DiagnosticDataType=Manager 264 ${resp}= Redfish.Post /redfish/v1/Managers/bmc/LogServices/Dump/Actions/LogService.CollectDiagnosticData 265 ... body=${payload} valid_status_codes=[${HTTP_ACCEPTED}] 266 267 # Example of response from above Redfish POST request. 268 # "@odata.id": "/redfish/v1/TaskService/Tasks/0", 269 # "@odata.type": "#Task.v1_4_3.Task", 270 # "Id": "0", 271 # "TaskState": "Running", 272 # "TaskStatus": "OK" 273 274 Wait Until Keyword Succeeds 5 min 15 sec Check Task Completion ${resp.dict['Id']} 275 ${task_id}= Set Variable ${resp.dict['Id']} 276 277 ${task_dict}= Redfish.Get Properties /redfish/v1/TaskService/Tasks/${task_id} 278 279 # Example of HttpHeaders field of task details. 280 # "Payload": { 281 # "HttpHeaders": [ 282 # "Host: <BMC_IP>", 283 # "Accept-Encoding: identity", 284 # "Connection: Keep-Alive", 285 # "Accept: */*", 286 # "Content-Length: 33", 287 # "Location: /redfish/v1/Managers/bmc/LogServices/Dump/Entries/2"] 288 # ], 289 # "HttpOperation": "POST", 290 # "JsonBody": "{\"DiagnosticDataType\":\"Manager\"}", 291 # "TargetUri": "/redfish/v1/Managers/bmc/LogServices/Dump/Actions/LogService.CollectDiagnosticData" 292 # } 293 294 [Return] ${task_dict["Payload"]["HttpHeaders"][-1].split("/")[-1]} 295 296Auto Generate BMC Dump 297 [Documentation] Auto generate BMC dump. 298 299 ${cmd}= Catenate busctl --verbose call xyz.openbmc_project.Dump.Manager 300 ... /xyz/openbmc_project/dump/bmc xyz.openbmc_project.Dump.Create CreateDump a{sv} 0 301 ${stdout} ${stderr} ${rc}= 302 ... BMC Execute Command ${cmd} 303 [Return] ${stdout} ${stderr} ${rc} 304 305Get Dump Size 306 [Documentation] Get dump size. 307 [Arguments] ${dump_uri} 308 309 # Description of argument(s): 310 # dump_uri Dump URI 311 # (Eg. /xyz/openbmc_project/dump/bmc/entry/1). 312 313 # Example of Dump entry. 314 # "data": { 315 # "CompletedTime": 1616760931, 316 # "Elapsed": 1616760931, 317 # "OffloadUri": "", 318 # "Offloaded": false, 319 # "Password": "", 320 # "Size": 3056, 321 # "SourceDumpId": 117440513, 322 # "StartTime": 1616760931, 323 # "Status": "xyz.openbmc_project.Common.Progress.OperationStatus.Completed", 324 # "VSPString": "" 325 # }, 326 327 Log ${dump_uri} 328 ${dump_data}= Redfish.Get Properties ${dump_uri} 329 [Return] ${dump_data["data"]["Size"]} 330 331Get Dump ID 332 [Documentation] Return dump ID. 333 [Arguments] ${task_id} 334 335 # Description of argument(s): 336 # task_id Task ID. 337 338 # Example of HttpHeaders field of task details. 339 # "Payload": { 340 # "HttpHeaders": [ 341 # "Host: <BMC_IP>", 342 # "Accept-Encoding: identity", 343 # "Connection: Keep-Alive", 344 # "Accept: */*", 345 # "Content-Length: 33", 346 # "Location: /redfish/v1/Managers/bmc/LogServices/Dump/Entries/2"] 347 # ], 348 # "HttpOperation": "POST", 349 # "JsonBody": "{\"DiagnosticDataType\":\"Manager\"}", 350 # "TargetUri": 351 # "/redfish/v1/Managers/bmc/LogServices/Dump/Actions/LogService.CollectDiagnosticData" 352 # } 353 354 ${task_dict}= Redfish.Get Properties /redfish/v1/TaskService/Tasks/${task_id} 355 ${key} ${value}= Set Variable ${task_dict["Payload"]["HttpHeaders"][-1].split(":")} 356 Run Keyword If '${key}' != 'Location' Fail 357 [Return] ${value.strip('/').split('/')[-1]} 358 359Get Task Status 360 [Documentation] Return task status. 361 [Arguments] ${task_id} 362 363 # Description of argument(s): 364 # task_id Task ID. 365 366 ${resp}= Redfish.Get Properties /redfish/v1/TaskService/Tasks/${task_id} 367 [Return] ${resp['TaskState']} 368 369Check Task Completion 370 [Documentation] Check if the task is complete. 371 [Arguments] ${task_id} 372 373 # Description of argument(s): 374 # task_id Task ID. 375 376 ${task_dict}= Redfish.Get Properties /redfish/v1/TaskService/Tasks/${task_id} 377 Should Be Equal As Strings ${task_dict['TaskState']} Completed 378 379Get Dump ID And Status 380 [Documentation] Return dump ID and status. 381 [Arguments] ${task_id} 382 383 # Description of argument(s): 384 # task_id Task ID. 385 386 Wait Until Keyword Succeeds 10 min 15 sec Check Task Completion ${task_id} 387 ${dump_id}= Get Dump ID ${task_id} 388 [Return] ${dump_id} Completed 389