summaryrefslogtreecommitdiffstats
path: root/scripts/lib/wic/plugin.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/wic/plugin.py')
-rw-r--r--scripts/lib/wic/plugin.py156
1 files changed, 156 insertions, 0 deletions
diff --git a/scripts/lib/wic/plugin.py b/scripts/lib/wic/plugin.py
new file mode 100644
index 0000000000..41a80175ca
--- /dev/null
+++ b/scripts/lib/wic/plugin.py
@@ -0,0 +1,156 @@
1#!/usr/bin/env python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os, sys
19
20from wic import msger
21from wic import pluginbase
22from wic.utils import errors
23from wic.utils.oe.misc import *
24
25__ALL__ = ['PluginMgr', 'pluginmgr']
26
27PLUGIN_TYPES = ["imager", "source"]
28
29PLUGIN_DIR = "/lib/wic/plugins" # relative to scripts
30SCRIPTS_PLUGIN_DIR = "scripts" + PLUGIN_DIR
31
32class PluginMgr(object):
33 plugin_dirs = {}
34
35 # make the manager class as singleton
36 _instance = None
37 def __new__(cls, *args, **kwargs):
38 if not cls._instance:
39 cls._instance = super(PluginMgr, cls).__new__(cls, *args, **kwargs)
40
41 return cls._instance
42
43 def __init__(self):
44 wic_path = os.path.dirname(__file__)
45 eos = wic_path.find('scripts') + len('scripts')
46 scripts_path = wic_path[:eos]
47 self.scripts_path = scripts_path
48 self.plugin_dir = scripts_path + PLUGIN_DIR
49 self.layers_path = None
50
51 def _build_plugin_dir_list(self, dl, ptype):
52 if self.layers_path is None:
53 self.layers_path = get_bitbake_var("BBLAYERS")
54 layer_dirs = []
55
56 if self.layers_path is not None:
57 for layer_path in self.layers_path.split():
58 path = os.path.join(layer_path, SCRIPTS_PLUGIN_DIR, ptype)
59 layer_dirs.append(path)
60
61 path = os.path.join(dl, ptype)
62 layer_dirs.append(path)
63
64 return layer_dirs
65
66 def append_dirs(self, dirs):
67 for path in dirs:
68 self._add_plugindir(path)
69
70 # load all the plugins AGAIN
71 self._load_all()
72
73 def _add_plugindir(self, path):
74 path = os.path.abspath(os.path.expanduser(path))
75
76 if not os.path.isdir(path):
77 msger.debug("Plugin dir is not a directory or does not exist: %s"\
78 % path)
79 return
80
81 if path not in self.plugin_dirs:
82 self.plugin_dirs[path] = False
83 # the value True/False means "loaded"
84
85 def _load_all(self):
86 for (pdir, loaded) in self.plugin_dirs.iteritems():
87 if loaded: continue
88
89 sys.path.insert(0, pdir)
90 for mod in [x[:-3] for x in os.listdir(pdir) if x.endswith(".py")]:
91 if mod and mod != '__init__':
92 if mod in sys.modules:
93 #self.plugin_dirs[pdir] = True
94 msger.warning("Module %s already exists, skip" % mod)
95 else:
96 try:
97 pymod = __import__(mod)
98 self.plugin_dirs[pdir] = True
99 msger.debug("Plugin module %s:%s imported"\
100 % (mod, pymod.__file__))
101 except ImportError, err:
102 msg = 'Failed to load plugin %s/%s: %s' \
103 % (os.path.basename(pdir), mod, err)
104 msger.warning(msg)
105
106 del(sys.path[0])
107
108 def get_plugins(self, ptype):
109 """ the return value is dict of name:class pairs """
110
111 if ptype not in PLUGIN_TYPES:
112 raise errors.CreatorError('%s is not valid plugin type' % ptype)
113
114 plugins_dir = self._build_plugin_dir_list(self.plugin_dir, ptype)
115
116 self.append_dirs(plugins_dir)
117
118 return pluginbase.get_plugins(ptype)
119
120 def get_source_plugins(self):
121 """
122 Return list of available source plugins.
123 """
124 plugins_dir = self._build_plugin_dir_list(self.plugin_dir, 'source')
125
126 self.append_dirs(plugins_dir)
127
128 plugins = []
129
130 for _source_name, klass in self.get_plugins('source').iteritems():
131 plugins.append(_source_name)
132
133 return plugins
134
135
136 def get_source_plugin_methods(self, source_name, methods):
137 """
138 The methods param is a dict with the method names to find. On
139 return, the dict values will be filled in with pointers to the
140 corresponding methods. If one or more methods are not found,
141 None is returned.
142 """
143 return_methods = None
144 for _source_name, klass in self.get_plugins('source').iteritems():
145 if _source_name == source_name:
146 for _method_name in methods.keys():
147 if not hasattr(klass, _method_name):
148 msger.warning("Unimplemented %s source interface for: %s"\
149 % (_method_name, _source_name))
150 return None
151 func = getattr(klass, _method_name)
152 methods[_method_name] = func
153 return_methods = methods
154 return return_methods
155
156pluginmgr = PluginMgr()