diff options
-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 | ||