diff options
Diffstat (limited to 'scripts/lib/wic/plugin.py')
| -rw-r--r-- | scripts/lib/wic/plugin.py | 99 |
1 files changed, 27 insertions, 72 deletions
diff --git a/scripts/lib/wic/plugin.py b/scripts/lib/wic/plugin.py index c200822af7..b45478cd9a 100644 --- a/scripts/lib/wic/plugin.py +++ b/scripts/lib/wic/plugin.py | |||
| @@ -16,95 +16,50 @@ | |||
| 16 | # Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 16 | # Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 17 | 17 | ||
| 18 | import os | 18 | import os |
| 19 | import sys | ||
| 20 | import logging | 19 | import logging |
| 21 | 20 | ||
| 21 | from importlib.machinery import SourceFileLoader | ||
| 22 | |||
| 22 | from wic import pluginbase, WicError | 23 | from wic import pluginbase, WicError |
| 23 | from wic.utils.misc import get_bitbake_var | 24 | from wic.utils.misc import get_bitbake_var |
| 24 | 25 | ||
| 25 | PLUGIN_TYPES = ["imager", "source"] | 26 | PLUGIN_TYPES = ["imager", "source"] |
| 26 | 27 | ||
| 27 | PLUGIN_DIR = "/lib/wic/plugins" # relative to scripts | 28 | SCRIPTS_PLUGIN_DIR = "scripts/lib/wic/plugins" |
| 28 | SCRIPTS_PLUGIN_DIR = "scripts" + PLUGIN_DIR | ||
| 29 | 29 | ||
| 30 | logger = logging.getLogger('wic') | 30 | logger = logging.getLogger('wic') |
| 31 | 31 | ||
| 32 | class PluginMgr: | 32 | class PluginMgr: |
| 33 | plugin_dirs = {} | 33 | _plugin_dirs = [] |
| 34 | wic_path = os.path.dirname(__file__) | 34 | _loaded = [] |
| 35 | eos = wic_path.rfind('scripts') + len('scripts') | ||
| 36 | scripts_path = wic_path[:eos] | ||
| 37 | plugin_dir = scripts_path + PLUGIN_DIR | ||
| 38 | layers_path = None | ||
| 39 | |||
| 40 | @classmethod | ||
| 41 | def _build_plugin_dir_list(cls, plugin_dir, ptype): | ||
| 42 | if cls.layers_path is None: | ||
| 43 | cls.layers_path = get_bitbake_var("BBLAYERS") | ||
| 44 | layer_dirs = [] | ||
| 45 | |||
| 46 | if cls.layers_path is not None: | ||
| 47 | for layer_path in cls.layers_path.split(): | ||
| 48 | path = os.path.join(layer_path, SCRIPTS_PLUGIN_DIR, ptype) | ||
| 49 | layer_dirs.append(path) | ||
| 50 | |||
| 51 | path = os.path.join(plugin_dir, ptype) | ||
| 52 | layer_dirs.append(path) | ||
| 53 | |||
| 54 | return layer_dirs | ||
| 55 | |||
| 56 | @classmethod | ||
| 57 | def append_dirs(cls, dirs): | ||
| 58 | for path in dirs: | ||
| 59 | cls._add_plugindir(path) | ||
| 60 | |||
| 61 | # load all the plugins AGAIN | ||
| 62 | cls._load_all() | ||
| 63 | |||
| 64 | @classmethod | ||
| 65 | def _add_plugindir(cls, path): | ||
| 66 | path = os.path.abspath(os.path.expanduser(path)) | ||
| 67 | |||
| 68 | if not os.path.isdir(path): | ||
| 69 | return | ||
| 70 | |||
| 71 | if path not in cls.plugin_dirs: | ||
| 72 | cls.plugin_dirs[path] = False | ||
| 73 | # the value True/False means "loaded" | ||
| 74 | |||
| 75 | @classmethod | ||
| 76 | def _load_all(cls): | ||
| 77 | for (pdir, loaded) in cls.plugin_dirs.items(): | ||
| 78 | if loaded: | ||
| 79 | continue | ||
| 80 | |||
| 81 | sys.path.insert(0, pdir) | ||
| 82 | for mod in [x[:-3] for x in os.listdir(pdir) if x.endswith(".py")]: | ||
| 83 | if mod and mod != '__init__': | ||
| 84 | if mod in sys.modules: | ||
| 85 | logger.warning("Module %s already exists, skip", mod) | ||
| 86 | else: | ||
| 87 | try: | ||
| 88 | pymod = __import__(mod) | ||
| 89 | cls.plugin_dirs[pdir] = True | ||
| 90 | logger.debug("Plugin module %s:%s imported", | ||
| 91 | mod, pymod.__file__) | ||
| 92 | except ImportError as err: | ||
| 93 | logger.warning('Failed to load plugin %s/%s: %s', | ||
| 94 | os.path.basename(pdir), mod, err) | ||
| 95 | |||
| 96 | del sys.path[0] | ||
| 97 | 35 | ||
| 98 | @classmethod | 36 | @classmethod |
| 99 | def get_plugins(cls, ptype): | 37 | def get_plugins(cls, ptype): |
| 100 | """ the return value is dict of name:class pairs """ | 38 | """Get dictionary of <plugin_name>:<class> pairs.""" |
| 101 | |||
| 102 | if ptype not in PLUGIN_TYPES: | 39 | if ptype not in PLUGIN_TYPES: |
| 103 | raise WicError('%s is not valid plugin type' % ptype) | 40 | raise WicError('%s is not valid plugin type' % ptype) |
| 104 | 41 | ||
| 105 | plugins_dir = cls._build_plugin_dir_list(cls.plugin_dir, ptype) | 42 | # collect plugin directories |
| 106 | 43 | if not cls._plugin_dirs: | |
| 107 | cls.append_dirs(plugins_dir) | 44 | cls._plugin_dirs = [os.path.join(os.path.dirname(__file__), 'plugins')] |
| 45 | layers = get_bitbake_var("BBLAYERS") or '' | ||
| 46 | for layer_path in layers.split(): | ||
| 47 | path = os.path.join(layer_path, SCRIPTS_PLUGIN_DIR) | ||
| 48 | path = os.path.abspath(os.path.expanduser(path)) | ||
| 49 | if path not in cls._plugin_dirs and os.path.isdir(path): | ||
| 50 | cls._plugin_dirs.insert(0, path) | ||
| 51 | |||
| 52 | # load plugins | ||
| 53 | for pdir in cls._plugin_dirs: | ||
| 54 | ppath = os.path.join(pdir, ptype) | ||
| 55 | if ppath not in cls._loaded: | ||
| 56 | if os.path.isdir(ppath): | ||
| 57 | for fname in os.listdir(ppath): | ||
| 58 | if fname.endswith('.py'): | ||
| 59 | mname = fname[:-3] | ||
| 60 | mpath = os.path.join(ppath, fname) | ||
| 61 | SourceFileLoader(mname, mpath).load_module() | ||
| 62 | cls._loaded.append(ppath) | ||
| 108 | 63 | ||
| 109 | return pluginbase.get_plugins(ptype) | 64 | return pluginbase.get_plugins(ptype) |
| 110 | 65 | ||
