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