blob: 5b7c2968c80046b5766b5150b3a0e4d75df4a734 [file] [log] [blame]
Michael Walshf4c62a22017-11-13 15:40:57 -06001#!/usr/bin/env python
2
3r"""
4This module provides functions which are useful to plug-in call point programs.
5"""
6
7import sys
8import os
9import re
10import collections
11
12import gen_print as gp
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050013import gen_misc as gm
Michael Walsha6b46ed2018-06-01 14:31:23 -050014import gen_cmd as gc
15
16PLUG_VAR_PREFIX = os.environ.get("PLUG_VAR_PREFIX", "AUTOBOOT")
Michael Walshf4c62a22017-11-13 15:40:57 -060017
18
19def get_plug_in_package_name(case=None):
Michael Walshf4c62a22017-11-13 15:40:57 -060020 r"""
21 Return the plug-in package name (e.g. "OS_Console", "DB_Logging").
22
23 Description of argument(s):
Michael Walsh0cb727d2019-10-16 17:16:45 -050024 case Indicates whether the value returned should be converted to upper or
25 lower case. Valid values are "upper", "lower" or None.
Michael Walshf4c62a22017-11-13 15:40:57 -060026 """
27
28 plug_in_package_name = os.path.basename(gp.pgm_dir_path[:-1])
29 if case == "upper":
30 return plug_in_package_name.upper()
31 elif case == "lower":
32 return plug_in_package_name.lower()
33 else:
34 return plug_in_package_name
35
36
Michael Walshfd7443d2018-10-30 13:12:18 -050037def return_plug_vars(general=True,
Michael Walshaeeb5272019-11-20 13:58:47 -060038 custom=True,
39 plug_in_package_name=None):
Michael Walshf4c62a22017-11-13 15:40:57 -060040 r"""
Michael Walsh0cb727d2019-10-16 17:16:45 -050041 Return an OrderedDict which is sorted by key and which contains all of the plug-in environment variables.
Michael Walshf4c62a22017-11-13 15:40:57 -060042
43 Example excerpt of resulting dictionary:
44
45 plug_var_dict:
Michael Walsh2ce1dba2019-02-05 19:29:28 +000046 [AUTOBOOT_BASE_TOOL_DIR_PATH]: /tmp/
Michael Walshf4c62a22017-11-13 15:40:57 -060047 [AUTOBOOT_BB_LEVEL]: <blank>
48 [AUTOBOOT_BOOT_FAIL]: 0
49 ...
50
51 This function also does the following:
Michael Walsh0cb727d2019-10-16 17:16:45 -050052 - Set a default value for environment variable AUTOBOOT_OPENBMC_NICKNAME/AUTOIPL_FSP1_NICKNAME if it is
53 not already set.
Michael Walshf4c62a22017-11-13 15:40:57 -060054 - Register PASSWORD variables to prevent their values from being printed.
Michael Walsha6b46ed2018-06-01 14:31:23 -050055
Michael Walsh0cb727d2019-10-16 17:16:45 -050056 Note: The programmer may set a default for any given environment variable by declaring a global variable
57 of the same name and setting its value. For example, let's say the calling program has this global
58 declaration:
Michael Walsha6b46ed2018-06-01 14:31:23 -050059
60 PERF_EXERCISERS_TOTAL_TIMEOUT = '180'
61
Michael Walsh0cb727d2019-10-16 17:16:45 -050062 If environment variable PERF_EXERCISERS_TOTAL_TIMEOUT is blank or not set, this function will set it to
63 '180'.
64
65 Furthermore, if such a default variable declaration is not a string, this function will preserve that
66 non-string type in setting global variables (with the exception of os.environ values which must be
67 string). Example:
68
69 NVDIMM_ENCRYPT = 0
Michael Walshfd7443d2018-10-30 13:12:18 -050070
71 Description of argument(s):
Michael Walsh0cb727d2019-10-16 17:16:45 -050072 general Return general plug-in parms (e.g. those beginning with "AUTOBOOT" or
73 "AUTOGUI").
74 custom Return custom plug-in parms (i.e. those beginning with the upper case
75 name of the plug-in package, for example "OBMC_SAMPLE_PARM1").
Michael Walshaeeb5272019-11-20 13:58:47 -060076 plug_in_package_name The name of the plug-in package for which custom parms are to be
77 returned. The default is the current plug in package name.
Michael Walshf4c62a22017-11-13 15:40:57 -060078 """
79
Michael Walshfd7443d2018-10-30 13:12:18 -050080 regex_list = []
81 if not (general or custom):
82 return collections.OrderedDict()
Michael Walshaeeb5272019-11-20 13:58:47 -060083 plug_in_package_name = gm.dft(plug_in_package_name, get_plug_in_package_name())
Michael Walshfd7443d2018-10-30 13:12:18 -050084 if general:
85 regex_list = [PLUG_VAR_PREFIX, "AUTOGUI"]
86 if custom:
Michael Walshaeeb5272019-11-20 13:58:47 -060087 regex_list.append(plug_in_package_name.upper())
Michael Walshfd7443d2018-10-30 13:12:18 -050088
89 regex = "^(" + "|".join(regex_list) + ")_"
Michael Walshf4c62a22017-11-13 15:40:57 -060090
91 # Set a default for nickname.
92 if os.environ.get("AUTOBOOT_OPENBMC_NICKNAME", "") == "":
93 os.environ['AUTOBOOT_OPENBMC_NICKNAME'] = \
94 os.environ.get("AUTOBOOT_OPENBMC_HOST", "")
95
Michael Walsha6b46ed2018-06-01 14:31:23 -050096 if os.environ.get("AUTOIPL_FSP1_NICKNAME", "") == "":
97 os.environ['AUTOIPL_FSP1_NICKNAME'] = \
98 os.environ.get("AUTOIPL_FSP1_NAME", "").split(".")[0]
99
Michael Walsh0cb727d2019-10-16 17:16:45 -0500100 # For all variables specified in the parm_def file, we want them to default to "" rather than being unset.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500101 # Process the parm_def file if it exists.
Michael Walshaeeb5272019-11-20 13:58:47 -0600102 parm_def_file_path = os.path.dirname(gp.pgm_dir_path.rstrip("/")) + "/" + plug_in_package_name \
103 + "/parm_def"
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500104 if os.path.exists(parm_def_file_path):
105 parm_defs = gm.my_parm_file(parm_def_file_path)
106 else:
107 parm_defs = collections.OrderedDict()
108 # Example parm_defs:
109 # parm_defs:
110 # parm_defs[rest_fail]: boolean
111 # parm_defs[command]: string
112 # parm_defs[esel_stop_file_path]: string
113
Michael Walsh0cb727d2019-10-16 17:16:45 -0500114 # Create a list of plug-in environment variables by pre-pending <all caps plug-in package name>_<all
115 # caps var name>
Michael Walshaeeb5272019-11-20 13:58:47 -0600116 plug_in_parm_names = [plug_in_package_name.upper() + "_" + x for x in
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500117 map(str.upper, parm_defs.keys())]
118 # Example plug_in_parm_names:
119 # plug_in_parm_names:
120 # plug_in_parm_names[0]: STOP_REST_FAIL
121 # plug_in_parm_names[1]: STOP_COMMAND
122 # plug_in_parm_names[2]: STOP_ESEL_STOP_FILE_PATH
123
Michael Walsh0cb727d2019-10-16 17:16:45 -0500124 # os.environ only accepts string values. However, if the user defines default values of other types
125 # (e.g. int), we wish to preserve the type.
126 non_string_defaults = {}
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500127 # Initialize unset plug-in vars.
128 for var_name in plug_in_parm_names:
Michael Walsh0cb727d2019-10-16 17:16:45 -0500129 # If there is a global variable with the same name as the environment variable, use its value as a
130 # default.
Michael Walsha6b46ed2018-06-01 14:31:23 -0500131 default_value = gm.get_mod_global(var_name, "")
Michael Walsh0cb727d2019-10-16 17:16:45 -0500132 if type(default_value) is not str:
133 non_string_defaults[var_name] = type(default_value)
134 os.environ[var_name] = os.environ.get(var_name, str(default_value))
Michael Walsha6b46ed2018-06-01 14:31:23 -0500135 if os.environ[var_name] == "":
Michael Walshc1df1502019-11-04 14:38:13 -0600136 os.environ[var_name] = str(default_value)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500137
Michael Walshf4c62a22017-11-13 15:40:57 -0600138 plug_var_dict = \
139 collections.OrderedDict(sorted({k: v for (k, v) in
Gunnar Mills096cd562018-03-26 10:19:12 -0500140 os.environ.items()
141 if re.match(regex, k)}.items()))
Michael Walsh0cb727d2019-10-16 17:16:45 -0500142 # Restore the types of any variables where the caller had defined default values.
143 for key, value in non_string_defaults.items():
144 cmd_buf = "plug_var_dict[key] = " + str(value).split("'")[1] + "(plug_var_dict[key]"
145 if value is int:
146 # Use int base argument of 0 to allow it to interpret hex strings.
147 cmd_buf += ", 0)"
148 else:
149 cmd_buf += ")"
Michael Walshc09b7cb2019-10-22 10:39:17 -0500150 exec(cmd_buf) in globals(), locals()
Michael Walsh0cb727d2019-10-16 17:16:45 -0500151 # Register password values to prevent printing them out. Any plug var whose name ends in PASSWORD will
152 # be registered.
Michael Walshf4c62a22017-11-13 15:40:57 -0600153 password_vals = {k: v for (k, v) in plug_var_dict.items()
154 if re.match(r".*_PASSWORD$", k)}.values()
155 map(gp.register_passwords, password_vals)
156
157 return plug_var_dict
158
159
Michael Walshfd7443d2018-10-30 13:12:18 -0500160def sprint_plug_vars(headers=1, **kwargs):
Michael Walshf4c62a22017-11-13 15:40:57 -0600161 r"""
Michael Walsh0cb727d2019-10-16 17:16:45 -0500162 Sprint the plug-in environment variables (i.e. those that begin with the global PLUG_VAR_PREFIX value or
163 those that begin with <plug-in package_name>_ in upper case letters.).
Michael Walshf4c62a22017-11-13 15:40:57 -0600164
165 Example excerpt of output:
Michael Walsh2ce1dba2019-02-05 19:29:28 +0000166 AUTOBOOT_BASE_TOOL_DIR_PATH=/tmp/
Michael Walshf4c62a22017-11-13 15:40:57 -0600167 AUTOBOOT_BB_LEVEL=
168 AUTOBOOT_BOOT_FAIL=0
169 AUTOBOOT_BOOT_FAIL_THRESHOLD=1000000
170
171 Description of argument(s):
172 headers Print a header and a footer.
Michael Walsh0cb727d2019-10-16 17:16:45 -0500173 kwargs These are passed directly to return_plug_vars. See return_plug_vars doc
174 string for details.
Michael Walshf4c62a22017-11-13 15:40:57 -0600175 """
Michael Walshfd7443d2018-10-30 13:12:18 -0500176 plug_var_dict = return_plug_vars(**kwargs)
Michael Walshf4c62a22017-11-13 15:40:57 -0600177 buffer = ""
178 if headers:
179 buffer += "\n" + gp.sprint_dashes()
180 for key, value in plug_var_dict.items():
Michael Walshfd7443d2018-10-30 13:12:18 -0500181 buffer += gp.sprint_varx(key, value)
Michael Walshf4c62a22017-11-13 15:40:57 -0600182 if headers:
183 buffer += gp.sprint_dashes() + "\n"
184
185 return buffer
186
187
Michael Walshfd7443d2018-10-30 13:12:18 -0500188def print_plug_in_header():
189 r"""
190 Print plug-in header.
191
Michael Walsh0cb727d2019-10-16 17:16:45 -0500192 When debug is set, print all plug_prefix variables (e.g. AUTOBOOT_OPENBMC_HOST, etc.) and all plug-in
193 environment variables (e.g. OBMC_SAMPLE_PARM1) with surrounding dashed lines. When debug is not set,
194 print only the plug-in environment variables (e.g. OBMC_SAMPLE_PARM1) with no surrounding dashed lines.
Michael Walshfd7443d2018-10-30 13:12:18 -0500195
Michael Walsh0cb727d2019-10-16 17:16:45 -0500196 NOTE: plug-in environment variables means any variable defined in the <plug-in dir>/parm_def file plus
197 any environment variables whose names begin with the upper-case plug-in package name.
Michael Walshfd7443d2018-10-30 13:12:18 -0500198 """
199
200 dprint_plug_vars()
201 if not debug:
202 qprint_plug_vars(headers=0, general=False, custom=True)
203
204
Michael Walsh47f8a602019-11-20 14:02:11 -0600205def get_plug_vars(mod_name="__main__", **kwargs):
Michael Walshf4c62a22017-11-13 15:40:57 -0600206 r"""
207 Get all plug-in variables and put them in corresponding global variables.
208
Michael Walsh0cb727d2019-10-16 17:16:45 -0500209 This would include all environment variables beginning with either the global PLUG_VAR_PREFIX value or
210 with the upper case version of the plug-in package name + underscore (e.g. OP_SAMPLE_VAR1 for plug-in
211 OP_Sample).
Michael Walshf4c62a22017-11-13 15:40:57 -0600212
Michael Walsh0cb727d2019-10-16 17:16:45 -0500213 The global variables to be set will be both with and without the global PLUG_VAR_PREFIX value prefix.
214 For example, if the environment variable in question is AUTOBOOT_OPENBMC_HOST, this function will set
215 global variable AUTOBOOT_OPENBMC_HOST and global variable OPENBMC_HOST.
Michael Walsh8b79b052019-05-02 17:07:08 -0500216
217 Description of argument(s):
Michael Walsh0cb727d2019-10-16 17:16:45 -0500218 mod_name The name of the module whose global plug-in variables should be retrieved.
Michael Walsh47f8a602019-11-20 14:02:11 -0600219 kwargs These are passed directly to return_plug_vars. See return_plug_vars's
220 prolog for details.
Michael Walshf4c62a22017-11-13 15:40:57 -0600221 """
222
Michael Walsh8b79b052019-05-02 17:07:08 -0500223 module = sys.modules[mod_name]
Michael Walsh47f8a602019-11-20 14:02:11 -0600224 plug_var_dict = return_plug_vars(**kwargs)
Michael Walshf4c62a22017-11-13 15:40:57 -0600225
Michael Walsha6b46ed2018-06-01 14:31:23 -0500226 # Get all PLUG_VAR_PREFIX environment variables and put them into globals.
Michael Walshf4c62a22017-11-13 15:40:57 -0600227 for key, value in plug_var_dict.items():
228 setattr(module, key, value)
Michael Walsha6b46ed2018-06-01 14:31:23 -0500229 setattr(module, re.sub("^" + PLUG_VAR_PREFIX + "_", "", key), value)
Michael Walshf4c62a22017-11-13 15:40:57 -0600230
231
232def get_plug_default(var_name,
233 default=None):
Michael Walshf4c62a22017-11-13 15:40:57 -0600234 r"""
235 Derive and return a default value for the given parm variable.
236
Michael Walsha6b46ed2018-06-01 14:31:23 -0500237 Dependencies:
238 Global variable PLUG_VAR_PREFIX must be set.
239
Michael Walsh0cb727d2019-10-16 17:16:45 -0500240 This function will assign a default by checking the following environment variables in the order shown.
241 The first one that has a value will be used.
Michael Walshf4c62a22017-11-13 15:40:57 -0600242 - <upper case package_name>_<var_name>
Michael Walsha6b46ed2018-06-01 14:31:23 -0500243 - <PLUG_VAR_PREFIX>_OVERRIDE_<var_name>
244 - <PLUG_VAR_PREFIX>_<var_name>
Michael Walshf4c62a22017-11-13 15:40:57 -0600245
Michael Walsh0cb727d2019-10-16 17:16:45 -0500246 If none of these are found, this function will return the value passed by the caller in the "default"
247 parm.
Michael Walshf4c62a22017-11-13 15:40:57 -0600248
249 Example:
250
Michael Walsh0cb727d2019-10-16 17:16:45 -0500251 Let's say your plug-in is named "OS_Console" and you call this function as follows:
Michael Walshf4c62a22017-11-13 15:40:57 -0600252
253 get_plug_default("quiet", 0)
254
Michael Walsh0cb727d2019-10-16 17:16:45 -0500255 The first of these environment variables that is found to be set will be used to provide the default
256 value.
Michael Walshf4c62a22017-11-13 15:40:57 -0600257 - OS_CONSOLE_QUIET
258 - AUTOBOOT_OVERRIDE_QUIET
259 - AUTOBOOT_QUIET
260
Michael Walsh0cb727d2019-10-16 17:16:45 -0500261 If none of those has a value, 0 (as specified by the caller in this example) is returned.
Michael Walshf4c62a22017-11-13 15:40:57 -0600262
Michael Walsh0cb727d2019-10-16 17:16:45 -0500263 Let's say the master driver program is named obmc_boot. obmc_boot program is responsible for calling
264 plug-ins. Let's further suppose that the user wishes to run the master program with --debug=0 but wishes
265 to have all plug-ins run with --debug=1. This could be accomplished with the following call:
266 export AUTOBOOT_OVERRIDE_DEBUG=1 ; obmc_boot --debug=0 --plug_in_dir_paths=<list of plug ins>
267
268 As another example, let's suppose that the user wishes to have just the OS_Console plug-in run with debug
269 and everything else to default to debug=0. This could be accomplished as follows:
270 export OS_CONSOLE_DEBUG=1 ; obmc_boot --debug=0 --plug_in_dir_paths=<list of plug ins>
271
272 And as one more example, let's say the user wishes to have obmc_boot and OS_Console run without debug but
273 have all other plug-ins run with debug:
274 export AUTOBOOT_OVERRIDE_DEBUG=1 ; export OS_CONSOLE_DEBUG=0 ; obmc_boot --debug=0
Michael Walshf4c62a22017-11-13 15:40:57 -0600275 --plug_in_dir_paths=<list of plug ins>
276
Michael Walshf4c62a22017-11-13 15:40:57 -0600277 Description of argument(s):
Michael Walsh0cb727d2019-10-16 17:16:45 -0500278 var_name The name of the variable for which a default value is to be calculated.
279 default The default value if one cannot be determined.
Michael Walshf4c62a22017-11-13 15:40:57 -0600280 """
281
282 var_name = var_name.upper()
283 plug_in_package_name = get_plug_in_package_name(case="upper")
284
285 package_var_name = plug_in_package_name + "_" + var_name
286 default_value = os.environ.get(package_var_name, None)
287 if default_value is not None:
288 # A package-name version of the variable was found so return its value.
289 return(default_value)
290
Michael Walsha6b46ed2018-06-01 14:31:23 -0500291 plug_var_name = PLUG_VAR_PREFIX + "_OVERRIDE_" + var_name
292 default_value = os.environ.get(plug_var_name, None)
Michael Walshf4c62a22017-11-13 15:40:57 -0600293 if default_value is not None:
Michael Walsh0cb727d2019-10-16 17:16:45 -0500294 # A PLUG_VAR_PREFIX version of the variable was found so return its value.
Michael Walshf4c62a22017-11-13 15:40:57 -0600295 return default_value
296
Michael Walsha6b46ed2018-06-01 14:31:23 -0500297 plug_var_name = PLUG_VAR_PREFIX + "_" + var_name
298 default_value = os.environ.get(plug_var_name, None)
Michael Walshf4c62a22017-11-13 15:40:57 -0600299 if default_value is not None:
Michael Walsh0cb727d2019-10-16 17:16:45 -0500300 # A PLUG_VAR_PREFIX version of the variable was found so return its value.
Michael Walshf4c62a22017-11-13 15:40:57 -0600301 return default_value
302
303 return default
304
305
306def srequired_plug_in(req_plug_in_names,
307 plug_in_dir_paths=None):
Michael Walshf4c62a22017-11-13 15:40:57 -0600308 r"""
Michael Walsh0cb727d2019-10-16 17:16:45 -0500309 Return an empty string if the required plug-ins are found in plug_in_dir_paths. Otherwise, return an
310 error string.
Michael Walshf4c62a22017-11-13 15:40:57 -0600311
312 Example call:
313 error_message = srequired_plug_in(req_plug_in_names, plug_in_dir_paths)
314
315 Description of argument(s):
Michael Walsh0cb727d2019-10-16 17:16:45 -0500316 req_plug_in_names A list of plug_in names that the caller requires (e.g. ['OS_Console']).
317 plug_in_dir_paths A string which is a colon-delimited list of plug-ins specified by the
318 user (e.g. DB_Logging:FFDC:OS_Console:Perf). Path values (e.g.
319 "/home/robot/dir1") will be stripped from this list to do the analysis.
320 Default value is the <PLUG_VAR_PREFIX>_PLUG_IN_DIR_PATHS environment
321 variable.
Michael Walshf4c62a22017-11-13 15:40:57 -0600322 """
323
324 # Calculate default value for plug_in_dir_paths.
325 if plug_in_dir_paths is None:
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500326 plug_in_dir_paths = os.environ.get(PLUG_VAR_PREFIX
327 + "_PLUG_IN_DIR_PATHS", "")
Michael Walshf4c62a22017-11-13 15:40:57 -0600328
329 error_message = ""
330
331 # Convert plug_in_dir_paths to a list of base names.
332 plug_in_dir_paths = \
Michael Walsh6aa5a9e2018-08-07 15:04:56 -0500333 list(filter(None, map(os.path.basename, plug_in_dir_paths.split(":"))))
Michael Walshf4c62a22017-11-13 15:40:57 -0600334
335 # Check for each of the user's required plug-ins.
336 for plug_in_name in req_plug_in_names:
337 if plug_in_name not in plug_in_dir_paths:
338 error_message = "The \"" + get_plug_in_package_name() +\
339 "\" plug-in cannot run unless the user also selects the \"" +\
340 plug_in_name + "\" plug in:\n" +\
341 gp.sprint_var(plug_in_dir_paths)
342
343 return error_message
344
345
346def required_plug_in(req_plug_in_names,
347 plug_in_dir_paths=None):
Michael Walshf4c62a22017-11-13 15:40:57 -0600348 r"""
Michael Walsh0cb727d2019-10-16 17:16:45 -0500349 Return True if each of the plug-ins in req_plug_in_names can be found in plug_in_dir_paths Otherwise,
350 return False and print an error message to stderr.
Michael Walshf4c62a22017-11-13 15:40:57 -0600351
352 Example call:
353 if not required_plug_in(['OS_Console'], AUTOBOOT_PLUG_IN_DIR_PATHS):
354 return False
355
356 Description of argument(s):
357 (See Description of arguments for srequired_plug_in (above)).
358 """
359
360 error_message = srequired_plug_in(req_plug_in_names, plug_in_dir_paths)
361 if not error_message == "":
362 gp.print_error_report(error_message)
363 return False
364
365 return True
366
367
Michael Walsh96ffeb72018-08-23 11:37:22 -0500368def compose_plug_in_save_dir_path(plug_in_package_name=None):
Michael Walsha6b46ed2018-06-01 14:31:23 -0500369 r"""
Michael Walsh0cb727d2019-10-16 17:16:45 -0500370 Create and return a directory path name that is suitable for saving plug-in data.
Michael Walsha6b46ed2018-06-01 14:31:23 -0500371
Michael Walsh0cb727d2019-10-16 17:16:45 -0500372 The name will be comprised of things such as plug_in package name, pid, etc. in order to guarantee that
373 it is unique for a given test run.
Michael Walsh96ffeb72018-08-23 11:37:22 -0500374
375 Description of argument(s):
Michael Walsh0cb727d2019-10-16 17:16:45 -0500376 plug_in_package_name The plug-in package name. This defaults to the name of the caller's
377 plug-in package. However, the caller can specify another value in order
378 to retrieve data saved by another plug-in package.
Michael Walsha6b46ed2018-06-01 14:31:23 -0500379 """
380
Michael Walsh96ffeb72018-08-23 11:37:22 -0500381 plug_in_package_name = gm.dft(plug_in_package_name,
382 get_plug_in_package_name())
383
Michael Walsha6b46ed2018-06-01 14:31:23 -0500384 BASE_TOOL_DIR_PATH = \
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500385 gm.add_trailing_slash(os.environ.get(PLUG_VAR_PREFIX
Michael Walsh2ce1dba2019-02-05 19:29:28 +0000386 + "_BASE_TOOL_DIR_PATH",
387 "/tmp/"))
Michael Walsha6b46ed2018-06-01 14:31:23 -0500388 NICKNAME = os.environ.get("AUTOBOOT_OPENBMC_NICKNAME", "")
389 if NICKNAME == "":
390 NICKNAME = os.environ["AUTOIPL_FSP1_NICKNAME"]
391 MASTER_PID = os.environ[PLUG_VAR_PREFIX + "_MASTER_PID"]
Michael Walsh053d0182019-09-06 16:27:33 -0500392 gp.qprint_vars(BASE_TOOL_DIR_PATH, NICKNAME, plug_in_package_name,
393 MASTER_PID)
Michael Walsh2ce1dba2019-02-05 19:29:28 +0000394 return BASE_TOOL_DIR_PATH + gm.username() + "/" + NICKNAME + "/" +\
395 plug_in_package_name + "/" + str(MASTER_PID) + "/"
Michael Walsha6b46ed2018-06-01 14:31:23 -0500396
397
Michael Walsh96ffeb72018-08-23 11:37:22 -0500398def create_plug_in_save_dir(plug_in_package_name=None):
Michael Walsha6b46ed2018-06-01 14:31:23 -0500399 r"""
Michael Walsh0cb727d2019-10-16 17:16:45 -0500400 Create a directory suitable for saving plug-in processing data and return its path name.
Michael Walsh024a2f32019-04-18 10:55:34 -0500401
402 See compose_plug_in_save_dir_path for details.
Michael Walsh96ffeb72018-08-23 11:37:22 -0500403
404 Description of argument(s):
Michael Walsh0cb727d2019-10-16 17:16:45 -0500405 plug_in_package_name See compose_plug_in_save_dir_path for details.
Michael Walsha6b46ed2018-06-01 14:31:23 -0500406 """
407
Michael Walsh96ffeb72018-08-23 11:37:22 -0500408 plug_in_save_dir_path = compose_plug_in_save_dir_path(plug_in_package_name)
Michael Walsha6b46ed2018-06-01 14:31:23 -0500409 if os.path.isdir(plug_in_save_dir_path):
410 return plug_in_save_dir_path
411 gc.shell_cmd("mkdir -p " + plug_in_save_dir_path)
412 return plug_in_save_dir_path
413
414
Michael Walsh96ffeb72018-08-23 11:37:22 -0500415def delete_plug_in_save_dir(plug_in_package_name=None):
Michael Walsha6b46ed2018-06-01 14:31:23 -0500416 r"""
Michael Walsh0cb727d2019-10-16 17:16:45 -0500417 Delete the plug_in save directory. See compose_plug_in_save_dir_path for details.
Michael Walsh96ffeb72018-08-23 11:37:22 -0500418
419 Description of argument(s):
Michael Walsh0cb727d2019-10-16 17:16:45 -0500420 plug_in_package_name See compose_plug_in_save_dir_path for details.
Michael Walsha6b46ed2018-06-01 14:31:23 -0500421 """
422
Michael Walsh96ffeb72018-08-23 11:37:22 -0500423 gc.shell_cmd("rm -rf "
424 + compose_plug_in_save_dir_path(plug_in_package_name))
Michael Walsha6b46ed2018-06-01 14:31:23 -0500425
426
Michael Walsh96ffeb72018-08-23 11:37:22 -0500427def save_plug_in_value(value, plug_in_package_name=None):
Michael Walsha6b46ed2018-06-01 14:31:23 -0500428 r"""
Michael Walsh0cb727d2019-10-16 17:16:45 -0500429 Save a value in a plug-in save file. The value may be retrieved later via a call to the
430 restore_plug_in_value function.
Michael Walsha6b46ed2018-06-01 14:31:23 -0500431
Michael Walsh0cb727d2019-10-16 17:16:45 -0500432 This function will figure out the variable name of the value passed and use that name in creating the
433 plug-in save file.
Michael Walsha6b46ed2018-06-01 14:31:23 -0500434
435 Example call:
436
437 my_var1 = 5
438 save_plug_in_value(my_var1)
439
Michael Walsh0cb727d2019-10-16 17:16:45 -0500440 In this example, the value "5" would be saved to the "my_var1" file in the plug-in save directory.
Michael Walsha6b46ed2018-06-01 14:31:23 -0500441
442 Description of argument(s):
443 value The value to be saved.
Michael Walsh0cb727d2019-10-16 17:16:45 -0500444 plug_in_package_name See compose_plug_in_save_dir_path for details.
Michael Walsha6b46ed2018-06-01 14:31:23 -0500445 """
446
447 # Get the name of the variable used as argument one to this function.
448 var_name = gp.get_arg_name(0, 1, stack_frame_ix=2)
Michael Walsh96ffeb72018-08-23 11:37:22 -0500449 plug_in_save_dir_path = create_plug_in_save_dir(plug_in_package_name)
Michael Walsha6b46ed2018-06-01 14:31:23 -0500450 save_file_path = plug_in_save_dir_path + var_name
451 gp.qprint_timen("Saving \"" + var_name + "\" value.")
452 gc.shell_cmd("echo '" + str(value) + "' > " + save_file_path)
453
454
Michael Walsh96ffeb72018-08-23 11:37:22 -0500455def restore_plug_in_value(default="", plug_in_package_name=None):
Michael Walsha6b46ed2018-06-01 14:31:23 -0500456 r"""
457 Return a value from a plug-in save file.
458
Michael Walsh0cb727d2019-10-16 17:16:45 -0500459 The name of the value to be restored will be determined by this function based on the lvalue being
460 assigned. Consider the following example:
Michael Walsha6b46ed2018-06-01 14:31:23 -0500461
462 my_var1 = restore_plug_in_value(2)
463
Michael Walsh0cb727d2019-10-16 17:16:45 -0500464 In this example, this function would look for the "my_var1" file in the plug-in save directory, read its
465 value and return it. If no such file exists, the default value of 2 would be returned.
Michael Walsha6b46ed2018-06-01 14:31:23 -0500466
467 Description of argument(s):
Michael Walsh0cb727d2019-10-16 17:16:45 -0500468 default The default value to be returned if there is no plug-in save file for the
469 value in question.
470 plug_in_package_name See compose_plug_in_save_dir_path for details.
Michael Walsha6b46ed2018-06-01 14:31:23 -0500471 """
472
473 # Get the lvalue from the caller's invocation of this function.
474 lvalue = gp.get_arg_name(0, -1, stack_frame_ix=2)
Michael Walsh96ffeb72018-08-23 11:37:22 -0500475 plug_in_save_dir_path = create_plug_in_save_dir(plug_in_package_name)
Michael Walsha6b46ed2018-06-01 14:31:23 -0500476 save_file_path = plug_in_save_dir_path + lvalue
477 if os.path.isfile(save_file_path):
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500478 gp.qprint_timen("Restoring " + lvalue + " value from "
479 + save_file_path + ".")
Michael Walsh25f0f162018-09-10 13:57:11 -0500480 value = gm.file_to_list(save_file_path, newlines=0, comments=0,
481 trim=1)[0]
482 if type(default) is bool:
483 # Convert from string to bool.
484 value = (value == 'True')
485 if type(default) is int:
486 # Convert from string to int.
487 value = int(value)
488 gp.qprint_varx(lvalue, value)
489 return value
Michael Walsha6b46ed2018-06-01 14:31:23 -0500490 else:
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500491 gp.qprint_timen("Save file " + save_file_path
492 + " does not exist so returning default value.")
Michael Walsh25f0f162018-09-10 13:57:11 -0500493 gp.qprint_var(default)
Michael Walsha6b46ed2018-06-01 14:31:23 -0500494 return default
495
496
Michael Walsh99beb652019-02-25 10:45:23 -0600497def exit_not_master():
498 r"""
Michael Walsh0cb727d2019-10-16 17:16:45 -0500499 Exit the program with return code zero if this program was NOT called by the master program.
Michael Walsh99beb652019-02-25 10:45:23 -0600500
501 There are cases where plug-ins are called by a multi-layered stack:
502
503 master_wrapper
504 obmc_boot_test.py
505 Example_plug_in/cp_setup
506
Michael Walsh0cb727d2019-10-16 17:16:45 -0500507 In a scenario like this, Example_plug_in/cp_setup may be called once directly by master_wrapper (the
508 master) and and then called again directly by obmc_boot_test.py (the child). Some plug-in programs may
509 wish to avoid doing any processing on the second such call. This function will achieve that purpose.
Michael Walsh99beb652019-02-25 10:45:23 -0600510
511 This function will print a standard message to stdout prior to exiting.
512 """
513
514 AUTOBOOT_MASTER_PID = gm.get_mod_global("AUTOBOOT_MASTER_PID")
515 AUTOBOOT_PROGRAM_PID = gm.get_mod_global("AUTOBOOT_PROGRAM_PID")
516
517 if AUTOBOOT_MASTER_PID != AUTOBOOT_PROGRAM_PID:
518 message = get_plug_in_package_name() + "/" + gp.pgm_name + " is not" \
519 + " being called by the master program in the stack so no action" \
520 + " will be taken."
521 gp.qprint_timen(message)
522 gp.qprint_vars(AUTOBOOT_MASTER_PID, AUTOBOOT_PROGRAM_PID)
523 exit(0)
524
525
Michael Walsh0cb727d2019-10-16 17:16:45 -0500526def stop_test_rc():
527 r"""
528 Return the constant stop test return code value.
529
530 When a plug-in call point program returns this value, it indicates that master program should stop
531 running.
532 """
533
534 return 0x00000002
535
536
Michael Walshf4c62a22017-11-13 15:40:57 -0600537# Create print wrapper functions for all sprint functions defined above.
Michael Walsh0cb727d2019-10-16 17:16:45 -0500538# func_names contains a list of all print functions which should be created from their sprint counterparts.
Michael Walshf4c62a22017-11-13 15:40:57 -0600539func_names = ['print_plug_vars']
540
Michael Walsh0cb727d2019-10-16 17:16:45 -0500541# stderr_func_names is a list of functions whose output should go to stderr rather than stdout.
Michael Walshf4c62a22017-11-13 15:40:57 -0600542stderr_func_names = []
543
544replace_dict = dict(gp.replace_dict)
Michael Walsh81c02342018-01-05 15:43:28 -0600545replace_dict['mod_qualifier'] = 'gp.'
Michael Walshf4c62a22017-11-13 15:40:57 -0600546func_defs = gp.create_print_wrapper_funcs(func_names, stderr_func_names,
547 replace_dict)
548gp.gp_debug_print(func_defs)
549exec(func_defs)