1#!/usr/bin/env python3 2 3r""" 4This module provides functions which are useful for running plug-ins. 5""" 6 7import sys 8import os 9import glob 10 11import gen_print as gp 12import gen_misc as gm 13 14# Some help text that is common to more than one program. 15plug_in_dir_paths_help_text = \ 16 'This is a colon-separated list of plug-in directory paths. If one' +\ 17 ' of the entries in the list is a plain directory name (i.e. no' +\ 18 ' path info), it will be taken to be a native plug-in. In that case,' +\ 19 ' %(prog)s will search for the native plug-in in the "plug-ins"' +\ 20 ' subdirectory of each path in the PATH environment variable until it' +\ 21 ' is found. Also, integrated plug-ins will automatically be appended' +\ 22 ' to your plug_in_dir_paths list. An integrated plug-in is any plug-in' +\ 23 ' found using the PATH variable that contains a file named "integrated".' 24 25mch_class_help_text = \ 26 'The class of machine that we are testing (e.g. "op" = "open power",' +\ 27 ' "obmc" = "open bmc", etc).' 28 29PATH_LIST = gm.return_path_list() 30 31 32def get_plug_in_base_paths(): 33 r""" 34 Get plug-in base paths and return them as a list. 35 36 This function searches the PATH_LIST (created from PATH environment variable) for any paths that have a 37 "plug_ins" subdirectory. All such paths are considered plug_in_base paths. 38 """ 39 40 global PATH_LIST 41 42 plug_in_base_path_list = [] 43 44 for path in PATH_LIST: 45 candidate_plug_in_base_path = path + "plug_ins/" 46 if os.path.isdir(candidate_plug_in_base_path): 47 plug_in_base_path_list.append(candidate_plug_in_base_path) 48 49 return plug_in_base_path_list 50 51 52# Define global plug_in_base_path_list and call get_plug_in_base_paths to set its value. 53plug_in_base_path_list = get_plug_in_base_paths() 54 55 56def find_plug_in_package(plug_in_name): 57 r""" 58 Find and return the normalized directory path of the specified plug in. This is done by searching the 59 global plug_in_base_path_list. 60 61 Description of arguments: 62 plug_in_name The unqualified name of the plug-in package. 63 """ 64 65 global plug_in_base_path_list 66 for plug_in_base_dir_path in plug_in_base_path_list: 67 candidate_plug_in_dir_path = os.path.normpath(plug_in_base_dir_path 68 + plug_in_name) + \ 69 os.sep 70 if os.path.isdir(candidate_plug_in_dir_path): 71 return candidate_plug_in_dir_path 72 73 return "" 74 75 76def validate_plug_in_package(plug_in_dir_path, 77 mch_class="obmc"): 78 r""" 79 Validate the plug in package and return the normalized plug-in directory path. 80 81 Description of arguments: 82 plug_in_dir_path The "relative" or absolute path to a plug in package directory. 83 mch_class The class of machine that we are testing (e.g. "op" = "open power", 84 "obmc" = "open bmc", etc). 85 """ 86 87 gp.dprint_executing() 88 89 if os.path.isabs(plug_in_dir_path): 90 # plug_in_dir_path begins with a slash so it is an absolute path. 91 candidate_plug_in_dir_path = os.path.normpath(plug_in_dir_path) +\ 92 os.sep 93 if not os.path.isdir(candidate_plug_in_dir_path): 94 gp.print_error_report("Plug-in directory path \"" 95 + plug_in_dir_path + "\" does not exist.\n") 96 exit(1) 97 else: 98 # The plug_in_dir_path is actually a simple name (e.g. "OBMC_Sample")... 99 candidate_plug_in_dir_path = find_plug_in_package(plug_in_dir_path) 100 if candidate_plug_in_dir_path == "": 101 global PATH_LIST 102 gp.print_error_report("Plug-in directory path \"" 103 + plug_in_dir_path + "\" could not be found" 104 + " in any of the following directories:\n" 105 + gp.sprint_var(PATH_LIST)) 106 exit(1) 107 # Make sure that this plug-in supports us... 108 supports_file_path = candidate_plug_in_dir_path + "supports_" + mch_class 109 if not os.path.exists(supports_file_path): 110 gp.print_error_report("The following file path could not be" 111 + " found:\n" 112 + gp.sprint_varx("supports_file_path", 113 supports_file_path) 114 + "\nThis file is necessary to indicate that" 115 + " the given plug-in supports the class of" 116 + " machine we are testing, namely \"" 117 + mch_class + "\".\n") 118 exit(1) 119 120 return candidate_plug_in_dir_path 121 122 123def return_integrated_plug_ins(mch_class="obmc"): 124 r""" 125 Return a list of integrated plug-ins. Integrated plug-ins are plug-ins which are selected without regard 126 for whether the user has specified them. In other words, they are "integrated" into the program suite. 127 The programmer designates a plug-in as integrated by putting a file named "integrated" into the plug-in 128 package directory. 129 130 Description of arguments: 131 mch_class The class of machine that we are testing (e.g. "op" = "open power", 132 "obmc" = "open bmc", etc). 133 """ 134 135 global plug_in_base_path_list 136 137 integrated_plug_ins_list = [] 138 139 DEBUG_SKIP_INTEGRATED = int(os.getenv('DEBUG_SKIP_INTEGRATED', '0')) 140 141 if DEBUG_SKIP_INTEGRATED: 142 return integrated_plug_ins_list 143 144 for plug_in_base_path in plug_in_base_path_list: 145 # Get a list of all plug-in paths that support our mch_class. 146 mch_class_candidate_list = glob.glob(plug_in_base_path 147 + "*/supports_" + mch_class) 148 for candidate_path in mch_class_candidate_list: 149 integrated_plug_in_dir_path = os.path.dirname(candidate_path) +\ 150 os.sep 151 integrated_file_path = integrated_plug_in_dir_path + "integrated" 152 if os.path.exists(integrated_file_path): 153 plug_in_name = \ 154 os.path.basename(os.path.dirname(candidate_path)) 155 if plug_in_name not in integrated_plug_ins_list: 156 # If this plug-in has not already been added to the list... 157 integrated_plug_ins_list.append(plug_in_name) 158 159 return integrated_plug_ins_list 160 161 162def return_plug_in_packages_list(plug_in_dir_paths, 163 mch_class="obmc"): 164 r""" 165 Return a list of plug-in packages given the plug_in_dir_paths string. This function calls 166 validate_plug_in_package so it will fail if plug_in_dir_paths contains any invalid plug-ins. 167 168 Description of arguments: 169 plug_in_dir_path The "relative" or absolute path to a plug in package directory. 170 mch_class The class of machine that we are testing (e.g. "op" = "open power", 171 "obmc" = "open bmc", etc). 172 """ 173 174 if plug_in_dir_paths != "": 175 plug_in_packages_list = plug_in_dir_paths.split(":") 176 else: 177 plug_in_packages_list = [] 178 179 # Get a list of integrated plug-ins (w/o full path names). 180 integrated_plug_ins_list = return_integrated_plug_ins(mch_class) 181 # Put both lists together in plug_in_packages_list with no duplicates. NOTE: This won't catch 182 # duplicates if the caller specifies the full path name of a native plug-in but that should be rare 183 # enough. 184 185 plug_in_packages_list = plug_in_packages_list + integrated_plug_ins_list 186 187 plug_in_packages_list = \ 188 list(set([validate_plug_in_package(path, mch_class) 189 for path in plug_in_packages_list])) 190 191 return plug_in_packages_list 192