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    [Return]  ${functional}
33
34
35Get Software Inventory State
36    [Documentation]  Return dictionary of the image type, version and functional state
37    ...  of the software objects active on the system.
38
39    # User defined state for software objects.
40    # Note: "Functional" term refers to firmware which system is currently booted with.
41    # sw_inv_dict:
42    #   [ace821ef]:
43    #     [image_type]:                 Host update
44    #     [image_id]:                   ace821ef
45    #     [functional]:                 True
46    #     [version]:                    witherspoon-xx.xx.xx.xx
47    #   [b9101858]:
48    #     [image_type]:                 BMC update
49    #     [image_id]:                   b9101858
50    #     [functional]:                 True
51    #     [version]:                    2.8.0-dev-150-g04508dc9f
52    #   [c45eafa5]:
53    #     [image_type]:                 BMC update
54    #     [image_id]:                   c45eafa5
55    #     [functional]:                 False
56    #     [version]:                    2.8.0-dev-149-g1a8df5077
57
58    ${sw_member_list}=  Redfish_Utils.Get Member List  /redfish/v1/UpdateService/FirmwareInventory
59    &{sw_inv_dict}=  Create Dictionary
60
61    # sw_member_list:
62    #   [0]:                            /redfish/v1/UpdateService/FirmwareInventory/98744d76
63    #   [1]:                            /redfish/v1/UpdateService/FirmwareInventory/9a8028ec
64    #   [2]:                            /redfish/v1/UpdateService/FirmwareInventory/acc9e073
65
66    FOR  ${uri_path}  IN  @{sw_member_list}
67        &{tmp_dict}=  Create Dictionary
68
69        ${resp}=  Redfish.Get  ${uri_path}  valid_status_codes=[${HTTP_OK}, ${HTTP_INTERNAL_SERVER_ERROR}]
70        ${image_info}  Set Variable  ${resp.dict}
71
72        Set To Dictionary  ${tmp_dict}  image_type  ${image_info["Description"]}
73        Set To Dictionary  ${tmp_dict}  image_id  ${uri_path.split("/")[-1]}
74
75        ${functional}=  Get Software Functional State  ${uri_path.split("/")[-1]}
76
77        Set To Dictionary  ${tmp_dict}  functional  ${functional}
78        Set To Dictionary  ${tmp_dict}  version  ${image_info["Version"]}
79        Set To Dictionary  ${sw_inv_dict}  ${uri_path.split("/")[-1]}  ${tmp_dict}
80    END
81
82    [Return]  &{sw_inv_dict}
83
84
85Get Software Inventory State By Version
86    [Documentation]  Return the software inventory record that matches the given software version.
87    [Arguments]  ${software_version}
88
89    # If no matchine record can be found, return ${EMPTY}.
90
91    # Example of returned data:
92    # software_inventory_record:
93    #   [image_type]:      BMC update
94    #   [image_id]:        1e662ba8
95    #   [functional]:      True
96    #   [version]:         2.8.0-dev-150-g04508dc9f
97
98    # Description of argument(s):
99    # software_version     A BMC or Host version (e.g "2.8.0-dev-150-g04508dc9f").
100
101    ${software_inventory}=  Get Software Inventory State
102    # Filter out entries that don't match the criterion..
103    ${software_inventory}=  Filter Struct  ${software_inventory}  [('version', '${software_version}')]
104    # Convert from dictionary to list.
105    ${software_inventory}=  Get Dictionary Values  ${software_inventory}
106    ${num_records}=  Get Length  ${software_inventory}
107
108    Return From Keyword If  ${num_records} == ${0}  ${EMPTY}
109
110    # Return the first list entry.
111    [Return]  ${software_inventory}[0]
112
113
114Get BMC Functional Firmware
115    [Documentation]  Get BMC functional firmware details.
116
117    ${sw_inv}=  Get Functional Firmware  BMC update
118    ${sw_inv}=  Get Non Functional Firmware  ${sw_inv}  True
119
120    [Return]  ${sw_inv}
121
122
123Get Functional Firmware
124    [Documentation]  Get all the BMC firmware details.
125    [Arguments]  ${image_type}
126
127    # Description of argument(s):
128    # image_type    Image value can be either BMC update or Host update.
129
130    ${software_inventory}=  Get Software Inventory State
131    ${bmc_inv}=  Get BMC Firmware  ${image_type}  ${software_inventory}
132
133    [Return]  ${bmc_inv}
134
135
136Get Non Functional Firmware
137    [Documentation]  Get BMC non functional firmware details.
138    [Arguments]  ${sw_inv}  ${functional_state}
139
140    # Description of argument(s):
141    # sw_inv            This dictionary contains all the BMC firmware details.
142    # functional_state  Functional state can be either True or False.
143
144    ${resp}=  Filter Struct  ${sw_inv}  [('functional', ${functional_state})]
145
146    ${num_records}=  Get Length  ${resp}
147    Set Global Variable  ${num_records}
148    Return From Keyword If  ${num_records} == ${0}  ${EMPTY}
149
150    ${list_inv_dict}=  Get Dictionary Values  ${resp}
151
152    [Return]  ${list_inv_dict}[0]
153
154
155Get Non Functional Firmware List
156    [Documentation]  Get BMC non functional firmware details.
157    [Arguments]  ${sw_inv}  ${functional_state}
158
159    # Description of argument(s):
160    # sw_inv            This dictionary contains all the BMC firmware details.
161    # functional_state  Functional state can be either True or False.
162
163    ${list_inv}=  Create List
164
165    FOR  ${key}  IN  @{sw_inv.keys()}
166      Run Keyword If  '${sw_inv['${key}']['functional']}' == '${functional_state}'
167      ...  Append To List  ${list_inv}  ${sw_inv['${key}']}
168    END
169
170    [Return]  ${list_inv}
171
172
173Redfish Upload Image And Check Progress State
174    [Documentation]  Code update with ApplyTime.
175
176    Log To Console   Start uploading image to BMC.
177    Redfish Upload Image  ${REDFISH_BASE_URI}UpdateService  ${IMAGE_FILE_PATH}
178    Log To Console   Completed image upload to BMC.
179
180    ${image_id}=  Get Latest Image ID
181    Rprint Vars  image_id
182
183    # We have noticed firmware inventory state Enabled quickly as soon the image
184    # is uploaded via redfish.
185    Wait Until Keyword Succeeds  2 min  05 sec
186    ...  Check Image Update Progress State  match_state='Disabled', 'Updating', 'Enabled'  image_id=${image_id}
187
188    Wait Until Keyword Succeeds  8 min  10 sec
189    ...  Check Image Update Progress State
190    ...    match_state='Enabled'  image_id=${image_id}
191
192
193Get Host Power State
194    [Documentation]  Get host power state.
195    [Arguments]  ${quiet}=0
196
197    # Description of arguments:
198    # quiet    Indicates whether results should be printed.
199
200    ${state}=  Redfish.Get Attribute
201    ...  ${REDFISH_BASE_URI}Systems/system  PowerState
202    Rqprint Vars  state
203
204    [Return]  ${state}
205
206
207Check Host Power State
208    [Documentation]  Check that the machine's host state matches
209    ...  the caller's required host state.
210    [Arguments]  ${match_state}
211
212    # Description of argument(s):
213    # match_state    The expected state. This may be one or more
214    #                comma-separated values (e.g. "On", "Off").
215    #                If the actual state matches any of the
216    #                states named in this argument,
217    #                this keyword passes.
218
219    ${state}=  Get Host Power State
220    Rvalid Value  state  valid_values=[${match_state}]
221
222
223Get System Firmware Details
224    [Documentation]  Return dictionary of system firmware details.
225
226    # {
227    #    FirmwareVersion: 2.8.0-dev-1067-gdc66ce1c5,
228    #    BiosVersion: witherspoon-XXX-XX.X-X
229    # }
230
231    ${firmware_version}=  Redfish Get BMC Version
232    ${bios_version}=  Redfish Get Host Version
233
234    &{sys_firmware_dict}=  Create Dictionary
235    Set To Dictionary
236    ...  ${sys_firmware_dict}  FirmwareVersion  ${firmware_version}  BiosVersion  ${bios_version}
237    Rprint Vars  sys_firmware_dict
238
239    [Return]  &{sys_firmware_dict}
240
241
242Switch Backup Firmware Image To Functional
243   [Documentation]  Switch the backup firmware image to make functional.
244
245   ${sw_inv}=  Get Functional Firmware  BMC image
246   ${nonfunctional_sw_inv}=  Get Non Functional Firmware  ${sw_inv}  False
247
248   ${firmware_inv_path}=
249   ...  Set Variable  /redfish/v1/UpdateService/FirmwareInventory/${nonfunctional_sw_inv['image_id']}
250
251   # Below URI, change to backup image and reset the BMC.
252   Redfish.Patch  /redfish/v1/Managers/bmc
253   ...  body={'Links': {'ActiveSoftwareImage': {'@odata.id': '${firmware_inv_path}'}}}
254
255