summaryrefslogtreecommitdiff
path: root/scripts/lib/wic/pluginbase.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/wic/pluginbase.py')
-rw-r--r--scripts/lib/wic/pluginbase.py92
1 files changed, 62 insertions, 30 deletions
diff --git a/scripts/lib/wic/pluginbase.py b/scripts/lib/wic/pluginbase.py
index ee8fe95c6f..fb3d179c2d 100644
--- a/scripts/lib/wic/pluginbase.py
+++ b/scripts/lib/wic/pluginbase.py
@@ -15,34 +15,74 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59
# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-from wic import msger
+__all__ = ['ImagerPlugin', 'SourcePlugin']
-class _Plugin(object):
- class __metaclass__(type):
- def __init__(cls, name, bases, attrs):
- if not hasattr(cls, 'plugins'):
- cls.plugins = {}
+import os
+import logging
- elif 'wic_plugin_type' in attrs:
- if attrs['wic_plugin_type'] not in cls.plugins:
- cls.plugins[attrs['wic_plugin_type']] = {}
+from collections import defaultdict
+from importlib.machinery import SourceFileLoader
- elif hasattr(cls, 'wic_plugin_type') and 'name' in attrs:
- cls.plugins[cls.wic_plugin_type][attrs['name']] = cls
+from wic import WicError
+from wic.utils.misc import get_bitbake_var
- def show_plugins(cls):
- for cls in cls.plugins[cls.wic_plugin_type]:
- print cls
+PLUGIN_TYPES = ["imager", "source"]
- def get_plugins(cls):
- return cls.plugins
+SCRIPTS_PLUGIN_DIR = "scripts/lib/wic/plugins"
+logger = logging.getLogger('wic')
-class ImagerPlugin(_Plugin):
+PLUGINS = defaultdict(dict)
+
+class PluginMgr:
+ _plugin_dirs = []
+
+ @classmethod
+ def get_plugins(cls, ptype):
+ """Get dictionary of <plugin_name>:<class> pairs."""
+ if ptype not in PLUGIN_TYPES:
+ raise WicError('%s is not valid plugin type' % ptype)
+
+ # collect plugin directories
+ if not cls._plugin_dirs:
+ cls._plugin_dirs = [os.path.join(os.path.dirname(__file__), 'plugins')]
+ layers = get_bitbake_var("BBLAYERS") or ''
+ for layer_path in layers.split():
+ path = os.path.join(layer_path, SCRIPTS_PLUGIN_DIR)
+ path = os.path.abspath(os.path.expanduser(path))
+ if path not in cls._plugin_dirs and os.path.isdir(path):
+ cls._plugin_dirs.insert(0, path)
+
+ if ptype not in PLUGINS:
+ # load all ptype plugins
+ for pdir in cls._plugin_dirs:
+ ppath = os.path.join(pdir, ptype)
+ if os.path.isdir(ppath):
+ for fname in os.listdir(ppath):
+ if fname.endswith('.py'):
+ mname = fname[:-3]
+ mpath = os.path.join(ppath, fname)
+ logger.debug("loading plugin module %s", mpath)
+ SourceFileLoader(mname, mpath).load_module()
+
+ return PLUGINS.get(ptype)
+
+class PluginMeta(type):
+ def __new__(cls, name, bases, attrs):
+ class_type = type.__new__(cls, name, bases, attrs)
+ if 'name' in attrs:
+ PLUGINS[class_type.wic_plugin_type][attrs['name']] = class_type
+
+ return class_type
+
+class ImagerPlugin(metaclass=PluginMeta):
wic_plugin_type = "imager"
+ def do_create(self):
+ raise WicError("Method %s.do_create is not implemented" %
+ self.__class__.__name__)
-class SourcePlugin(_Plugin):
+class SourcePlugin(metaclass=PluginMeta):
wic_plugin_type = "source"
"""
The methods that can be implemented by --source plugins.
@@ -58,7 +98,7 @@ class SourcePlugin(_Plugin):
disk image. This provides a hook to allow finalization of a
disk image e.g. to write an MBR to it.
"""
- msger.debug("SourcePlugin: do_install_disk: disk: %s" % disk_name)
+ logger.debug("SourcePlugin: do_install_disk: disk: %s", disk_name)
@classmethod
def do_stage_partition(cls, part, source_params, creator, cr_workdir,
@@ -75,7 +115,7 @@ class SourcePlugin(_Plugin):
Not that get_bitbake_var() allows you to acces non-standard
variables that you might want to use for this.
"""
- msger.debug("SourcePlugin: do_stage_partition: part: %s" % part)
+ logger.debug("SourcePlugin: do_stage_partition: part: %s", part)
@classmethod
def do_configure_partition(cls, part, source_params, creator, cr_workdir,
@@ -86,7 +126,7 @@ class SourcePlugin(_Plugin):
custom configuration files for a partition, for example
syslinux or grub config files.
"""
- msger.debug("SourcePlugin: do_configure_partition: part: %s" % part)
+ logger.debug("SourcePlugin: do_configure_partition: part: %s", part)
@classmethod
def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
@@ -96,13 +136,5 @@ class SourcePlugin(_Plugin):
Called to do the actual content population for a partition i.e. it
'prepares' the partition to be incorporated into the image.
"""
- msger.debug("SourcePlugin: do_prepare_partition: part: %s" % part)
-
-def get_plugins(typen):
- plugins = ImagerPlugin.get_plugins()
- if typen in plugins:
- return plugins[typen]
- else:
- return None
+ logger.debug("SourcePlugin: do_prepare_partition: part: %s", part)
-__all__ = ['ImagerPlugin', 'SourcePlugin', 'get_plugins']