1*** Settings *** 2Documentation Redfish BMC and PNOR software utilities keywords. 3 4Library code_update_utils.py 5Library gen_robot_valid.py 6Library tftp_update_utils.py 7Resource bmc_redfish_utils.robot 8Resource boot_utils.robot 9 10*** Keywords *** 11 12Get Software Functional State 13 [Documentation] Return functional or active state of the software (i.e. True/False). 14 [Arguments] ${image_id} 15 16 # Description of argument(s): 17 # image_id The image ID (e.g. "acc9e073"). 18 19 ${resp}= Redfish.Get /redfish/v1/UpdateService/FirmwareInventory/${image_id} 20 ... valid_status_codes=[${HTTP_OK}, ${HTTP_INTERNAL_SERVER_ERROR}] 21 ${image_info} Set Variable ${resp.dict} 22 23 ${sw_functional}= Run Keyword If 24 ... '${image_info["Description"]}' == 'BMC image' or '${image_info["Description"]}' == 'BMC update' 25 ... Redfish.Get Attribute /redfish/v1/Managers/${MANAGER_ID} FirmwareVersion 26 ... ELSE 27 ... Redfish.Get Attribute /redfish/v1/Systems/system BiosVersion 28 29 ${functional}= Run Keyword And Return Status 30 ... Should Be Equal ${sw_functional} ${image_info["Version"]} 31 32 # If they are not same, return from here. 33 Return From Keyword If '${functional}' == 'False' ${functional} 34 35 # WHen the functional and backup firmware versions are same, this ensure, we rightly set the 36 # test inventory dictionary for the firmware functional status. 37 Run Keyword If 38 ... '${image_info["Description"]}' == 'BMC image' or '${image_info["Description"]}' == 'BMC update' 39 ... Run Keyword And Return Find Active Software Image ${image_id} 40 41 [Return] ${functional} 42 43 44Find Active Software Image 45 [Documentation] Match the firmware id of ActiveSoftwareImage attribute with the input id. 46 ... The ActiveSoftwareImage id is the current functional BMC firmware. 47 [Arguments] ${image_id} 48 49 # Description of argument(s): 50 # image_id The image ID (e.g. "acc9e073"). 51 52 # This attribute tells which is the firmware version currently functional. 53 # "ActiveSoftwareImage": { 54 # "@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/5ca9fec0" 55 # }, 56 ${active_sw_img}= Redfish.Get Attribute /redfish/v1/Managers/${MANAGER_ID} Links 57 58 ${active_id}= Set Variable ${active_sw_img["ActiveSoftwareImage"]["@odata.id"].split("/")[-1]} 59 60 ${matched_functional}= Run Keyword And Return Status 61 ... Should Be Equal As Strings ${image_id} ${active_id} 62 63 # Returns True if matched else False. 64 [Return] ${matched_functional} 65 66 67Get Software Inventory State 68 [Documentation] Return dictionary of the image type, version and functional state 69 ... of the software objects active on the system. 70 71 # User defined state for software objects. 72 # Note: "Functional" term refers to firmware which system is currently booted with. 73 # sw_inv_dict: 74 # [ace821ef]: 75 # [image_type]: Host update 76 # [image_id]: ace821ef 77 # [functional]: True 78 # [version]: witherspoon-xx.xx.xx.xx 79 # [b9101858]: 80 # [image_type]: BMC update 81 # [image_id]: b9101858 82 # [functional]: True 83 # [version]: 2.8.0-dev-150-g04508dc9f 84 # [c45eafa5]: 85 # [image_type]: BMC update 86 # [image_id]: c45eafa5 87 # [functional]: False 88 # [version]: 2.8.0-dev-149-g1a8df5077 89 90 ${sw_member_list}= Redfish_Utils.Get Member List /redfish/v1/UpdateService/FirmwareInventory 91 &{sw_inv_dict}= Create Dictionary 92 93 # sw_member_list: 94 # [0]: /redfish/v1/UpdateService/FirmwareInventory/98744d76 95 # [1]: /redfish/v1/UpdateService/FirmwareInventory/9a8028ec 96 # [2]: /redfish/v1/UpdateService/FirmwareInventory/acc9e073 97 98 FOR ${uri_path} IN @{sw_member_list} 99 &{tmp_dict}= Create Dictionary 100 101 ${resp}= Redfish.Get ${uri_path} valid_status_codes=[${HTTP_OK}, ${HTTP_INTERNAL_SERVER_ERROR}] 102 ${image_info} Set Variable ${resp.dict} 103 104 Set To Dictionary ${tmp_dict} image_type ${image_info["Description"]} 105 Set To Dictionary ${tmp_dict} image_id ${uri_path.split("/")[-1]} 106 107 ${functional}= Get Software Functional State ${uri_path.split("/")[-1]} 108 109 Set To Dictionary ${tmp_dict} functional ${functional} 110 Set To Dictionary ${tmp_dict} version ${image_info["Version"]} 111 Set To Dictionary ${sw_inv_dict} ${uri_path.split("/")[-1]} ${tmp_dict} 112 END 113 114 [Return] &{sw_inv_dict} 115 116 117Get Software Inventory State By Version 118 [Documentation] Return the software inventory record that matches the given software version. 119 [Arguments] ${software_version} 120 121 # If no matchine record can be found, return ${EMPTY}. 122 123 # Example of returned data: 124 # software_inventory_record: 125 # [image_type]: BMC update 126 # [image_id]: 1e662ba8 127 # [functional]: True 128 # [version]: 2.8.0-dev-150-g04508dc9f 129 130 # Description of argument(s): 131 # software_version A BMC or Host version (e.g "2.8.0-dev-150-g04508dc9f"). 132 133 ${software_inventory}= Get Software Inventory State 134 # Filter out entries that don't match the criterion.. 135 ${software_inventory}= Filter Struct ${software_inventory} [('version', '${software_version}')] 136 # Convert from dictionary to list. 137 ${software_inventory}= Get Dictionary Values ${software_inventory} 138 ${num_records}= Get Length ${software_inventory} 139 140 Return From Keyword If ${num_records} == ${0} ${EMPTY} 141 142 # Return the first list entry. 143 [Return] ${software_inventory}[0] 144 145 146Get BMC Functional Firmware 147 [Documentation] Get BMC functional firmware details. 148 149 ${sw_inv}= Get Functional Firmware BMC update 150 ${sw_inv}= Get Non Functional Firmware ${sw_inv} True 151 152 [Return] ${sw_inv} 153 154 155Get Functional Firmware 156 [Documentation] Get all the BMC firmware details. 157 [Arguments] ${image_type} 158 159 # Description of argument(s): 160 # image_type Image value can be either BMC update or Host update. 161 162 ${software_inventory}= Get Software Inventory State 163 ${bmc_inv}= Get BMC Firmware ${image_type} ${software_inventory} 164 165 [Return] ${bmc_inv} 166 167 168Get Non Functional Firmware 169 [Documentation] Get BMC non functional firmware details. 170 [Arguments] ${sw_inv} ${functional_state} 171 172 # Description of argument(s): 173 # sw_inv This dictionary contains all the BMC firmware details. 174 # functional_state Functional state can be either True or False. 175 176 ${resp}= Filter Struct ${sw_inv} [('functional', ${functional_state})] 177 178 ${num_records}= Get Length ${resp} 179 Set Global Variable ${num_records} 180 Return From Keyword If ${num_records} == ${0} ${EMPTY} 181 182 ${list_inv_dict}= Get Dictionary Values ${resp} 183 184 [Return] ${list_inv_dict}[0] 185 186 187Get Non Functional Firmware List 188 [Documentation] Get BMC non functional firmware details. 189 [Arguments] ${sw_inv} ${functional_state} 190 191 # Description of argument(s): 192 # sw_inv This dictionary contains all the BMC firmware details. 193 # functional_state Functional state can be either True or False. 194 195 ${list_inv}= Create List 196 197 FOR ${key} IN @{sw_inv.keys()} 198 Run Keyword If '${sw_inv['${key}']['functional']}' == '${functional_state}' 199 ... Append To List ${list_inv} ${sw_inv['${key}']} 200 END 201 202 [Return] ${list_inv} 203 204 205Get Redfish Update Service URI 206 [Documentation] Get Redfish firmware update URI. 207 208 ${update_url}= Redfish.Get Attribute ${REDFISH_BASE_URI}UpdateService HttpPushUri 209 210 Log To Console Firmware update URI: ${update_url} 211 212 [Return] ${update_url} 213 214 215Redfish Upload Image And Check Progress State 216 [Documentation] Code update with ApplyTime. 217 218 Log To Console Start uploading image to BMC. 219 220 # URI : /redfish/v1/UpdateService 221 # "HttpPushUri": "/redfish/v1/UpdateService/update", 222 223 ${redfish_update_uri}= Get Redfish Update Service URI 224 Redfish Upload Image ${redfish_update_uri} ${IMAGE_FILE_PATH} 225 Log To Console Completed image upload to BMC. 226 227 ${image_id}= Get Latest Image ID 228 Rprint Vars image_id 229 230 # We have noticed firmware inventory state Enabled quickly as soon the image 231 # is uploaded via redfish. 232 Wait Until Keyword Succeeds 2 min 05 sec 233 ... Check Image Update Progress State match_state='Disabled', 'Updating', 'Enabled' image_id=${image_id} 234 235 Wait Until Keyword Succeeds 8 min 10 sec 236 ... Check Image Update Progress State 237 ... match_state='Enabled' image_id=${image_id} 238 239 240Get Host Power State 241 [Documentation] Get host power state. 242 [Arguments] ${quiet}=0 243 244 # Description of arguments: 245 # quiet Indicates whether results should be printed. 246 247 ${state}= Redfish.Get Attribute 248 ... ${REDFISH_BASE_URI}Systems/system PowerState 249 Rqprint Vars state 250 251 [Return] ${state} 252 253 254Check Host Power State 255 [Documentation] Check that the machine's host state matches 256 ... the caller's required host state. 257 [Arguments] ${match_state} 258 259 # Description of argument(s): 260 # match_state The expected state. This may be one or more 261 # comma-separated values (e.g. "On", "Off"). 262 # If the actual state matches any of the 263 # states named in this argument, 264 # this keyword passes. 265 266 ${state}= Get Host Power State 267 Rvalid Value state valid_values=[${match_state}] 268 269 270Get System Firmware Details 271 [Documentation] Return dictionary of system firmware details. 272 273 # { 274 # FirmwareVersion: 2.8.0-dev-1067-gdc66ce1c5, 275 # BiosVersion: witherspoon-XXX-XX.X-X 276 # } 277 278 ${firmware_version}= Redfish Get BMC Version 279 ${bios_version}= Redfish Get Host Version 280 281 &{sys_firmware_dict}= Create Dictionary 282 Set To Dictionary 283 ... ${sys_firmware_dict} FirmwareVersion ${firmware_version} BiosVersion ${bios_version} 284 Rprint Vars sys_firmware_dict 285 286 [Return] &{sys_firmware_dict} 287 288 289Switch Backup Firmware Image To Functional 290 [Documentation] Switch the backup firmware image to make functional. 291 292 ${sw_inv}= Get Functional Firmware BMC image 293 ${nonfunctional_sw_inv}= Get Non Functional Firmware ${sw_inv} False 294 295 ${firmware_inv_path}= 296 ... Set Variable /redfish/v1/UpdateService/FirmwareInventory/${nonfunctional_sw_inv['image_id']} 297 298 # Below URI, change to backup image and reset the BMC. 299 Redfish.Patch /redfish/v1/Managers/${MANAGER_ID} 300 ... body={'Links': {'ActiveSoftwareImage': {'@odata.id': '${firmware_inv_path}'}}} 301 302 303Create List Of Task 304 [Documentation] Return list of task id(s) from provided list of dictionary. 305 [Arguments] ${task_dict_list} 306 307 # Description of argument(s): 308 # task_dict_list Task id dictionary list. 309 310 # '@odata.id': '/redfish/v1/TaskService/Tasks/0' 311 312 ${task_list}= Create List 313 314 FOR ${task_dict} IN @{task_dict_list} 315 Append To List ${task_list} ${task_dict['@odata.id']} 316 END 317 318 [Return] ${task_list} 319 320 321Create Initiated Task State Dict 322 [Documentation] Create active task inventory dictionary as certain URI create task 323 ... to serve the user request. 324 [Arguments] ${task_obj} 325 326 # Description of argument(s): 327 # task_obj Task dictionary. 328 329 # task_inv 330 # TargetUri /redfish/v1/UpdateService 331 # TaskIdURI /redfish/v1/TaskService/Tasks/0 332 # TaskState Starting 333 # TaskStatus OK 334 335 ${task_inv}= Create Dictionary 336 Set To Dictionary ${task_inv} TargetUri ${task_obj['Payload']['TargetUri']} 337 Set To Dictionary ${task_inv} TaskIdURI ${task_obj['@odata.id']} 338 Set To Dictionary ${task_inv} TaskState ${task_obj['TaskState']} 339 Set To Dictionary ${task_inv} TaskStatus ${task_obj['TaskStatus']} 340 341 [Return] ${task_inv} 342 343 344Get Task Inventory 345 [Documentation] Return task inventory. 346 [Arguments] ${task_info} 347 348 # Description of argument(s): 349 # task_info Task information. 350 351 # Task information. 352 # @odata.id: /redfish/v1/TaskService/Tasks/1 353 # Id: 1 354 # TaskState: Starting 355 # TaskStatus: OK 356 357 ${task_payload}= Redfish.Get Properties ${task_info['@odata.id']} 358 359 ${task_inv}= Create Initiated Task State Dict ${task_payload} 360 361 [Return] ${task_inv} 362 363 364Match Target URI 365 [Documentation] Match target uri from task list. 366 [Arguments] ${task_list} ${target_uri} 367 368 # Description of argument(s): 369 # task_list Task id list. 370 # target_uri Task created for target URI. 371 372 # target_uri /redfish/v1/UpdateService 373 374 FOR ${task_id} IN @{task_list} 375 ${task_payload}= Redfish.Get Properties ${task_id} 376 Run Keyword And Return If '${task_payload['Payload']['TargetUri']}' == '${target_uri}' Create Initiated Task State Dict ${task_payload} 377 END 378 379 380Check Task With Match TargetUri 381 [Documentation] Create task state dictionary. 382 [Arguments] ${target_uri}=/redfish/v1/TaskService/Tasks 383 384 # Description of argument(s): 385 # target_uri Target URI for which task is initiated. 386 387 ${task_dict_list}= Redfish.Get Attribute /redfish/v1/TaskService/Tasks Members 388 389 ${task_list}= Create List Of Task ${task_dict_list} 390 391 ${task_inv}= Match Target URI ${task_list} ${target_uri} 392 393 [Return] ${task_inv} 394 395 396Verify Task Progress State 397 [Documentation] Verify task progress matches the user expected task state. 398 [Arguments] ${task_inv} ${task_state} 399 400 # Description of argument(s): 401 # task_inv Initiated task inventory dict information. 402 # task_state Expected task state, user reference from data/task_state.json. 403 404 # task_inv 405 # TaskIdURI /redfish/v1/TaskService/Tasks/0 406 # TaskState Starting 407 # TaskStatus OK 408 409 ${task_payload}= Redfish.Get Properties ${task_inv['TaskIdURI']} 410 411 ${temp_task_inv}= Create Dictionary 412 Set To Dictionary ${temp_task_inv} TaskState ${task_payload['TaskState']} 413 Set To Dictionary ${temp_task_inv} TaskStatus ${task_payload['TaskStatus']} 414 415 Rprint Vars temp_task_inv 416 417 Should Be Equal As Strings ${task_state['TaskState']} ${task_payload['TaskState']} 418 Should Be Equal As Strings ${task_state['TaskStatus']} ${task_payload['TaskStatus']} 419 420