blob: ba12274898043461a751201ded1d34b45c1e8df0 [file] [log] [blame]
Michael Walshb973f9b2018-09-19 16:00:06 -05001#!/usr/bin/env python
2
3r"""
4This module provides many valuable openbmctool.py functions such as
5openbmctool_execute_command.
6"""
7
Michael Walshd064ac92018-09-21 16:42:03 -05008import gen_print as gp
Michael Walshb973f9b2018-09-19 16:00:06 -05009import gen_cmd as gc
10import gen_valid as gv
Michael Walshd064ac92018-09-21 16:42:03 -050011import gen_misc as gm
12import var_funcs as vf
Michael Walshb973f9b2018-09-19 16:00:06 -050013from robot.libraries.BuiltIn import BuiltIn
14import re
15
16
17def openbmctool_execute_command(command_string,
18 *args,
19 **kwargs):
20 r"""
21 Run the command string as an argument to the openbmctool.py program and
22 return the stdout and the return code.
23
24 This function provides several benefits versus calling shell_cmd directly:
25 - This function will obtain the global values for OPENBMC_HOST,
26 OPENBMC_USERNAME, etc.
27 - This function will compose the openbmctool.py command string which
28 includes the caller's command_string.
29 - The openbmctool.py produces additional text that clutters the output.
30 This function will remove such text. Example:
31 Attempting login...
32 <actual output>
33 User root has been logged out
34
35 NOTE: If you have pipe symbols in your command_string, they must be
36 surrounded by a single space on each side (see example below).
37
38 Example code:
39 ${rc} ${output}= Openbmctool Execute Command fru status | head -n 2
40
41 Example output:
42 #(CDT) 2018/09/19 15:16:58 - Issuing: set -o pipefail ; openbmctool.py -H hostname -U root -P ********
43 ... fru status | tail -n +1 | egrep -v 'Attempting login|User [^ ]+ hasbeen logged out' | head -n 2
44 Component | Is a FRU | Present | Functional | Has Logs
45 cpu0 | Yes | Yes | Yes | No
46
47 Description of arguments:
48 command_string The command string to be passed to the
49 openbmctool.py program.
Michael Walsh58b11ac2018-09-20 15:24:37 -050050 All remaining arguments are passed directly to shell_cmd. See the
51 shell_cmd prolog for details on allowable arguments. The caller may code
52 them directly as in this example:
53 openbmctool_execute_command("my command", quiet=1, max_attempts=2).
54 Python will do the work of putting these values into args/kwargs.
Michael Walshb973f9b2018-09-19 16:00:06 -050055 """
56
57 if not gv.valid_value(command_string):
58 return "", "", 1
59
60 # Get global BMC variable values.
61 openbmc_host = BuiltIn().get_variable_value("${OPENBMC_HOST}", default="")
62 openbmc_username = BuiltIn().get_variable_value("${OPENBMC_USERNAME}",
63 default="")
64 openbmc_password = BuiltIn().get_variable_value("${OPENBMC_PASSWORD}",
65 default="")
66 if not gv.valid_value(openbmc_host):
67 return "", "", 1
68 if not gv.valid_value(openbmc_username):
69 return "", "", 1
70 if not gv.valid_value(openbmc_password):
71 return "", "", 1
72
73 # Break the caller's command up into separate piped commands. For
74 # example, the user may have specified "fru status | head -n 2" which
75 # would be broken into 2 list elements.
76 pipeline = map(str.strip, re.split(r' \| ', str(command_string)))
77 # The "tail" command below prevents a "egrep: write error: Broken pipe"
78 # error if the user is piping the output to a sub-process.
79 # Use "egrep -v" to get rid of editorial output from openbmctool.py.
80 pipeline.insert(1, "tail -n +1 | egrep -v 'Attempting login|User [^ ]+ has"
81 " been logged out'")
82
Michael Walshd064ac92018-09-21 16:42:03 -050083 command_string = "set -o pipefail ; python3 openbmctool.py -H " + openbmc_host\
Michael Walshb973f9b2018-09-19 16:00:06 -050084 + " -U " + openbmc_username + " -P " + openbmc_password + " "\
85 + " | ".join(pipeline)
86
87 return gc.shell_cmd(command_string, *args, **kwargs)
Michael Walshd064ac92018-09-21 16:42:03 -050088
89
90def get_fru_status():
91 r"""
92 Get the fru status and return as a list of dictionaries.
93
94 Example robot code:
95
96 ${fru_status}= Get Fru Status
97 Rprint Vars 1 fru_status
98
99 Example result (excerpt):
100
101 fru_status:
102 fru_status[0]:
103 [component]: cpu0
104 [is_a]: Yes
105 [fru]: Yes
106 [present]: Yes
107 [functional]: No
108 fru_status[1]:
109 [component]: cpu0-core0
110 [is_a]: No
111 [fru]: Yes
112 [present]: Yes
113 [functional]: No
114 ...
115 """
116 rc, output = openbmctool_execute_command("fru status", print_output=False,
117 ignore_err=False)
118 # Example value for output (partial):
119 # Component | Is a FRU | Present | Functional | Has Logs
120 # cpu0 | Yes | Yes | Yes | No
121 # cpu0-core0 | No | Yes | Yes | No
122 # ...
123
124 # Replace spaces with underscores in field names (e.g. "Is a FRU" becomes
125 # "Is_a_FRU").
126 output = re.sub("([^ \\|])[ ]([^ ])", "\\1_\\2", output)
127 output = re.sub("([^ \\|])[ ]([^ ])", "\\1_\\2", output)
128
129 return vf.outbuf_to_report(output, field_delim="|")
130
131
132def get_fru_print(parse_json=True):
133 r"""
134 Get the output of the fru print command and return it either as raw JSON
135 data or as a list of dictionaries.
136
137 Example robot code:
138
139 ${fru_print}= Get Fru Print parse_json=${False}
140 Log to Console ${fru_print}
141
142 Example result (excerpt):
143
144 {
145 "data": {
146 "/xyz/openbmc_project/inventory/system": {
147 "AssetTag": "",
148 "BuildDate": "",
149 "Cached": false,
150 "FieldReplaceable": false,
151 "Manufacturer": "",
152 "Model": "xxxxxxxx",
153 "PartNumber": "",
154 "Present": true,
155 "PrettyName": "",
156 "SerialNumber": "13183FA"
157 },
158 "/xyz/openbmc_project/inventory/system/chassis": {
159 "AirCooled": true,
160 "WaterCooled": false
161 },
162 ...
163
164 Example robot code:
165
166 ${fru_print}= Get Fru Print
167 Rprint Vars 1 fru_print
168
169 Example result (excerpt):
170
171 fru_print:
172 fru_print[0]:
173 [data]:
174 [/xyz/openbmc_project/inventory/system]:
175 [AssetTag]: <blank>
176 [BuildDate]: <blank>
177 [Cached]: False
178 [FieldReplaceable]: False
179 [Manufacturer]: <blank>
180 [Model]: xxxxxxxx
181 [PartNumber]: <blank>
182 [Present]: True
183 [PrettyName]: <blank>
184 [SerialNumber]: 13183FA
185 [/xyz/openbmc_project/inventory/system/chassis]:
186 [AirCooled]: True
187 [WaterCooled]: False
188 ...
189
190 Description of argument(s):
191 parse_json Indicates that the raw JSON data should
192 parsed into a list of dictionaries.
193 """
194
195 rc, output = openbmctool_execute_command("fru print", print_output=False,
196 ignore_err=False)
197 if parse_json:
198 return gm.json_loads_multiple(output)
199 else:
200 return output
201
202
203def get_fru_list(parse_json=True):
204 r"""
205 Get the output of the fru list command and return it either as raw JSON
206 data or as a list of dictionaries.
207
208 Example robot code:
209
210 ${fru_list}= Get Fru List parse_json=${False}
211 Log to Console ${fru_list}
212
213 Example result (excerpt):
214
215 {
216 "data": {
217 "/xyz/openbmc_project/inventory/system": {
218 "AssetTag": "",
219 "BuildDate": "",
220 "Cached": false,
221 "FieldReplaceable": false,
222 "Manufacturer": "",
223 "Model": "xxxxxxxx",
224 "PartNumber": "",
225 "Present": true,
226 "PrettyName": "",
227 "SerialNumber": "13183FA"
228 },
229 "/xyz/openbmc_project/inventory/system/chassis": {
230 "AirCooled": true,
231 "WaterCooled": false
232 },
233 ...
234
235 Example robot code:
236
237 ${fru_list}= Get Fru List
238 Rprint Vars 1 fru_list
239
240 Example result (excerpt):
241
242 fru_list:
243 fru_list[0]:
244 [data]:
245 [/xyz/openbmc_project/inventory/system]:
246 [AssetTag]: <blank>
247 [BuildDate]: <blank>
248 [Cached]: False
249 [FieldReplaceable]: False
250 [Manufacturer]: <blank>
251 [Model]: xxxxxxxx
252 [PartNumber]: <blank>
253 [Present]: True
254 [PrettyName]: <blank>
255 [SerialNumber]: 13183FA
256 [/xyz/openbmc_project/inventory/system/chassis]:
257 [AirCooled]: True
258 [WaterCooled]: False
259 ...
260
261 Description of argument(s):
262 parse_json Indicates that the raw JSON data should
263 parsed into a list of dictionaries.
264 """
265
266 rc, output = openbmctool_execute_command("fru list", print_output=False,
267 ignore_err=False)
268 if parse_json:
269 return gm.json_loads_multiple(output)
270 else:
271 return output
272
273
274def get_sensors_print():
275
276 r"""
277 Get the output of the sensors print command and return as a list of
278 dictionaries.
279
280 Example robot code:
281
282 ${sensors_print}= Get Sensors Print
283 Rprint Vars 1 sensors_print
284
285 Example result (excerpt):
286
287 sensors_print:
288 sensors_print[0]:
289 [sensor]: OCC0
290 [type]: Discrete
291 [units]: N/A
292 [value]: Active
293 [target]: Active
294 sensors_print[1]:
295 [sensor]: OCC1
296 [type]: Discrete
297 [units]: N/A
298 [value]: Active
299 [target]: Active
300 ...
301 """
302 rc, output = openbmctool_execute_command("sensors print",
303 print_output=False,
304 ignore_err=False)
305 # Example value for output (partial):
306 # sensor | type | units | value | target
307 # OCC0 | Discrete | N/A | Active | Active
308 # OCC1 | Discrete | N/A | Active | Active
309
310 return vf.outbuf_to_report(output, field_delim="|")
311
312
313def get_sensors_list():
314
315 r"""
316 Get the output of the sensors list command and return as a list of
317 dictionaries.
318
319 Example robot code:
320
321 ${sensors_list}= Get Sensors List
322 Rprint Vars 1 sensors_list
323
324 Example result (excerpt):
325
326 sensors_list:
327 sensors_list[0]:
328 [sensor]: OCC0
329 [type]: Discrete
330 [units]: N/A
331 [value]: Active
332 [target]: Active
333 sensors_list[1]:
334 [sensor]: OCC1
335 [type]: Discrete
336 [units]: N/A
337 [value]: Active
338 [target]: Active
339 ...
340 """
341 rc, output = openbmctool_execute_command("sensors list",
342 print_output=False,
343 ignore_err=False)
344 # Example value for output (partial):
345 # sensor | type | units | value | target
346 # OCC0 | Discrete | N/A | Active | Active
347 # OCC1 | Discrete | N/A | Active | Active
348
349 return vf.outbuf_to_report(output, field_delim="|")
350
351
352def get_openbmctool_version():
353 r"""
354 Get the openbmctool.py version and return it.
355
356 Example robot code:
357 ${openbmctool_version}= Get Openbmctool Version
358 Rprint Vars openbmctool_version
359
360 Example result (excerpt):
361 openbmctool_version: 1.06
362 """
363 rc, output = openbmctool_execute_command("-V | cut -f 2 -d ' '",
364 print_output=False,
365 ignore_err=False)
366 return output