1*** Settings *** 2Documentation BMC and PNOR update utilities keywords. 3 4Library code_update_utils.py 5Library OperatingSystem 6Library String 7Library utilities.py 8Variables ../data/variables.py 9Resource boot_utils.robot 10Resource rest_client.robot 11Resource openbmc_ffdc.robot 12 13*** Keywords *** 14 15Get Software Objects 16 [Documentation] Get the host software objects and return as a list. 17 [Arguments] ${version_type}=${VERSION_PURPOSE_HOST} 18 19 # Description of argument(s): 20 # version_type Either BMC or host version purpose. 21 # By default host version purpose string. 22 # (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC" 23 # "xyz.openbmc_project.Software.Version.VersionPurpose.Host"). 24 25 # Example: 26 # "data": [ 27 # "/xyz/openbmc_project/software/f3b29aa8", 28 # "/xyz/openbmc_project/software/e49bc78e", 29 # ], 30 # Iterate the list and return the host object name path list. 31 32 ${host_list}= Create List 33 ${sw_list}= Read Properties ${SOFTWARE_VERSION_URI} 34 35 :FOR ${index} IN @{sw_list} 36 \ ${attr_purpose}= Read Software Attribute ${index} Purpose 37 \ Continue For Loop If '${attr_purpose}' != '${version_type}' 38 \ Append To List ${host_list} ${index} 39 40 [Return] ${host_list} 41 42 43Read Software Attribute 44 [Documentation] Return software attribute data. 45 [Arguments] ${software_object} ${attribute_name} 46 47 # Description of argument(s): 48 # software_object Software object path. 49 # (e.g. "/xyz/openbmc_project/software/f3b29aa8"). 50 # attribute_name Software object attribute name. 51 52 ${resp}= OpenBMC Get Request ${software_object}/attr/${attribute_name} 53 ... quiet=${1} 54 Return From Keyword If ${resp.status_code} != ${HTTP_OK} 55 ${content}= To JSON ${resp.content} 56 [Return] ${content["data"]} 57 58 59Get Software Objects Id 60 [Documentation] Get the software objects id and return as a list. 61 [Arguments] ${version_type}=${VERSION_PURPOSE_HOST} 62 63 # Description of argument(s): 64 # version_type Either BMC or host version purpose. 65 # By default host version purpose string. 66 # (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC" 67 # "xyz.openbmc_project.Software.Version.VersionPurpose.Host"). 68 69 ${sw_id_list}= Create List 70 ${sw_list}= Get Software Objects ${version_type} 71 72 :FOR ${index} IN @{sw_list} 73 \ Append To List ${sw_id_list} ${index.rsplit('/', 1)[1]} 74 75 [Return] ${sw_id_list} 76 77 78Get Host Software Property 79 [Documentation] Return a dictionary of host software properties. 80 [Arguments] ${host_object} 81 82 # Description of argument(s): 83 # host_object Host software object path. 84 # (e.g. "/xyz/openbmc_project/software/f3b29aa8"). 85 86 ${sw_attributes}= Read Properties ${host_object} 87 [return] ${sw_attributes} 88 89Get Host Software Objects Details 90 [Documentation] Return software object details as a list of dictionaries. 91 [Arguments] ${quiet}=${QUIET} 92 93 ${software}= Create List 94 95 ${pnor_details}= Get Software Objects ${VERSION_PURPOSE_HOST} 96 :FOR ${pnor} IN @{pnor_details} 97 \ ${resp}= OpenBMC Get Request ${pnor} quiet=${1} 98 \ ${json}= To JSON ${resp.content} 99 \ Append To List ${software} ${json["data"]} 100 101 [Return] ${software} 102 103Set Host Software Property 104 [Documentation] Set the host software properties of a given object. 105 [Arguments] ${host_object} ${sw_attribute} ${data} 106 107 # Description of argument(s): 108 # host_object Host software object name. 109 # sw_attribute Host software attribute name. 110 # (e.g. "Activation", "Priority", "RequestedActivation" etc). 111 # data Value to be written. 112 113 ${args}= Create Dictionary data=${data} 114 Write Attribute ${host_object} ${sw_attribute} data=${args} 115 # Sync time for software updater manager to update. 116 # TODO: openbmc/openbmc#2857 117 Sleep 10s 118 119 120Set Property To Invalid Value And Verify No Change 121 [Documentation] Attempt to set a property and check that the value didn't 122 ... change. 123 [Arguments] ${property} ${version_type} 124 125 # Description of argument(s): 126 # property The property to attempt to set. 127 # version_type Either BMC or host version purpose. 128 # By default host version purpose string. 129 # (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC" 130 # "xyz.openbmc_project.Software.Version.VersionPurpose.Host"). 131 132 ${software_objects}= Get Software Objects version_type=${version_type} 133 ${prev_properties}= Get Host Software Property @{software_objects}[0] 134 Run Keyword And Expect Error 500 != 200 135 ... Set Host Software Property @{software_objects}[0] ${property} foo 136 ${cur_properties}= Get Host Software Property @{software_objects}[0] 137 Should Be Equal As Strings &{prev_properties}[${property}] 138 ... &{cur_properties}[${property}] 139 140 141Set Priority To Invalid Value And Expect Error 142 [Documentation] Set the priority of an image to an invalid value and 143 ... check that an error was returned. 144 [Arguments] ${version_type} ${priority} 145 146 # Description of argument(s): 147 # version_type Either BMC or host version purpose. 148 # (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC" 149 # "xyz.openbmc_project.Software.Version.VersionPurpose.Host"). 150 # priority The priority value to set. Should be an integer outside of 151 # the range of 0 through 255. 152 153 ${images}= Get Software Objects version_type=${version_type} 154 ${num_images}= Get Length ${images} 155 Should Be True 0 < ${num_images} 156 157 Run Keyword And Expect Error 403 != 200 158 ... Set Host Software Property @{images}[0] Priority ${priority} 159 160 161Upload And Activate Image 162 [Documentation] Upload an image to the BMC and activate it with REST. 163 [Arguments] ${image_file_path} ${wait}=${1} ${skip_if_active}=false 164 165 # Description of argument(s): 166 # image_file_path The path to the image tarball to upload and activate. 167 # wait Indicates that this keyword should wait for host or 168 # BMC activation is completed. 169 # skip_if_active If set to true, will skip the code update if this 170 # image is already on the BMC. 171 172 OperatingSystem.File Should Exist ${image_file_path} 173 ${image_version}= Get Version Tar ${image_file_path} 174 175 ${image_data}= OperatingSystem.Get Binary File ${image_file_path} 176 177 Wait Until Keyword Succeeds 3 times 60 sec 178 ... Upload Image To BMC /upload/image timeout=${30} data=${image_data} 179 ${ret} ${version_id}= Verify Image Upload ${image_version} 180 Should Be True ${ret} 181 182 # Verify the image is 'READY' to be activated or if it's already active, 183 # set priority to 0 and reboot the BMC. 184 ${software_state}= Read Properties ${SOFTWARE_VERSION_URI}${version_id} 185 ${activation}= Set Variable &{software_state}[Activation] 186 187 Run Keyword If 188 ... '${skip_if_active}' == 'true' and '${activation}' == '${ACTIVE}' 189 ... Run Keywords 190 ... Set Host Software Property ${SOFTWARE_VERSION_URI}${version_id} 191 ... Priority ${0} 192 ... AND 193 ... Return From Keyword 194 195 Should Be Equal As Strings &{software_state}[Activation] ${READY} 196 197 # Request the image to be activated. 198 ${args}= Create Dictionary data=${REQUESTED_ACTIVE} 199 Write Attribute ${SOFTWARE_VERSION_URI}${version_id} 200 ... RequestedActivation data=${args} 201 ${software_state}= Read Properties ${SOFTWARE_VERSION_URI}${version_id} 202 Should Be Equal As Strings &{software_state}[RequestedActivation] 203 ... ${REQUESTED_ACTIVE} 204 205 # Does caller want to wait for activation to complete? 206 Return From Keyword If '${wait}' == '${0}' ${version_id} 207 208 # Verify code update was successful and Activation state is Active. 209 Wait For Activation State Change ${version_id} ${ACTIVATING} 210 ${software_state}= Read Properties ${SOFTWARE_VERSION_URI}${version_id} 211 Should Be Equal As Strings &{software_state}[Activation] ${ACTIVE} 212 213 # Uploaded and activated image should have priority set to 0. Due to timing 214 # contention, it may take up to 10 seconds to complete updating priority. 215 Wait Until Keyword Succeeds 10 sec 5 sec 216 ... Check Software Object Attribute ${version_id} Priority ${0} 217 218 [Return] ${version_id} 219 220 221Attempt To Reboot BMC During Image Activation 222 [Documentation] Attempt to reboot the BMC while an image is activating and 223 ... check that the BMC ignores the reboot command and finishes 224 ... activation. 225 [Arguments] ${image_file_path} 226 227 # Description of argument(s): 228 # image_file_path Path to the image to update to. 229 230 # Attempt to reboot during activation. 231 ${version_id}= Upload And Activate Image ${image_file_path} 232 ... wait=${0} 233 ${resp}= OpenBMC Get Request ${SOFTWARE_VERSION_URI}${version_id} 234 Should Be Equal As Strings ${resp.status_code} ${HTTP_OK} 235 236 OBMC Reboot (off) 237 238 ${resp}= OpenBMC Get Request ${SOFTWARE_VERSION_URI}${version_id} 239 Should Be Equal As Strings ${resp.status_code} ${HTTP_NOT_FOUND} 240 241 242Activate Image And Verify No Duplicate Priorities 243 [Documentation] Upload an image, and then check that no images have the 244 ... same priority. 245 [Arguments] ${image_file_path} ${image_purpose} 246 247 # Description of argument(s): 248 # image_file_path The path to the image to upload. 249 # image_purpose The purpose in the image's MANIFEST file. 250 251 Upload And Activate Image ${image_file_path} skip_if_active=true 252 Verify No Duplicate Image Priorities ${image_purpose} 253 254 255Set Same Priority For Multiple Images 256 [Documentation] Find two images, set the priorities to be the same, and 257 ... verify that the priorities are not the same. 258 [Arguments] ${version_purpose} 259 260 # Description of argument(s): 261 # version_purpose Either BMC or host version purpose. 262 # (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC" 263 # "xyz.openbmc_project.Software.Version.VersionPurpose.Host"). 264 265 # Make sure we have more than two images. 266 ${software_objects}= Get Software Objects version_type=${version_purpose} 267 ${num_images}= Get Length ${software_objects} 268 Should Be True 1 < ${num_images} 269 ... msg=Only found one image on the BMC with purpose ${version_purpose}. 270 271 # Set the priority of the second image to the priority of the first. 272 ${properties}= Get Host Software Property @{software_objects}[0] 273 Set Host Software Property @{software_objects}[1] Priority 274 ... &{properties}[Priority] 275 Verify No Duplicate Image Priorities ${version_purpose} 276 277 # Set the priority of the first image back to what it was before 278 Set Host Software Property @{software_objects}[0] Priority 279 ... &{properties}[Priority] 280 281 282Delete Software Object 283 [Documentation] Deletes an image from the BMC. 284 [Arguments] ${software_object} 285 286 # Description of argument(s): 287 # software_object The URI to the software image to delete. 288 289 ${arglist}= Create List 290 ${args}= Create Dictionary data=${arglist} 291 ${resp}= OpenBMC Post Request ${software_object}/action/delete 292 ... data=${args} 293 Should Be Equal As Strings ${resp.status_code} ${HTTP_OK} 294 295 296Delete Image And Verify 297 [Documentation] Delete an image from the BMC and verify that it was 298 ... removed from software and the /tmp/images directory. 299 [Arguments] ${software_object} ${version_type} 300 301 # Description of argument(s): 302 # software_object The URI of the software object to delete. 303 # version_type The type of the software object, e.g. 304 # xyz.openbmc_project.Software.Version.VersionPurpose.Host 305 # or xyz.openbmc_project.Software.Version.VersionPurpose.BMC. 306 307 Log To Console Deleting ${software_object} 308 309 # Delete the image. 310 Delete Software Object ${software_object} 311 # TODO: If/when we don't have to delete twice anymore, take this out 312 Run Keyword And Ignore Error Delete Software Object ${software_object} 313 314 # Verify that it's gone from software. 315 ${software_objects}= Get Software Objects version_type=${version_type} 316 Should Not Contain ${software_objects} ${software_object} 317 318 # Check that there is no file in the /tmp/images directory. 319 ${image_id}= Fetch From Right ${software_object} / 320 BMC Execute Command 321 ... [ ! -d "/tmp/images/${image_id}" ] 322 323 324Delete All Non Running BMC Images 325 [Documentation] Delete all BMC images that are not running on the BMC. 326 327 @{datalist}= Create List 328 ${data}= Create Dictionary data=@{datalist} 329 Call Method ${SOFTWARE_VERSION_URI} DeleteAll data=${data} 330 331 332Check Error And Collect FFDC 333 [Documentation] Collect FFDC if error log exists. 334 335 ${status}= Run Keyword And Return Status Error Logs Should Not Exist 336 Run Keyword If '${status}' == 'False' FFDC 337 Delete Error Logs 338 339 340Verify Running BMC Image 341 [Documentation] Verify that the version on the BMC is the same as the 342 ... version in the given image. 343 [Arguments] ${image_file_path} 344 345 # Description of argument(s): 346 # image_file_path Path to the BMC image tarball. 347 348 ${tar_version}= Get Version Tar ${image_file_path} 349 ${bmc_version}= Get BMC Version 350 ${bmc_version}= Remove String ${bmc_version} " 351 Should Be Equal ${tar_version} ${bmc_version} 352 353 354Verify Running Host Image 355 [Documentation] Verify that the version of the PNOR image that is on the 356 ... BMC is the same as the one in the given image. 357 [Arguments] ${image_file_path} 358 359 # Description of argument(s): 360 # image_file_path Path to the PNOR image tarball. 361 362 ${tar_version}= Get Version Tar ${image_file_path} 363 ${pnor_version}= Get PNOR Version 364 Should Be Equal ${tar_version} ${pnor_version} 365 366 367Get Least Value Priority Image 368 [Documentation] Find the least value in "Priority" attribute and return. 369 [Arguments] ${version_type} 370 371 # Description of argument(s): 372 # version_type Either BMC or host version purpose. 373 374 ${priority_value_list}= Create List 375 ${sw_list}= Get Software Objects version_type=${version_type} 376 377 :FOR ${index} IN @{sw_list} 378 \ ${priority_value}= 379 ... Read Software Attribute ${index} Priority 380 \ Append To List ${priority_value_list} ${priority_value} 381 382 ${min_value}= Min List Value ${priority_value_list} 383 384 [Return] ${min_value} 385 386 387Enable Field Mode And Verify Unmount 388 [Documentation] Enable field mode and check that /usr/local is unmounted. 389 390 # After running, /xyz/openbmc_project/software should look like this: 391 # /xyz/openbmc_project/software 392 # { 393 # "FieldModeEnabled": 1, 394 # "associations": [ 395 # [ 396 # "active", 397 # "software_version", 398 # "/xyz/openbmc_project/software/fcf8e182" 399 # ], 400 # [ 401 # "functional", 402 # "functional", 403 # "/xyz/openbmc_project/software/fcf8e182" 404 # ] 405 # ] 406 # } 407 408 ${args}= Create Dictionary data=${1} 409 Write Attribute ${SOFTWARE_VERSION_URI} FieldModeEnabled data=${args} 410 Sleep 5s 411 BMC Execute Command [ ! -d "/usr/local/share" ] 412 413 414Disable Field Mode And Verify Unmount 415 [Documentation] Disable field mode, unmask usr local mount and reboot. 416 417 BMC Execute Command /sbin/fw_setenv fieldmode 418 BMC Execute Command /bin/systemctl unmask usr-local.mount 419 OBMC Reboot (off) stack_mode=normal 420 BMC Execute Command [ -d "/usr/local/share" ] 421 422 423Field Mode Should Be Enabled 424 [Documentation] Check that field mode is enabled. 425 426 ${value}= Read Attribute ${SOFTWARE_VERSION_URI} FieldModeEnabled 427 Should Be True ${value} ${1} 428 429List Installed Images 430 [Documentation] List all the installed images. 431 [Arguments] ${image_type} 432 433 # Description of argument(s): 434 # image_type Either "BMC" or "PNOR". 435 436 # List the installed images. 437 ${installed_images}= Get Software Objects 438 ... ${SOFTWARE_PURPOSE}.${image_type} 439 440 Run Keyword If ${installed_images} != [] 441 ... Get List of Images ${installed_images} 442 ... ELSE Log No ${image_type} images are present. 443 444Get List of Images 445 [Documentation] Get List of Images 446 [Arguments] ${installed_images} 447 448 :FOR ${uri} IN @{installed_images} 449 \ ${resp}= OpenBMC Get Request ${uri} 450 \ ${json}= To JSON ${resp.content} 451 \ Log ${json["data"]} 452 453 454Check Software Object Attribute 455 [Documentation] Get the software property of a given object and verify. 456 [Arguments] ${image_object} ${sw_attribute} ${value} 457 458 # Description of argument(s): 459 # image_object Image software object name. 460 # sw_attribute Software attribute name. 461 # (e.g. "Activation", "Priority", "RequestedActivation" etc). 462 # value Software attribute value to compare. 463 464 ${data}= Read Attribute 465 ... ${SOFTWARE_VERSION_URI}${image_object} ${sw_attribute} 466 467 Should Be True ${data} == ${value} 468 ... msg=Given attribute value ${data} mismatch ${value}. 469 470 471Image Should Be Signed 472 [Documentation] Fail if the image is not signed. 473 474 Directory Should Exist ${ACTIVATION_DIR_PATH} 475 ... msg=${ACTIVATION_DIR_PATH} does not exist. Therefore, the image is not signed. 476 477 478Get Latest Image ID 479 [Documentation] Return the ID of the most recently extracted image. 480 # Note: This keyword will fail if there is no such file. 481 482 # Example: # ls /tmp/images/ 483 # 1b714fb7 484 ${image_id}= Get Latest File /tmp/images/ 485 Rvalid Value image_id 486 487 # Though an image sub-directory was found, it really isn't valid unless 488 # the MANIFEST file is present. 489 BMC Execute Command ls -l /tmp/images/${image_id}/MANIFEST 490 491 [Return] ${image_id} 492 493 494Check Image Update Progress State 495 [Documentation] Check that the image update progress state matches the specified state. 496 [Arguments] ${match_state} ${image_id} 497 498 # Description of argument(s): 499 # match_state The expected state. This may be one or more comma-separated values 500 # (e.g. "Disabled", "Disabled, Updating"). If the actual state matches 501 # any of the states named in this argument, this keyword passes. 502 # image_id The image ID (e.g. "1b714fb7"). 503 504 ${state}= Get Image Update Progress State image_id=${image_id} 505 Rvalid Value state valid_values=[${match_state}] 506 507 508Get Image Update Progress State 509 [Documentation] Return the current state of the image update. 510 [Arguments] ${image_id} 511 512 # Description of argument(s): 513 # image_id The image ID (e.g. "1b714fb7"). 514 515 # In this example, this keyword would return the value "Enabled". 516 # "Status": { 517 # "Health": "OK", 518 # "HealthRollup": "OK", 519 # "State": "Enabled" 520 # }, 521 ${status}= Redfish.Get Attribute /redfish/v1/UpdateService/FirmwareInventory/${image_id} Status 522 Rprint Vars status 523 524 [Return] ${status["State"]} 525 526 527Get Firmware Image Version 528 [Documentation] Get the version of the currently installed firmware and return it. 529 [Arguments] ${image_id} 530 531 # Description of argument(s): 532 # image_id The image ID (e.g. "1b714fb7"). 533 534 # Example of a version returned by this keyword: 535 # 2.8.0-dev-19-g6d5764b33 536 ${version}= Redfish.Get Attribute /redfish/v1/UpdateService/FirmwareInventory/${image_id} Version 537 Rprint Vars version 538 539 [Return] ${version} 540