blob: fc57cef3460135a52d6951da0d6a394c5e68e21a [file] [log] [blame]
George Keishinge7e91712021-09-03 11:28:44 -05001#!/usr/bin/env python3
Michael Walsh7423c012016-10-04 10:27:21 -05002
3r"""
4This module provides functions which are useful for running plug-ins.
5"""
6
7import sys
8import os
Michael Walsh7423c012016-10-04 10:27:21 -05009import 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
Michael Walsh7423c012016-10-04 10:27:21 -050032def get_plug_in_base_paths():
Michael Walsh7423c012016-10-04 10:27:21 -050033 r"""
34 Get plug-in base paths and return them as a list.
35
Michael Walsh410b1782019-10-22 15:56:18 -050036 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.
Michael Walsh7423c012016-10-04 10:27:21 -050038 """
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
Gunnar Mills096cd562018-03-26 10:19:12 -050051
Michael Walsh410b1782019-10-22 15:56:18 -050052# Define global plug_in_base_path_list and call get_plug_in_base_paths to set its value.
Michael Walsh7423c012016-10-04 10:27:21 -050053plug_in_base_path_list = get_plug_in_base_paths()
54
55
Michael Walsh7423c012016-10-04 10:27:21 -050056def find_plug_in_package(plug_in_name):
Michael Walsh7423c012016-10-04 10:27:21 -050057 r"""
Michael Walsh410b1782019-10-22 15:56:18 -050058 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.
Michael Walsh7423c012016-10-04 10:27:21 -050060
61 Description of arguments:
Michael Walsh410b1782019-10-22 15:56:18 -050062 plug_in_name The unqualified name of the plug-in package.
Michael Walsh7423c012016-10-04 10:27:21 -050063 """
64
65 global plug_in_base_path_list
66 for plug_in_base_dir_path in plug_in_base_path_list:
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050067 candidate_plug_in_dir_path = os.path.normpath(plug_in_base_dir_path
68 + plug_in_name) + \
Michael Walsh6cd9cbe2017-06-30 16:59:36 -050069 os.sep
Michael Walsh7423c012016-10-04 10:27:21 -050070 if os.path.isdir(candidate_plug_in_dir_path):
71 return candidate_plug_in_dir_path
72
73 return ""
74
Michael Walsh7423c012016-10-04 10:27:21 -050075
Michael Walsh7423c012016-10-04 10:27:21 -050076def validate_plug_in_package(plug_in_dir_path,
77 mch_class="obmc"):
Michael Walsh7423c012016-10-04 10:27:21 -050078 r"""
Michael Walsh410b1782019-10-22 15:56:18 -050079 Validate the plug in package and return the normalized plug-in directory path.
Michael Walsh7423c012016-10-04 10:27:21 -050080
81 Description of arguments:
Michael Walsh410b1782019-10-22 15:56:18 -050082 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).
Michael Walsh7423c012016-10-04 10:27:21 -050085 """
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) +\
Michael Walsh6cd9cbe2017-06-30 16:59:36 -050092 os.sep
Michael Walsh7423c012016-10-04 10:27:21 -050093 if not os.path.isdir(candidate_plug_in_dir_path):
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050094 gp.print_error_report("Plug-in directory path \""
95 + plug_in_dir_path + "\" does not exist.\n")
Michael Walsh7423c012016-10-04 10:27:21 -050096 exit(1)
97 else:
Michael Walsh410b1782019-10-22 15:56:18 -050098 # The plug_in_dir_path is actually a simple name (e.g. "OBMC_Sample")...
Michael Walsh7423c012016-10-04 10:27:21 -050099 candidate_plug_in_dir_path = find_plug_in_package(plug_in_dir_path)
100 if candidate_plug_in_dir_path == "":
101 global PATH_LIST
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500102 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))
Michael Walsh7423c012016-10-04 10:27:21 -0500106 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):
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500110 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")
Michael Walsh7423c012016-10-04 10:27:21 -0500118 exit(1)
119
120 return candidate_plug_in_dir_path
121
Michael Walsh7423c012016-10-04 10:27:21 -0500122
Michael Walsh7423c012016-10-04 10:27:21 -0500123def return_integrated_plug_ins(mch_class="obmc"):
Michael Walsh7423c012016-10-04 10:27:21 -0500124 r"""
Michael Walsh410b1782019-10-22 15:56:18 -0500125 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.
Michael Walsh7423c012016-10-04 10:27:21 -0500129
130 Description of arguments:
Michael Walsh410b1782019-10-22 15:56:18 -0500131 mch_class The class of machine that we are testing (e.g. "op" = "open power",
132 "obmc" = "open bmc", etc).
Michael Walsh7423c012016-10-04 10:27:21 -0500133 """
134
135 global plug_in_base_path_list
136
137 integrated_plug_ins_list = []
138
Michael Walsh6cd9cbe2017-06-30 16:59:36 -0500139 DEBUG_SKIP_INTEGRATED = int(os.getenv('DEBUG_SKIP_INTEGRATED', '0'))
140
141 if DEBUG_SKIP_INTEGRATED:
142 return integrated_plug_ins_list
143
Michael Walsh7423c012016-10-04 10:27:21 -0500144 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.
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500146 mch_class_candidate_list = glob.glob(plug_in_base_path
147 + "*/supports_" + mch_class)
Michael Walsh7423c012016-10-04 10:27:21 -0500148 for candidate_path in mch_class_candidate_list:
149 integrated_plug_in_dir_path = os.path.dirname(candidate_path) +\
Michael Walsh6cd9cbe2017-06-30 16:59:36 -0500150 os.sep
Michael Walsh7423c012016-10-04 10:27:21 -0500151 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
Michael Walsh7423c012016-10-04 10:27:21 -0500161
Michael Walsh7423c012016-10-04 10:27:21 -0500162def return_plug_in_packages_list(plug_in_dir_paths,
163 mch_class="obmc"):
Michael Walsh7423c012016-10-04 10:27:21 -0500164 r"""
Michael Walsh410b1782019-10-22 15:56:18 -0500165 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.
Michael Walsh7423c012016-10-04 10:27:21 -0500167
168 Description of arguments:
Michael Walsh410b1782019-10-22 15:56:18 -0500169 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).
Michael Walsh7423c012016-10-04 10:27:21 -0500172 """
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)
Michael Walsh410b1782019-10-22 15:56:18 -0500181 # 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.
Michael Walsh7423c012016-10-04 10:27:21 -0500184
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