blob: f1d647fee880e724fb3616de2ed91dc8e5912f3e [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 Walshf4c62a22017-11-13 15:40:57 -060014
15
16def get_plug_in_package_name(case=None):
Michael Walshf4c62a22017-11-13 15:40:57 -060017 r"""
18 Return the plug-in package name (e.g. "OS_Console", "DB_Logging").
19
20 Description of argument(s):
21 case Indicates whether the value returned
22 should be converted to upper or lower
23 case. Valid values are "upper", "lower"
24 or None.
25 """
26
27 plug_in_package_name = os.path.basename(gp.pgm_dir_path[:-1])
28 if case == "upper":
29 return plug_in_package_name.upper()
30 elif case == "lower":
31 return plug_in_package_name.lower()
32 else:
33 return plug_in_package_name
34
35
36def return_plug_vars():
Michael Walshf4c62a22017-11-13 15:40:57 -060037 r"""
38 Return an OrderedDict which is sorted by key and which contains all of the
39 plug-in environment variables.
40
41 Example excerpt of resulting dictionary:
42
43 plug_var_dict:
44 [AUTOBOOT_BASE_TOOL_DIR_PATH]: /fspmount/
45 [AUTOBOOT_BB_LEVEL]: <blank>
46 [AUTOBOOT_BOOT_FAIL]: 0
47 ...
48
49 This function also does the following:
50 - Set a default value for environment variable AUTOBOOT_OPENBMC_NICKNAME
51 if it is not already set.
52 - Register PASSWORD variables to prevent their values from being printed.
53 """
54
55 plug_in_package_name = get_plug_in_package_name(case="upper")
Michael Walsh8af99072018-03-26 10:50:02 -050056 regex = "^(AUTOBOOT|AUTOGUI|" + plug_in_package_name + ")_"
Michael Walshf4c62a22017-11-13 15:40:57 -060057
58 # Set a default for nickname.
59 if os.environ.get("AUTOBOOT_OPENBMC_NICKNAME", "") == "":
60 os.environ['AUTOBOOT_OPENBMC_NICKNAME'] = \
61 os.environ.get("AUTOBOOT_OPENBMC_HOST", "")
62
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050063 # For all variables specified in the parm_def file, we want them to
64 # default to "" rather than being unset.
65 # Process the parm_def file if it exists.
66 parm_def_file_path = gp.pgm_dir_path + "parm_def"
67 if os.path.exists(parm_def_file_path):
68 parm_defs = gm.my_parm_file(parm_def_file_path)
69 else:
70 parm_defs = collections.OrderedDict()
71 # Example parm_defs:
72 # parm_defs:
73 # parm_defs[rest_fail]: boolean
74 # parm_defs[command]: string
75 # parm_defs[esel_stop_file_path]: string
76
77 # Create a list of plug-in environment variables by pre-pending <all caps
78 # plug-in package name>_<all caps var name>
79 plug_in_parm_names = [plug_in_package_name + "_" + x for x in
80 map(str.upper, parm_defs.keys())]
81 # Example plug_in_parm_names:
82 # plug_in_parm_names:
83 # plug_in_parm_names[0]: STOP_REST_FAIL
84 # plug_in_parm_names[1]: STOP_COMMAND
85 # plug_in_parm_names[2]: STOP_ESEL_STOP_FILE_PATH
86
87 # Initialize unset plug-in vars.
88 for var_name in plug_in_parm_names:
89 os.environ[var_name] = os.environ.get(var_name, "")
90
Michael Walshf4c62a22017-11-13 15:40:57 -060091 plug_var_dict = \
92 collections.OrderedDict(sorted({k: v for (k, v) in
Gunnar Mills096cd562018-03-26 10:19:12 -050093 os.environ.items()
94 if re.match(regex, k)}.items()))
Michael Walshf4c62a22017-11-13 15:40:57 -060095
96 # Register password values to prevent printing them out. Any plug var
97 # whose name ends in PASSWORD will be registered.
98 password_vals = {k: v for (k, v) in plug_var_dict.items()
99 if re.match(r".*_PASSWORD$", k)}.values()
100 map(gp.register_passwords, password_vals)
101
102 return plug_var_dict
103
104
105def sprint_plug_vars(headers=1):
Michael Walshf4c62a22017-11-13 15:40:57 -0600106 r"""
107 Sprint the plug-in environment variables (i.e. those that begin with
108 AUTOBOOT_ those that begin with <plug-in package_name>_ in upper case
109 letters.).
110
111 Example excerpt of output:
112 AUTOBOOT_BASE_TOOL_DIR_PATH=/fspmount/
113 AUTOBOOT_BB_LEVEL=
114 AUTOBOOT_BOOT_FAIL=0
115 AUTOBOOT_BOOT_FAIL_THRESHOLD=1000000
116
117 Description of argument(s):
118 headers Print a header and a footer.
119 """
120
121 plug_var_dict = return_plug_vars()
122 buffer = ""
123 if headers:
124 buffer += "\n" + gp.sprint_dashes()
125 for key, value in plug_var_dict.items():
126 buffer += key + "=" + value + "\n"
127 if headers:
128 buffer += gp.sprint_dashes() + "\n"
129
130 return buffer
131
132
133def get_plug_vars():
Michael Walshf4c62a22017-11-13 15:40:57 -0600134 r"""
135 Get all plug-in variables and put them in corresponding global variables.
136
137 This would include all environment variables beginning with either
138 "AUTOBOOT_" or with the upper case version of the plug-in package name +
139 underscore (e.g. OP_SAMPLE_VAR1 for plug-in OP_Sample).
140
141 The global variables to be set will be both with and without the
142 "AUTOBOOT_" prefix. For example, if the environment variable in question
143 is AUTOBOOT_OPENBMC_HOST, this function will set global variable
144 AUTOBOOT_OPENBMC_HOST and global variable OPENBMC_HOST.
145 """
146
147 module = sys.modules['__main__']
148 plug_var_dict = return_plug_vars()
149
150 # Get all "AUTOBOOT_" environment variables and put them into globals.
151 for key, value in plug_var_dict.items():
152 setattr(module, key, value)
153 setattr(module, re.sub("^AUTOBOOT_", "", key), value)
154
155
156def get_plug_default(var_name,
157 default=None):
Michael Walshf4c62a22017-11-13 15:40:57 -0600158 r"""
159 Derive and return a default value for the given parm variable.
160
161 This function will assign a default by checking the following environment
162 variables in the order shown. The first one that has a value will be used.
163 - <upper case package_name>_<var_name>
164 - AUTOBOOT_OVERRIDE_<var_name>
165 - AUTOBOOT_<var_name>
166
167 If none of these are found, this function will return the value passed by
168 the caller in the "default" parm.
169
170 Example:
171
172 Let's say your plug-in is named "OS_Console" and you call this function as
173 follows:
174
175 get_plug_default("quiet", 0)
176
177 The first of these environment variables that is found to be set will be
178 used to provide the default value.
179 - OS_CONSOLE_QUIET
180 - AUTOBOOT_OVERRIDE_QUIET
181 - AUTOBOOT_QUIET
182
183 If none of those has a value, 0 (as specified by the caller in this
184 example) is returned.
185
186 Let's say the master driver program is named obmc_boot. obmc_boot program
187 is responsible for calling plug-ins. Let's further suppose that the user
188 wishes to run the master program with --debug=0 but wishes to have all
189 plug-ins run with --debug=1. This could be accomplished with the
190 following call:
191 export AUTOBOOT_OVERRIDE_DEBUG=1 ; obmc_boot --debug=0
192 --plug_in_dir_paths=<list of plug ins>
193
194 As another example, let's suppose that the user wishes to have just the
195 OS_Console plug-in run with debug and everything else to default to
196 debug=0. This could be accomplished as follows:
197 export OS_CONSOLE_DEBUG=1 ; obmc_boot --debug=0 --plug_in_dir_paths=<list
198 of plug ins>
199
200 And as one more example, let's say the user wishes to have obmc_boot and
201 OS_Console run without debug but have all other plug-ins run with debug:
202 export AUTOBOOT_OVERRIDE_DEBUG=1 ; export OS_CONSOLE_DEBUG=0 ; obmc_boot
203 --debug=0 --plug_in_dir_paths=<list of plug ins>
204
205 Description of argument(s):
206 var_name The name of the variable for which a
207 default value is to be calculated.
208 default The default value if one cannot be
209 determined.
210 """
211
212 var_name = var_name.upper()
213 plug_in_package_name = get_plug_in_package_name(case="upper")
214
215 package_var_name = plug_in_package_name + "_" + var_name
216 default_value = os.environ.get(package_var_name, None)
217 if default_value is not None:
218 # A package-name version of the variable was found so return its value.
219 return(default_value)
220
221 autoboot_var_name = "AUTOBOOT_OVERRIDE_" + var_name
222 default_value = os.environ.get(autoboot_var_name, None)
223 if default_value is not None:
224 # An AUTOBOOT_ version of the variable was found so return its value.
225 return default_value
226
227 autoboot_var_name = "AUTOBOOT_" + var_name
228 default_value = os.environ.get(autoboot_var_name, None)
229 if default_value is not None:
230 # An AUTOBOOT_ version of the variable was found so return its value.
231 return default_value
232
233 return default
234
235
236def srequired_plug_in(req_plug_in_names,
237 plug_in_dir_paths=None):
Michael Walshf4c62a22017-11-13 15:40:57 -0600238 r"""
239 Return an empty string if the required plug-ins are found in
240 plug_in_dir_paths. Otherwise, return an error string.
241
242 Example call:
243 error_message = srequired_plug_in(req_plug_in_names, plug_in_dir_paths)
244
245 Description of argument(s):
246 req_plug_in_names A list of plug_in names that the caller
247 requires (e.g. ['OS_Console']).
248 plug_in_dir_paths A string which is a colon-delimited list
249 of plug-ins specified by the user (e.g.
250 DB_Logging:FFDC:OS_Console:Perf). Path
251 values (e.g. "/home/robot/dir1") will be
252 stripped from this list to do the
253 analysis. Default value is the
254 AUTOBOOT_PLUG_IN_DIR_PATHS environment
255 variable.
256 """
257
258 # Calculate default value for plug_in_dir_paths.
259 if plug_in_dir_paths is None:
260 plug_in_dir_paths = os.environ.get("AUTOBOOT_PLUG_IN_DIR_PATHS", "")
261
262 error_message = ""
263
264 # Convert plug_in_dir_paths to a list of base names.
265 plug_in_dir_paths = \
266 filter(None, map(os.path.basename, plug_in_dir_paths.split(":")))
267
268 # Check for each of the user's required plug-ins.
269 for plug_in_name in req_plug_in_names:
270 if plug_in_name not in plug_in_dir_paths:
271 error_message = "The \"" + get_plug_in_package_name() +\
272 "\" plug-in cannot run unless the user also selects the \"" +\
273 plug_in_name + "\" plug in:\n" +\
274 gp.sprint_var(plug_in_dir_paths)
275
276 return error_message
277
278
279def required_plug_in(req_plug_in_names,
280 plug_in_dir_paths=None):
Michael Walshf4c62a22017-11-13 15:40:57 -0600281 r"""
282 Return True if each of the plug-ins in req_plug_in_names can be found in
283 plug_in_dir_paths Otherwise, return False and print an error message to
284 stderr.
285
286 Example call:
287 if not required_plug_in(['OS_Console'], AUTOBOOT_PLUG_IN_DIR_PATHS):
288 return False
289
290 Description of argument(s):
291 (See Description of arguments for srequired_plug_in (above)).
292 """
293
294 error_message = srequired_plug_in(req_plug_in_names, plug_in_dir_paths)
295 if not error_message == "":
296 gp.print_error_report(error_message)
297 return False
298
299 return True
300
301
302# Create print wrapper functions for all sprint functions defined above.
303# func_names contains a list of all print functions which should be created
304# from their sprint counterparts.
305func_names = ['print_plug_vars']
306
307# stderr_func_names is a list of functions whose output should go to stderr
308# rather than stdout.
309stderr_func_names = []
310
311replace_dict = dict(gp.replace_dict)
Michael Walsh81c02342018-01-05 15:43:28 -0600312replace_dict['mod_qualifier'] = 'gp.'
Michael Walshf4c62a22017-11-13 15:40:57 -0600313func_defs = gp.create_print_wrapper_funcs(func_names, stderr_func_names,
314 replace_dict)
315gp.gp_debug_print(func_defs)
316exec(func_defs)