| #!/usr/bin/env python3 | 
 |  | 
 | r""" | 
 | This module provides functions which are useful for running plug-ins. | 
 | """ | 
 |  | 
 | import glob | 
 | import os | 
 | import sys | 
 |  | 
 | import gen_misc as gm | 
 | import gen_print as gp | 
 |  | 
 | # Some help text that is common to more than one program. | 
 | plug_in_dir_paths_help_text = ( | 
 |     "This is a colon-separated list of plug-in directory paths.  If one" | 
 |     + " of the entries in the list is a plain directory name (i.e. no" | 
 |     + " path info), it will be taken to be a native plug-in.  In that case," | 
 |     + ' %(prog)s will search for the native plug-in in the "plug-ins"' | 
 |     + " subdirectory of each path in the PATH environment variable until it" | 
 |     + " is found.  Also, integrated plug-ins will automatically be appended" | 
 |     + " to your plug_in_dir_paths list.  An integrated plug-in is any plug-in" | 
 |     + ' found using the PATH variable that contains a file named "integrated".' | 
 | ) | 
 |  | 
 | mch_class_help_text = ( | 
 |     'The class of machine that we are testing (e.g. "op" = "open power",' | 
 |     + ' "obmc" = "open bmc", etc).' | 
 | ) | 
 |  | 
 | PATH_LIST = gm.return_path_list() | 
 |  | 
 |  | 
 | def get_plug_in_base_paths(): | 
 |     r""" | 
 |     Get plug-in base paths and return them as a list. | 
 |  | 
 |     This function searches the PATH_LIST (created from PATH environment variable) for any paths that have a | 
 |     "plug_ins" subdirectory.  All such paths are considered plug_in_base paths. | 
 |     """ | 
 |  | 
 |     global PATH_LIST | 
 |  | 
 |     plug_in_base_path_list = [] | 
 |  | 
 |     for path in PATH_LIST: | 
 |         candidate_plug_in_base_path = path + "plug_ins/" | 
 |         if os.path.isdir(candidate_plug_in_base_path): | 
 |             plug_in_base_path_list.append(candidate_plug_in_base_path) | 
 |  | 
 |     return plug_in_base_path_list | 
 |  | 
 |  | 
 | # Define global plug_in_base_path_list and call get_plug_in_base_paths to set its value. | 
 | plug_in_base_path_list = get_plug_in_base_paths() | 
 |  | 
 |  | 
 | def find_plug_in_package(plug_in_name): | 
 |     r""" | 
 |     Find and return the normalized directory path of the specified plug in.  This is done by searching the | 
 |     global plug_in_base_path_list. | 
 |  | 
 |     Description of arguments: | 
 |     plug_in_name                    The unqualified name of the plug-in package. | 
 |     """ | 
 |  | 
 |     global plug_in_base_path_list | 
 |     for plug_in_base_dir_path in plug_in_base_path_list: | 
 |         candidate_plug_in_dir_path = ( | 
 |             os.path.normpath(plug_in_base_dir_path + plug_in_name) + os.sep | 
 |         ) | 
 |         if os.path.isdir(candidate_plug_in_dir_path): | 
 |             return candidate_plug_in_dir_path | 
 |  | 
 |     return "" | 
 |  | 
 |  | 
 | def validate_plug_in_package(plug_in_dir_path, mch_class="obmc"): | 
 |     r""" | 
 |     Validate the plug in package and return the normalized plug-in directory path. | 
 |  | 
 |     Description of arguments: | 
 |     plug_in_dir_path                The "relative" or absolute path to a plug in package directory. | 
 |     mch_class                       The class of machine that we are testing (e.g. "op" = "open power", | 
 |                                     "obmc" = "open bmc", etc). | 
 |     """ | 
 |  | 
 |     gp.dprint_executing() | 
 |  | 
 |     if os.path.isabs(plug_in_dir_path): | 
 |         # plug_in_dir_path begins with a slash so it is an absolute path. | 
 |         candidate_plug_in_dir_path = ( | 
 |             os.path.normpath(plug_in_dir_path) + os.sep | 
 |         ) | 
 |         if not os.path.isdir(candidate_plug_in_dir_path): | 
 |             gp.print_error_report( | 
 |                 'Plug-in directory path "' | 
 |                 + plug_in_dir_path | 
 |                 + '" does not exist.\n' | 
 |             ) | 
 |             exit(1) | 
 |     else: | 
 |         # The plug_in_dir_path is actually a simple name (e.g. "OBMC_Sample")... | 
 |         candidate_plug_in_dir_path = find_plug_in_package(plug_in_dir_path) | 
 |         if candidate_plug_in_dir_path == "": | 
 |             global PATH_LIST | 
 |             gp.print_error_report( | 
 |                 'Plug-in directory path "' | 
 |                 + plug_in_dir_path | 
 |                 + '" could not be found' | 
 |                 + " in any of the following directories:\n" | 
 |                 + gp.sprint_var(PATH_LIST) | 
 |             ) | 
 |             exit(1) | 
 |     # Make sure that this plug-in supports us... | 
 |     supports_file_path = candidate_plug_in_dir_path + "supports_" + mch_class | 
 |     if not os.path.exists(supports_file_path): | 
 |         gp.print_error_report( | 
 |             "The following file path could not be" | 
 |             + " found:\n" | 
 |             + gp.sprint_varx("supports_file_path", supports_file_path) | 
 |             + "\nThis file is necessary to indicate that" | 
 |             + " the given plug-in supports the class of" | 
 |             + ' machine we are testing, namely "' | 
 |             + mch_class | 
 |             + '".\n' | 
 |         ) | 
 |         exit(1) | 
 |  | 
 |     return candidate_plug_in_dir_path | 
 |  | 
 |  | 
 | def return_integrated_plug_ins(mch_class="obmc"): | 
 |     r""" | 
 |     Return a list of integrated plug-ins.  Integrated plug-ins are plug-ins which are selected without regard | 
 |     for whether the user has specified them.  In other words, they are "integrated" into the program suite. | 
 |     The programmer designates a plug-in as integrated by putting a file named "integrated" into the plug-in | 
 |     package directory. | 
 |  | 
 |     Description of arguments: | 
 |     mch_class                       The class of machine that we are testing (e.g. "op" = "open power", | 
 |                                     "obmc" = "open bmc", etc). | 
 |     """ | 
 |  | 
 |     global plug_in_base_path_list | 
 |  | 
 |     integrated_plug_ins_list = [] | 
 |  | 
 |     DEBUG_SKIP_INTEGRATED = int(os.getenv("DEBUG_SKIP_INTEGRATED", "0")) | 
 |  | 
 |     if DEBUG_SKIP_INTEGRATED: | 
 |         return integrated_plug_ins_list | 
 |  | 
 |     for plug_in_base_path in plug_in_base_path_list: | 
 |         # Get a list of all plug-in paths that support our mch_class. | 
 |         mch_class_candidate_list = glob.glob( | 
 |             plug_in_base_path + "*/supports_" + mch_class | 
 |         ) | 
 |         for candidate_path in mch_class_candidate_list: | 
 |             integrated_plug_in_dir_path = ( | 
 |                 os.path.dirname(candidate_path) + os.sep | 
 |             ) | 
 |             integrated_file_path = integrated_plug_in_dir_path + "integrated" | 
 |             if os.path.exists(integrated_file_path): | 
 |                 plug_in_name = os.path.basename( | 
 |                     os.path.dirname(candidate_path) | 
 |                 ) | 
 |                 if plug_in_name not in integrated_plug_ins_list: | 
 |                     # If this plug-in has not already been added to the list... | 
 |                     integrated_plug_ins_list.append(plug_in_name) | 
 |  | 
 |     return integrated_plug_ins_list | 
 |  | 
 |  | 
 | def return_plug_in_packages_list(plug_in_dir_paths, mch_class="obmc"): | 
 |     r""" | 
 |     Return a list of plug-in packages given the plug_in_dir_paths string.  This function calls | 
 |     validate_plug_in_package so it will fail if plug_in_dir_paths contains any invalid plug-ins. | 
 |  | 
 |     Description of arguments: | 
 |     plug_in_dir_path                The "relative" or absolute path to a plug in package directory. | 
 |     mch_class                       The class of machine that we are testing (e.g. "op" = "open power", | 
 |                                     "obmc" = "open bmc", etc). | 
 |     """ | 
 |  | 
 |     if plug_in_dir_paths != "": | 
 |         plug_in_packages_list = plug_in_dir_paths.split(":") | 
 |     else: | 
 |         plug_in_packages_list = [] | 
 |  | 
 |     # Get a list of integrated plug-ins (w/o full path names). | 
 |     integrated_plug_ins_list = return_integrated_plug_ins(mch_class) | 
 |     # Put both lists together in plug_in_packages_list with no duplicates.  NOTE: This won't catch | 
 |     # duplicates if the caller specifies the full path name of a native plug-in but that should be rare | 
 |     # enough. | 
 |  | 
 |     plug_in_packages_list = plug_in_packages_list + integrated_plug_ins_list | 
 |  | 
 |     plug_in_packages_list = list( | 
 |         set( | 
 |             [ | 
 |                 validate_plug_in_package(path, mch_class) | 
 |                 for path in plug_in_packages_list | 
 |             ] | 
 |         ) | 
 |     ) | 
 |  | 
 |     return plug_in_packages_list |