George Keishing | e7e9171 | 2021-09-03 11:28:44 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 2 | |
| 3 | r""" |
| 4 | This module provides functions which are useful for running plug-ins. |
| 5 | """ |
| 6 | |
George Keishing | e635ddc | 2022-12-08 07:38:02 -0600 | [diff] [blame] | 7 | import glob |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 8 | import os |
| 9 | import sys |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 10 | |
George Keishing | e635ddc | 2022-12-08 07:38:02 -0600 | [diff] [blame] | 11 | import gen_misc as gm |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 12 | import gen_print as gp |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 13 | |
| 14 | # Some help text that is common to more than one program. |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 15 | plug_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 | ) |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 25 | |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 26 | mch_class_help_text = ( |
| 27 | 'The class of machine that we are testing (e.g. "op" = "open power",' |
| 28 | + ' "obmc" = "open bmc", etc).' |
| 29 | ) |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 30 | |
| 31 | PATH_LIST = gm.return_path_list() |
| 32 | |
| 33 | |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 34 | def get_plug_in_base_paths(): |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 35 | r""" |
| 36 | Get plug-in base paths and return them as a list. |
| 37 | |
Michael Walsh | 410b178 | 2019-10-22 15:56:18 -0500 | [diff] [blame] | 38 | This function searches the PATH_LIST (created from PATH environment variable) for any paths that have a |
| 39 | "plug_ins" subdirectory. All such paths are considered plug_in_base paths. |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 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 Mills | 096cd56 | 2018-03-26 10:19:12 -0500 | [diff] [blame] | 53 | |
Michael Walsh | 410b178 | 2019-10-22 15:56:18 -0500 | [diff] [blame] | 54 | # Define global plug_in_base_path_list and call get_plug_in_base_paths to set its value. |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 55 | plug_in_base_path_list = get_plug_in_base_paths() |
| 56 | |
| 57 | |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 58 | def find_plug_in_package(plug_in_name): |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 59 | r""" |
Michael Walsh | 410b178 | 2019-10-22 15:56:18 -0500 | [diff] [blame] | 60 | Find and return the normalized directory path of the specified plug in. This is done by searching the |
| 61 | global plug_in_base_path_list. |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 62 | |
| 63 | Description of arguments: |
Michael Walsh | 410b178 | 2019-10-22 15:56:18 -0500 | [diff] [blame] | 64 | plug_in_name The unqualified name of the plug-in package. |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 65 | """ |
| 66 | |
| 67 | global plug_in_base_path_list |
| 68 | for plug_in_base_dir_path in plug_in_base_path_list: |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 69 | candidate_plug_in_dir_path = ( |
| 70 | os.path.normpath(plug_in_base_dir_path + plug_in_name) + os.sep |
| 71 | ) |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 72 | if os.path.isdir(candidate_plug_in_dir_path): |
| 73 | return candidate_plug_in_dir_path |
| 74 | |
| 75 | return "" |
| 76 | |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 77 | |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 78 | def validate_plug_in_package(plug_in_dir_path, mch_class="obmc"): |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 79 | r""" |
Michael Walsh | 410b178 | 2019-10-22 15:56:18 -0500 | [diff] [blame] | 80 | Validate the plug in package and return the normalized plug-in directory path. |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 81 | |
| 82 | Description of arguments: |
Michael Walsh | 410b178 | 2019-10-22 15:56:18 -0500 | [diff] [blame] | 83 | plug_in_dir_path The "relative" or absolute path to a plug in package directory. |
| 84 | mch_class The class of machine that we are testing (e.g. "op" = "open power", |
| 85 | "obmc" = "open bmc", etc). |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 86 | """ |
| 87 | |
| 88 | gp.dprint_executing() |
| 89 | |
| 90 | if os.path.isabs(plug_in_dir_path): |
| 91 | # plug_in_dir_path begins with a slash so it is an absolute path. |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 92 | candidate_plug_in_dir_path = ( |
| 93 | os.path.normpath(plug_in_dir_path) + os.sep |
| 94 | ) |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 95 | if not os.path.isdir(candidate_plug_in_dir_path): |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 96 | gp.print_error_report( |
| 97 | 'Plug-in directory path "' |
| 98 | + plug_in_dir_path |
| 99 | + '" does not exist.\n' |
| 100 | ) |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 101 | exit(1) |
| 102 | else: |
Michael Walsh | 410b178 | 2019-10-22 15:56:18 -0500 | [diff] [blame] | 103 | # The plug_in_dir_path is actually a simple name (e.g. "OBMC_Sample")... |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 104 | candidate_plug_in_dir_path = find_plug_in_package(plug_in_dir_path) |
| 105 | if candidate_plug_in_dir_path == "": |
| 106 | global PATH_LIST |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 107 | gp.print_error_report( |
| 108 | 'Plug-in directory path "' |
| 109 | + plug_in_dir_path |
| 110 | + '" could not be found' |
| 111 | + " in any of the following directories:\n" |
| 112 | + gp.sprint_var(PATH_LIST) |
| 113 | ) |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 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): |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 118 | gp.print_error_report( |
| 119 | "The following file path could not be" |
| 120 | + " found:\n" |
| 121 | + gp.sprint_varx("supports_file_path", 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 |
| 126 | + '".\n' |
| 127 | ) |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 128 | exit(1) |
| 129 | |
| 130 | return candidate_plug_in_dir_path |
| 131 | |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 132 | |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 133 | def return_integrated_plug_ins(mch_class="obmc"): |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 134 | r""" |
Michael Walsh | 410b178 | 2019-10-22 15:56:18 -0500 | [diff] [blame] | 135 | Return a list of integrated plug-ins. Integrated plug-ins are plug-ins which are selected without regard |
| 136 | for whether the user has specified them. In other words, they are "integrated" into the program suite. |
| 137 | The programmer designates a plug-in as integrated by putting a file named "integrated" into the plug-in |
| 138 | package directory. |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 139 | |
| 140 | Description of arguments: |
Michael Walsh | 410b178 | 2019-10-22 15:56:18 -0500 | [diff] [blame] | 141 | mch_class The class of machine that we are testing (e.g. "op" = "open power", |
| 142 | "obmc" = "open bmc", etc). |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 143 | """ |
| 144 | |
| 145 | global plug_in_base_path_list |
| 146 | |
| 147 | integrated_plug_ins_list = [] |
| 148 | |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 149 | DEBUG_SKIP_INTEGRATED = int(os.getenv("DEBUG_SKIP_INTEGRATED", "0")) |
Michael Walsh | 6cd9cbe | 2017-06-30 16:59:36 -0500 | [diff] [blame] | 150 | |
| 151 | if DEBUG_SKIP_INTEGRATED: |
| 152 | return integrated_plug_ins_list |
| 153 | |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 154 | 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. |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 156 | mch_class_candidate_list = glob.glob( |
| 157 | plug_in_base_path + "*/supports_" + mch_class |
| 158 | ) |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 159 | for candidate_path in mch_class_candidate_list: |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 160 | integrated_plug_in_dir_path = ( |
| 161 | os.path.dirname(candidate_path) + os.sep |
| 162 | ) |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 163 | integrated_file_path = integrated_plug_in_dir_path + "integrated" |
| 164 | if os.path.exists(integrated_file_path): |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 165 | plug_in_name = os.path.basename( |
| 166 | os.path.dirname(candidate_path) |
| 167 | ) |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 168 | if plug_in_name not in integrated_plug_ins_list: |
| 169 | # If this plug-in has not already been added to the list... |
| 170 | integrated_plug_ins_list.append(plug_in_name) |
| 171 | |
| 172 | return integrated_plug_ins_list |
| 173 | |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 174 | |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 175 | def return_plug_in_packages_list(plug_in_dir_paths, mch_class="obmc"): |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 176 | r""" |
Michael Walsh | 410b178 | 2019-10-22 15:56:18 -0500 | [diff] [blame] | 177 | Return a list of plug-in packages given the plug_in_dir_paths string. This function calls |
| 178 | validate_plug_in_package so it will fail if plug_in_dir_paths contains any invalid plug-ins. |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 179 | |
| 180 | Description of arguments: |
Michael Walsh | 410b178 | 2019-10-22 15:56:18 -0500 | [diff] [blame] | 181 | plug_in_dir_path The "relative" or absolute path to a plug in package directory. |
| 182 | mch_class The class of machine that we are testing (e.g. "op" = "open power", |
| 183 | "obmc" = "open bmc", etc). |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 184 | """ |
| 185 | |
| 186 | if plug_in_dir_paths != "": |
| 187 | plug_in_packages_list = plug_in_dir_paths.split(":") |
| 188 | else: |
| 189 | plug_in_packages_list = [] |
| 190 | |
| 191 | # Get a list of integrated plug-ins (w/o full path names). |
| 192 | integrated_plug_ins_list = return_integrated_plug_ins(mch_class) |
Michael Walsh | 410b178 | 2019-10-22 15:56:18 -0500 | [diff] [blame] | 193 | # Put both lists together in plug_in_packages_list with no duplicates. NOTE: This won't catch |
| 194 | # duplicates if the caller specifies the full path name of a native plug-in but that should be rare |
| 195 | # enough. |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 196 | |
| 197 | plug_in_packages_list = plug_in_packages_list + integrated_plug_ins_list |
| 198 | |
Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 199 | plug_in_packages_list = list( |
| 200 | set( |
| 201 | [ |
| 202 | validate_plug_in_package(path, mch_class) |
| 203 | for path in plug_in_packages_list |
| 204 | ] |
| 205 | ) |
| 206 | ) |
Michael Walsh | 7423c01 | 2016-10-04 10:27:21 -0500 | [diff] [blame] | 207 | |
| 208 | return plug_in_packages_list |