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