1#!/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) 290replace_dict['mod_qualifier'] = 'gp.' 291func_defs = gp.create_print_wrapper_funcs(func_names, stderr_func_names, 292 replace_dict) 293gp.gp_debug_print(func_defs) 294exec(func_defs) 295