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