summaryrefslogtreecommitdiffstats
path: root/scripts/lib/mic/imager/direct.py
diff options
context:
space:
mode:
authorTom Zanussi <tom.zanussi@linux.intel.com>2014-08-08 15:53:52 -0500
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-08-11 10:53:12 +0100
commitd8f9d05baee3abd4feb0a5b2f2afe467e919c6b9 (patch)
treeedc6ba90a220ad5bbba41998c3c5c82e1e97760d /scripts/lib/mic/imager/direct.py
parenta43c1f94205d95c6eb77af2f0a494b4143f9eaf8 (diff)
downloadpoky-d8f9d05baee3abd4feb0a5b2f2afe467e919c6b9.tar.gz
wic: Rename /mic to /wic
As well as any other stray instances of mic in the codebase that can be removed. We don't really need to carry around legacy naming, and the history is in git. (From OE-Core rev: 598b120406dc1d2b7e377bd1ab6f0acbef034b22) Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/lib/mic/imager/direct.py')
-rw-r--r--scripts/lib/mic/imager/direct.py363
1 files changed, 0 insertions, 363 deletions
diff --git a/scripts/lib/mic/imager/direct.py b/scripts/lib/mic/imager/direct.py
deleted file mode 100644
index 2f2bd4e072..0000000000
--- a/scripts/lib/mic/imager/direct.py
+++ /dev/null
@@ -1,363 +0,0 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2013, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This implements the 'direct' image creator class for 'wic', based
22# loosely on the raw image creator from 'mic'
23#
24# AUTHORS
25# Tom Zanussi <tom.zanussi (at] linux.intel.com>
26#
27
28import os
29import stat
30import shutil
31
32from mic import kickstart, msger
33from mic.utils import fs_related, runner, misc
34from mic.utils.partitionedfs import Image
35from mic.utils.errors import CreatorError, ImageError
36from mic.imager.baseimager import BaseImageCreator
37from mic.utils.oe.misc import *
38from mic.plugin import pluginmgr
39
40disk_methods = {
41 "do_install_disk":None,
42}
43
44class DirectImageCreator(BaseImageCreator):
45 """
46 Installs a system into a file containing a partitioned disk image.
47
48 DirectImageCreator is an advanced ImageCreator subclass; an image
49 file is formatted with a partition table, each partition created
50 from a rootfs or other OpenEmbedded build artifact and dd'ed into
51 the virtual disk. The disk image can subsequently be dd'ed onto
52 media and used on actual hardware.
53 """
54
55 def __init__(self, oe_builddir, image_output_dir, rootfs_dir, bootimg_dir,
56 kernel_dir, native_sysroot, hdddir, staging_data_dir,
57 creatoropts=None):
58 """
59 Initialize a DirectImageCreator instance.
60
61 This method takes the same arguments as ImageCreator.__init__()
62 """
63 BaseImageCreator.__init__(self, creatoropts)
64
65 self.__image = None
66 self.__disks = {}
67 self.__disk_format = "direct"
68 self._disk_names = []
69 self._ptable_format = self.ks.handler.bootloader.ptable
70
71 self.oe_builddir = oe_builddir
72 if image_output_dir:
73 self.tmpdir = image_output_dir
74 self.rootfs_dir = rootfs_dir
75 self.bootimg_dir = bootimg_dir
76 self.kernel_dir = kernel_dir
77 self.native_sysroot = native_sysroot
78 self.hdddir = hdddir
79 self.staging_data_dir = staging_data_dir
80
81 def __write_fstab(self, image_rootfs):
82 """overriden to generate fstab (temporarily) in rootfs. This is called
83 from _create, make sure it doesn't get called from
84 BaseImage.create()
85 """
86 if image_rootfs is None:
87 return None
88
89 fstab = image_rootfs + "/etc/fstab"
90 if not os.path.isfile(fstab):
91 return None
92
93 parts = self._get_parts()
94
95 self._save_fstab(fstab)
96 fstab_lines = self._get_fstab(fstab, parts)
97 self._update_fstab(fstab_lines, parts)
98 self._write_fstab(fstab, fstab_lines)
99
100 return fstab
101
102 def _update_fstab(self, fstab_lines, parts):
103 """Assume partition order same as in wks"""
104 for num, p in enumerate(parts, 1):
105 if not p.mountpoint or p.mountpoint == "/" or p.mountpoint == "/boot":
106 continue
107 if self._ptable_format == 'msdos' and num > 3:
108 device_name = "/dev/" + p.disk + str(num + 1)
109 else:
110 device_name = "/dev/" + p.disk + str(num)
111
112 opts = "defaults"
113 if p.fsopts:
114 opts = p.fsopts
115
116 fstab_entry = device_name + "\t" + \
117 p.mountpoint + "\t" + \
118 p.fstype + "\t" + \
119 opts + "\t0\t0\n"
120 fstab_lines.append(fstab_entry)
121
122 def _write_fstab(self, fstab, fstab_lines):
123 fstab = open(fstab, "w")
124 for line in fstab_lines:
125 fstab.write(line)
126 fstab.close()
127
128 def _save_fstab(self, fstab):
129 """Save the current fstab in rootfs"""
130 shutil.copyfile(fstab, fstab + ".orig")
131
132 def _restore_fstab(self, fstab):
133 """Restore the saved fstab in rootfs"""
134 if fstab is None:
135 return
136 shutil.move(fstab + ".orig", fstab)
137
138 def _get_fstab(self, fstab, parts):
139 """Return the desired contents of /etc/fstab."""
140 f = open(fstab, "r")
141 fstab_contents = f.readlines()
142 f.close()
143
144 return fstab_contents
145
146 def set_bootimg_dir(self, bootimg_dir):
147 """
148 Accessor for bootimg_dir, the actual location used for the source
149 of the bootimg. Should be set by source plugins (only if they
150 change the default bootimg source) so the correct info gets
151 displayed for print_outimage_info().
152 """
153 self.bootimg_dir = bootimg_dir
154
155 def _get_parts(self):
156 if not self.ks:
157 raise CreatorError("Failed to get partition info, "
158 "please check your kickstart setting.")
159
160 # Set a default partition if no partition is given out
161 if not self.ks.handler.partition.partitions:
162 partstr = "part / --size 1900 --ondisk sda --fstype=ext3"
163 args = partstr.split()
164 pd = self.ks.handler.partition.parse(args[1:])
165 if pd not in self.ks.handler.partition.partitions:
166 self.ks.handler.partition.partitions.append(pd)
167
168 # partitions list from kickstart file
169 return kickstart.get_partitions(self.ks)
170
171 def get_disk_names(self):
172 """ Returns a list of physical target disk names (e.g., 'sdb') which
173 will be created. """
174
175 if self._disk_names:
176 return self._disk_names
177
178 #get partition info from ks handler
179 parts = self._get_parts()
180
181 for i in range(len(parts)):
182 if parts[i].disk:
183 disk_name = parts[i].disk
184 else:
185 raise CreatorError("Failed to create disks, no --ondisk "
186 "specified in partition line of ks file")
187
188 if parts[i].mountpoint and not parts[i].fstype:
189 raise CreatorError("Failed to create disks, no --fstype "
190 "specified for partition with mountpoint "
191 "'%s' in the ks file")
192
193 self._disk_names.append(disk_name)
194
195 return self._disk_names
196
197 def _full_name(self, name, extention):
198 """ Construct full file name for a file we generate. """
199 return "%s-%s.%s" % (self.name, name, extention)
200
201 def _full_path(self, path, name, extention):
202 """ Construct full file path to a file we generate. """
203 return os.path.join(path, self._full_name(name, extention))
204
205 def get_default_source_plugin(self):
206 """
207 The default source plugin i.e. the plugin that's consulted for
208 overall image generation tasks outside of any particular
209 partition. For convenience, we just hang it off the
210 bootloader handler since it's the one non-partition object in
211 any setup. By default the default plugin is set to the same
212 plugin as the /boot partition; since we hang it off the
213 bootloader object, the default can be explicitly set using the
214 --source bootloader param.
215 """
216 return self.ks.handler.bootloader.source
217
218 #
219 # Actual implemention
220 #
221 def _create(self):
222 """
223 For 'wic', we already have our build artifacts - we just create
224 filesystems from the artifacts directly and combine them into
225 a partitioned image.
226 """
227 parts = self._get_parts()
228
229 self.__image = Image()
230
231 for p in parts:
232 # as a convenience, set source to the boot partition source
233 # instead of forcing it to be set via bootloader --source
234 if not self.ks.handler.bootloader.source and p.mountpoint == "/boot":
235 self.ks.handler.bootloader.source = p.source
236
237 for p in parts:
238 # need to create the filesystems in order to get their
239 # sizes before we can add them and do the layout.
240 # Image.create() actually calls __format_disks() to create
241 # the disk images and carve out the partitions, then
242 # self.assemble() calls Image.assemble() which calls
243 # __write_partitition() for each partition to dd the fs
244 # into the partitions.
245 fstab = self.__write_fstab(self.rootfs_dir.get("ROOTFS_DIR"))
246
247 p.prepare(self, self.workdir, self.oe_builddir, self.rootfs_dir,
248 self.bootimg_dir, self.kernel_dir, self.native_sysroot)
249
250 self._restore_fstab(fstab)
251
252 self.__image.add_partition(int(p.size),
253 p.disk,
254 p.mountpoint,
255 p.source_file,
256 p.fstype,
257 p.label,
258 fsopts = p.fsopts,
259 boot = p.active,
260 align = p.align,
261 part_type = p.part_type)
262
263 self.__image.layout_partitions(self._ptable_format)
264
265 self.__imgdir = self.workdir
266 for disk_name, disk in self.__image.disks.items():
267 full_path = self._full_path(self.__imgdir, disk_name, "direct")
268 msger.debug("Adding disk %s as %s with size %s bytes" \
269 % (disk_name, full_path, disk['min_size']))
270 disk_obj = fs_related.DiskImage(full_path, disk['min_size'])
271 self.__disks[disk_name] = disk_obj
272 self.__image.add_disk(disk_name, disk_obj)
273
274 self.__image.create()
275
276 def assemble(self):
277 """
278 Assemble partitions into disk image(s)
279 """
280 for disk_name, disk in self.__image.disks.items():
281 full_path = self._full_path(self.__imgdir, disk_name, "direct")
282 msger.debug("Assembling disk %s as %s with size %s bytes" \
283 % (disk_name, full_path, disk['min_size']))
284 self.__image.assemble(full_path)
285
286 def finalize(self):
287 """
288 Finalize the disk image.
289
290 For example, prepare the image to be bootable by e.g.
291 creating and installing a bootloader configuration.
292
293 """
294 source_plugin = self.get_default_source_plugin()
295 if source_plugin:
296 self._source_methods = pluginmgr.get_source_plugin_methods(source_plugin, disk_methods)
297 for disk_name, disk in self.__image.disks.items():
298 self._source_methods["do_install_disk"](disk, disk_name, self,
299 self.workdir,
300 self.oe_builddir,
301 self.bootimg_dir,
302 self.kernel_dir,
303 self.native_sysroot)
304
305 def print_outimage_info(self):
306 """
307 Print the image(s) and artifacts used, for the user.
308 """
309 msg = "The new image(s) can be found here:\n"
310
311 parts = self._get_parts()
312
313 for disk_name, disk in self.__image.disks.items():
314 full_path = self._full_path(self.__imgdir, disk_name, "direct")
315 msg += ' %s\n\n' % full_path
316
317 msg += 'The following build artifacts were used to create the image(s):\n'
318 for p in parts:
319 if p.get_rootfs() is None:
320 continue
321 if p.mountpoint == '/':
322 str = ':'
323 else:
324 str = '["%s"]:' % p.label
325 msg += ' ROOTFS_DIR%s%s\n' % (str.ljust(20), p.get_rootfs())
326
327 msg += ' BOOTIMG_DIR: %s\n' % self.bootimg_dir
328 msg += ' KERNEL_DIR: %s\n' % self.kernel_dir
329 msg += ' NATIVE_SYSROOT: %s\n' % self.native_sysroot
330
331 msger.info(msg)
332
333 def _get_boot_config(self):
334 """
335 Return the rootdev/root_part_uuid (if specified by
336 --part-type)
337
338 Assume partition order same as in wks
339 """
340 rootdev = None
341 root_part_uuid = None
342 parts = self._get_parts()
343 for num, p in enumerate(parts, 1):
344 if p.mountpoint == "/":
345 part = ''
346 if p.disk.startswith('mmcblk'):
347 part = 'p'
348
349 if self._ptable_format == 'msdos' and num > 3:
350 rootdev = "/dev/%s%s%-d" % (p.disk, part, num + 1)
351 else:
352 rootdev = "/dev/%s%s%-d" % (p.disk, part, num)
353 root_part_uuid = p.part_type
354
355 return (rootdev, root_part_uuid)
356
357 def _cleanup(self):
358 if not self.__image is None:
359 try:
360 self.__image.cleanup()
361 except ImageError, err:
362 msger.warning("%s" % err)
363