summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorTom Zanussi <tom.zanussi@linux.intel.com>2014-02-03 19:16:57 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-02-04 12:57:35 +0000
commit73ce09065fb8c095be9c8e94e2d9d873ff06c70f (patch)
tree7ab046017eefe1e94873f2db08e28745b0235bc1 /scripts
parent363488fc9a045ef7415f0d07777c934a2c452714 (diff)
downloadpoky-73ce09065fb8c095be9c8e94e2d9d873ff06c70f.tar.gz
wic: Add SourcePlugin class
Define the SourcePlugin class, which is the class that should be subclassed to create a 'source' plugin. 'Source' plugins provide a mechanism to customize various aspects of the image generation process in wic, mainly the contents of partitions. The initial version of wic defined a --source param for partitions, which was in the first revision hard-coded to two possible values: rootfs and bootimg. This patch essentially removes the hard-coded --bootimg param and replaces it with a plugin system that maps the value specified as --source to a particular 'source' plugin instead. A 'source' plugin is created as a subclass of SourcePlugin and the plugin file containing it is added to scriptsl/lib/mic/plugins/source/ to make the plugin implementation available to the wic implementation. When the wic implementation needs to invoke a partition-specific implementation, it looks for the plugin that has the same name as the --source param given to that partition. For example, if the partition is set up like this: part /boot --source bootimg-pcbios ... then the methods defined as class members of the plugin having the matching .name class member would be used. To be more concrete, here's the plugin definition that would match a '--source bootimg-pcbios' usage, along with an example method that would be called by the wic implementation when it needed to invoke an implementation-specific partition-preparation function: class BootimgPcbiosPlugin(SourcePlugin): name = 'bootimg-pcbios' @classmethod def do_prepare_partition(self, part, ...) If the subclass itself doesn't implement a function, a 'default' version in a superclass will be located and used, which is why all plugins must be derived from SourcePlugin. This scheme is extensible - adding more hooks is a simple matter of adding more plugin methods to SourcePlugin and derived classes. The code that then needs to call the plugin methods the uses plugin.get_source_plugin_methods() to find the method(s) needed by the call; this is done by filling up a dict with keys containing the methon names of interest - on success, these will be filled in with the actual methods. fPlease see the implementation for examples and details. Note that a source plugin need not restrict itself to methods that apply directly to partitions - methods can also be defined for higher level processing such as at the 'disk' level. The get_default_source_plugin() of DirectImageCreator allows the default source plugin to be retrieved; by default this is set to be the same plugin used for the /boot partition, but that can be overridden by specifying a different --source and therefore different plugin on the 'bootloader' line. This isn't ideal, but it avoids forcing a new high-level object to be defined for that purpose. Note that the '--source rootfs' param remains as its current hard-coded value, which is just the rootfs to be used to populate the partition - by default, that's just the value of the bitbake ROOTFS_DIR variable (or whatever was passed in using the -r param). Note that this also could also be overridden by creating a source plugin using a different name; at this point, unlike with bootimg, there's been no need to do so. (From OE-Core rev: 663833d8ecccb36ab42150bc5c9c00be79fa5b93) Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/lib/mic/plugin.py23
-rw-r--r--scripts/lib/mic/pluginbase.py55
2 files changed, 75 insertions, 3 deletions
diff --git a/scripts/lib/mic/plugin.py b/scripts/lib/mic/plugin.py
index 7c296e9765..df03c15081 100644
--- a/scripts/lib/mic/plugin.py
+++ b/scripts/lib/mic/plugin.py
@@ -19,13 +19,12 @@ import os, sys
19 19
20from mic import msger 20from mic import msger
21from mic import pluginbase 21from mic import pluginbase
22from mic.conf import configmgr
23from mic.utils import errors 22from mic.utils import errors
24 23
25 24
26__ALL__ = ['PluginMgr', 'pluginmgr'] 25__ALL__ = ['PluginMgr', 'pluginmgr']
27 26
28PLUGIN_TYPES = ["imager", "backend"] # TODO "hook" 27PLUGIN_TYPES = ["imager", "source"] # TODO "hook"
29 28
30 29
31class PluginMgr(object): 30class PluginMgr(object):
@@ -99,4 +98,24 @@ class PluginMgr(object):
99 98
100 return pluginbase.get_plugins(ptype) 99 return pluginbase.get_plugins(ptype)
101 100
101 def get_source_plugin_methods(self, source_name, methods):
102 """
103 The methods param is a dict with the method names to find. On
104 return, the dict values will be filled in with pointers to the
105 corresponding methods. If one or more methods are not found,
106 None is returned.
107 """
108 return_methods = None
109 for _source_name, klass in self.get_plugins('source').iteritems():
110 if _source_name == source_name:
111 for _method_name in methods.keys():
112 if not hasattr(klass, _method_name):
113 msger.warning("Unimplemented %s source interface for: %s"\
114 % (_method_name, _source_name))
115 return None
116 func = getattr(klass, _method_name)
117 methods[_method_name] = func
118 return_methods = methods
119 return return_methods
120
102pluginmgr = PluginMgr() 121pluginmgr = PluginMgr()
diff --git a/scripts/lib/mic/pluginbase.py b/scripts/lib/mic/pluginbase.py
index 2f9d7209e9..e26b525dc3 100644
--- a/scripts/lib/mic/pluginbase.py
+++ b/scripts/lib/mic/pluginbase.py
@@ -80,6 +80,59 @@ class ImagerPlugin(_Plugin):
80 def do_chroot(self): 80 def do_chroot(self):
81 pass 81 pass
82 82
83class SourcePlugin(_Plugin):
84 mic_plugin_type = "source"
85 """
86 The methods that can be implemented by --source plugins.
87
88 Any methods not implemented in a subclass inherit these.
89 """
90
91 @classmethod
92 def do_install_disk(self, disk, disk_name, cr, workdir, oe_builddir,
93 bootimg_dir, kernel_dir, native_sysroot):
94 """
95 Called after all partitions have been prepared and assembled into a
96 disk image. This provides a hook to allow finalization of a
97 disk image e.g. to write an MBR to it.
98 """
99 msger.debug("SourcePlugin: do_install_disk: disk: %s" % disk_name)
100
101 @classmethod
102 def do_stage_partition(self, part, cr, workdir, oe_builddir, bootimg_dir,
103 kernel_dir, native_sysroot):
104 """
105 Special content staging hook called before do_prepare_partition(),
106 normally empty.
107
108 Typically, a partition will just use the passed-in parame e.g
109 straight bootimg_dir, etc, but in some cases, things need to
110 be more tailored e.g. to use a deploy dir + /boot, etc. This
111 hook allows those files to be staged in a customized fashion.
112 Not that get_bitbake_var() allows you to acces non-standard
113 variables that you might want to use for this.
114 """
115 msger.debug("SourcePlugin: do_stage_partition: part: %s" % part)
116
117 @classmethod
118 def do_configure_partition(self, part, cr, cr_workdir, oe_builddir,
119 bootimg_dir, kernel_dir, native_sysroot):
120 """
121 Called before do_prepare_partition(), typically used to create
122 custom configuration files for a partition, for example
123 syslinux or grub config files.
124 """
125 msger.debug("SourcePlugin: do_configure_partition: part: %s" % part)
126
127 @classmethod
128 def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir,
129 kernel_dir, native_sysroot):
130 """
131 Called to do the actual content population for a partition i.e. it
132 'prepares' the partition to be incorporated into the image.
133 """
134 msger.debug("SourcePlugin: do_prepare_partition: part: %s" % part)
135
83class BackendPlugin(_Plugin): 136class BackendPlugin(_Plugin):
84 mic_plugin_type="backend" 137 mic_plugin_type="backend"
85 138
@@ -93,4 +146,4 @@ def get_plugins(typen):
93 else: 146 else:
94 return None 147 return None
95 148
96__all__ = ['ImagerPlugin', 'BackendPlugin', 'get_plugins'] 149__all__ = ['ImagerPlugin', 'BackendPlugin', 'SourcePlugin', 'get_plugins']