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/bmc 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/bmc 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 205Redfish Upload Image And Check Progress State 206 [Documentation] Code update with ApplyTime. 207 208 Log To Console Start uploading image to BMC. 209 Redfish Upload Image ${REDFISH_BASE_URI}UpdateService ${IMAGE_FILE_PATH} 210 Log To Console Completed image upload to BMC. 211 212 ${image_id}= Get Latest Image ID 213 Rprint Vars image_id 214 215 # We have noticed firmware inventory state Enabled quickly as soon the image 216 # is uploaded via redfish. 217 Wait Until Keyword Succeeds 2 min 05 sec 218 ... Check Image Update Progress State match_state='Disabled', 'Updating', 'Enabled' image_id=${image_id} 219 220 Wait Until Keyword Succeeds 8 min 10 sec 221 ... Check Image Update Progress State 222 ... match_state='Enabled' image_id=${image_id} 223 224 225Get Host Power State 226 [Documentation] Get host power state. 227 [Arguments] ${quiet}=0 228 229 # Description of arguments: 230 # quiet Indicates whether results should be printed. 231 232 ${state}= Redfish.Get Attribute 233 ... ${REDFISH_BASE_URI}Systems/system PowerState 234 Rqprint Vars state 235 236 [Return] ${state} 237 238 239Check Host Power State 240 [Documentation] Check that the machine's host state matches 241 ... the caller's required host state. 242 [Arguments] ${match_state} 243 244 # Description of argument(s): 245 # match_state The expected state. This may be one or more 246 # comma-separated values (e.g. "On", "Off"). 247 # If the actual state matches any of the 248 # states named in this argument, 249 # this keyword passes. 250 251 ${state}= Get Host Power State 252 Rvalid Value state valid_values=[${match_state}] 253 254 255Get System Firmware Details 256 [Documentation] Return dictionary of system firmware details. 257 258 # { 259 # FirmwareVersion: 2.8.0-dev-1067-gdc66ce1c5, 260 # BiosVersion: witherspoon-XXX-XX.X-X 261 # } 262 263 ${firmware_version}= Redfish Get BMC Version 264 ${bios_version}= Redfish Get Host Version 265 266 &{sys_firmware_dict}= Create Dictionary 267 Set To Dictionary 268 ... ${sys_firmware_dict} FirmwareVersion ${firmware_version} BiosVersion ${bios_version} 269 Rprint Vars sys_firmware_dict 270 271 [Return] &{sys_firmware_dict} 272 273 274Switch Backup Firmware Image To Functional 275 [Documentation] Switch the backup firmware image to make functional. 276 277 ${sw_inv}= Get Functional Firmware BMC image 278 ${nonfunctional_sw_inv}= Get Non Functional Firmware ${sw_inv} False 279 280 ${firmware_inv_path}= 281 ... Set Variable /redfish/v1/UpdateService/FirmwareInventory/${nonfunctional_sw_inv['image_id']} 282 283 # Below URI, change to backup image and reset the BMC. 284 Redfish.Patch /redfish/v1/Managers/bmc 285 ... body={'Links': {'ActiveSoftwareImage': {'@odata.id': '${firmware_inv_path}'}}} 286 287 288Create List Of Task 289 [Documentation] Return list of task id(s) from provided list of dictionary. 290 [Arguments] ${task_dict_list} 291 292 # Description of argument(s): 293 # task_dict_list Task id dictionary list. 294 295 # '@odata.id': '/redfish/v1/TaskService/Tasks/0' 296 297 ${task_list}= Create List 298 299 FOR ${task_dict} IN @{task_dict_list} 300 Append To List ${task_list} ${task_dict['@odata.id']} 301 END 302 303 [Return] ${task_list} 304 305 306Create Initiated Task State Dict 307 [Documentation] Create active task inventory dictionary as certain URI create task 308 ... to serve the user request. 309 [Arguments] ${task_obj} 310 311 # Description of argument(s): 312 # task_obj Task dictionary. 313 314 # task_inv 315 # TargetUri /redfish/v1/UpdateService 316 # TaskIdURI /redfish/v1/TaskService/Tasks/0 317 # TaskState Starting 318 # TaskStatus OK 319 320 ${task_inv}= Create Dictionary 321 Set To Dictionary ${task_inv} TargetUri ${task_obj['Payload']['TargetUri']} 322 Set To Dictionary ${task_inv} TaskIdURI ${task_obj['@odata.id']} 323 Set To Dictionary ${task_inv} TaskState ${task_obj['TaskState']} 324 Set To Dictionary ${task_inv} TaskStatus ${task_obj['TaskStatus']} 325 326 [Return] ${task_inv} 327 328 329Match Target URI 330 [Documentation] Match target uri from task list. 331 [Arguments] ${task_list} ${target_uri} 332 333 # Description of argument(s): 334 # task_list Task id list. 335 # target_uri Task created for target URI. 336 337 # target_uri /redfish/v1/UpdateService 338 339 FOR ${task_id} IN @{task_list} 340 ${task_payload}= Redfish.Get Properties ${task_id} 341 Run Keyword And Return If '${task_payload['Payload']['TargetUri']}' == '${target_uri}' Create Initiated Task State Dict ${task_payload} 342 END 343 344 345Check Task With Match TargetUri 346 [Documentation] Create task state dictionary. 347 [Arguments] ${target_uri}=/redfish/v1/TaskService/Tasks 348 349 # Description of argument(s): 350 # target_uri Target URI for which task is initiated. 351 352 ${task_dict_list}= Redfish.Get Attribute /redfish/v1/TaskService/Tasks Members 353 354 ${task_list}= Create List Of Task ${task_dict_list} 355 356 ${task_inv}= Match Target URI ${task_list} ${target_uri} 357 358 [Return] ${task_inv} 359 360 361Verify Task Progress State 362 [Documentation] Verify task progress matches the user expected task state. 363 [Arguments] ${task_inv} ${task_state} 364 365 # Description of argument(s): 366 # task_inv Initiated task inventory dict information. 367 # task_state Expected task state, user reference from data/task_state.json. 368 369 # task_inv 370 # TaskIdURI /redfish/v1/TaskService/Tasks/0 371 # TaskState Starting 372 # TaskStatus OK 373 374 ${task_payload}= Redfish.Get Properties ${task_inv['TaskIdURI']} 375 376 ${temp_task_inv}= Create Dictionary 377 Set To Dictionary ${temp_task_inv} TaskState ${task_payload['TaskState']} 378 Set To Dictionary ${temp_task_inv} TaskStatus ${task_payload['TaskStatus']} 379 380 Rprint Vars temp_task_inv 381 382 Should Be Equal As Strings ${task_state['TaskState']} ${task_payload['TaskState']} 383 Should Be Equal As Strings ${task_state['TaskStatus']} ${task_payload['TaskStatus']} 384 385