summaryrefslogtreecommitdiffstats
path: root/scripts/lib/mic/imager/liveusb.py
diff options
context:
space:
mode:
authorTom Zanussi <tom.zanussi@linux.intel.com>2013-08-24 15:31:34 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2013-10-01 22:56:03 +0100
commit9fc88f96d40b17c90bac53b90045a87b2d2cff84 (patch)
tree63010e5aabf895697655baf89bd668d6752b3f97 /scripts/lib/mic/imager/liveusb.py
parent53a1d9a788fd9f970af980da2ab975cca60685c4 (diff)
downloadpoky-9fc88f96d40b17c90bac53b90045a87b2d2cff84.tar.gz
wic: Add mic w/pykickstart
This is the starting point for the implemention described in [YOCTO 3847] which came to the conclusion that it would make sense to use kickstart syntax to implement image creation in OpenEmbedded. I subsequently realized that there was an existing tool that already implemented image creation using kickstart syntax, the Tizen/Meego mic tool. As such, it made sense to use that as a starting point - this commit essentially just copies the relevant Python code from the MIC tool to the scripts/lib dir, where it can be accessed by the previously created wic tool. Most of this will be removed or renamed by later commits, since we're initially focusing on partitioning only. Care should be taken so that we can easily add back any additional functionality should we decide later to expand the tool, though (we may also want to contribute our local changes to the mic tool to the Tizen project if it makes sense, and therefore should avoid gratuitous changes to the original code if possible). Added the /mic subdir from Tizen mic repo as a starting point: git clone git://review.tizen.org/tools/mic.git For reference, the top commit: commit 20164175ddc234a17b8a12c33d04b012347b1530 Author: Gui Chen <gui.chen@intel.com> Date: Sun Jun 30 22:32:16 2013 -0400 bump up to 0.19.2 Also added the /plugins subdir, moved to under the /mic subdir (to match the default plugin_dir location in mic.conf.in, which was renamed to yocto-image.conf (moved and renamed by later patches) and put into /scripts. (From OE-Core rev: 31f0360f1fd4ebc9dfcaed42d1c50d2448b4632e) Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com> Signed-off-by: Saul Wold <sgw@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/lib/mic/imager/liveusb.py')
-rw-r--r--scripts/lib/mic/imager/liveusb.py308
1 files changed, 308 insertions, 0 deletions
diff --git a/scripts/lib/mic/imager/liveusb.py b/scripts/lib/mic/imager/liveusb.py
new file mode 100644
index 0000000000..a909928a4c
--- /dev/null
+++ b/scripts/lib/mic/imager/liveusb.py
@@ -0,0 +1,308 @@
1#!/usr/bin/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
19import shutil
20import re
21
22from mic import msger
23from mic.utils import misc, fs_related, runner
24from mic.utils.errors import CreatorError, MountError
25from mic.utils.partitionedfs import PartitionedMount
26from mic.imager.livecd import LiveCDImageCreator
27
28
29class LiveUSBImageCreator(LiveCDImageCreator):
30 def __init__(self, *args):
31 LiveCDImageCreator.__init__(self, *args)
32
33 self._dep_checks.extend(["kpartx", "parted"])
34
35 # remove dependency of genisoimage in parent class
36 if "genisoimage" in self._dep_checks:
37 self._dep_checks.remove("genisoimage")
38
39 def _create_usbimg(self, isodir):
40 overlaysizemb = 64 #default
41 #skipcompress = self.skip_compression?
42 fstype = "vfat"
43 homesizemb=0
44 swapsizemb=0
45 homefile="home.img"
46 plussize=128
47 kernelargs=None
48
49 if fstype == 'vfat':
50 if overlaysizemb > 2047:
51 raise CreatorError("Can't have an overlay of 2048MB or "
52 "greater on VFAT")
53
54 if homesizemb > 2047:
55 raise CreatorError("Can't have an home overlay of 2048MB or "
56 "greater on VFAT")
57
58 if swapsizemb > 2047:
59 raise CreatorError("Can't have an swap overlay of 2048MB or "
60 "greater on VFAT")
61
62 livesize = misc.get_file_size(isodir + "/LiveOS")
63
64 usbimgsize = (overlaysizemb + \
65 homesizemb + \
66 swapsizemb + \
67 livesize + \
68 plussize) * 1024L * 1024L
69
70 disk = fs_related.SparseLoopbackDisk("%s/%s.usbimg" \
71 % (self._outdir, self.name),
72 usbimgsize)
73 usbmnt = self._mkdtemp("usb-mnt")
74 usbloop = PartitionedMount(usbmnt)
75 usbloop.add_disk('/dev/sdb', disk)
76
77 usbloop.add_partition(usbimgsize/1024/1024,
78 "/dev/sdb",
79 "/",
80 fstype,
81 boot=True)
82
83 usbloop.mount()
84
85 try:
86 fs_related.makedirs(usbmnt + "/LiveOS")
87
88 if os.path.exists(isodir + "/LiveOS/squashfs.img"):
89 shutil.copyfile(isodir + "/LiveOS/squashfs.img",
90 usbmnt + "/LiveOS/squashfs.img")
91 else:
92 fs_related.mksquashfs(os.path.dirname(self._image),
93 usbmnt + "/LiveOS/squashfs.img")
94
95 if os.path.exists(isodir + "/LiveOS/osmin.img"):
96 shutil.copyfile(isodir + "/LiveOS/osmin.img",
97 usbmnt + "/LiveOS/osmin.img")
98
99 if fstype == "vfat" or fstype == "msdos":
100 uuid = usbloop.partitions[0]['mount'].uuid
101 label = usbloop.partitions[0]['mount'].fslabel
102 usblabel = "UUID=%s-%s" % (uuid[0:4], uuid[4:8])
103 overlaysuffix = "-%s-%s-%s" % (label, uuid[0:4], uuid[4:8])
104 else:
105 diskmount = usbloop.partitions[0]['mount']
106 usblabel = "UUID=%s" % diskmount.uuid
107 overlaysuffix = "-%s-%s" % (diskmount.fslabel, diskmount.uuid)
108
109 args = ['cp', "-Rf", isodir + "/isolinux", usbmnt + "/syslinux"]
110 rc = runner.show(args)
111 if rc:
112 raise CreatorError("Can't copy isolinux directory %s" \
113 % (isodir + "/isolinux/*"))
114
115 if os.path.isfile("/usr/share/syslinux/isolinux.bin"):
116 syslinux_path = "/usr/share/syslinux"
117 elif os.path.isfile("/usr/lib/syslinux/isolinux.bin"):
118 syslinux_path = "/usr/lib/syslinux"
119 else:
120 raise CreatorError("syslinux not installed : "
121 "cannot find syslinux installation path")
122
123 for f in ("isolinux.bin", "vesamenu.c32"):
124 path = os.path.join(syslinux_path, f)
125 if os.path.isfile(path):
126 args = ['cp', path, usbmnt + "/syslinux/"]
127 rc = runner.show(args)
128 if rc:
129 raise CreatorError("Can't copy syslinux file " + path)
130 else:
131 raise CreatorError("syslinux not installed: "
132 "syslinux file %s not found" % path)
133
134 fd = open(isodir + "/isolinux/isolinux.cfg", "r")
135 text = fd.read()
136 fd.close()
137 pattern = re.compile('CDLABEL=[^ ]*')
138 text = pattern.sub(usblabel, text)
139 pattern = re.compile('rootfstype=[^ ]*')
140 text = pattern.sub("rootfstype=" + fstype, text)
141 if kernelargs:
142 text = text.replace("rd.live.image", "rd.live.image " + kernelargs)
143
144 if overlaysizemb > 0:
145 msger.info("Initializing persistent overlay file")
146 overfile = "overlay" + overlaysuffix
147 if fstype == "vfat":
148 args = ['dd',
149 "if=/dev/zero",
150 "of=" + usbmnt + "/LiveOS/" + overfile,
151 "count=%d" % overlaysizemb,
152 "bs=1M"]
153 else:
154 args = ['dd',
155 "if=/dev/null",
156 "of=" + usbmnt + "/LiveOS/" + overfile,
157 "count=1",
158 "bs=1M",
159 "seek=%d" % overlaysizemb]
160 rc = runner.show(args)
161 if rc:
162 raise CreatorError("Can't create overlay file")
163 text = text.replace("rd.live.image", "rd.live.image rd.live.overlay=" + usblabel)
164 text = text.replace(" ro ", " rw ")
165
166 if swapsizemb > 0:
167 msger.info("Initializing swap file")
168 swapfile = usbmnt + "/LiveOS/" + "swap.img"
169 args = ['dd',
170 "if=/dev/zero",
171 "of=" + swapfile,
172 "count=%d" % swapsizemb,
173 "bs=1M"]
174 rc = runner.show(args)
175 if rc:
176 raise CreatorError("Can't create swap file")
177 args = ["mkswap", "-f", swapfile]
178 rc = runner.show(args)
179 if rc:
180 raise CreatorError("Can't mkswap on swap file")
181
182 if homesizemb > 0:
183 msger.info("Initializing persistent /home")
184 homefile = usbmnt + "/LiveOS/" + homefile
185 if fstype == "vfat":
186 args = ['dd',
187 "if=/dev/zero",
188 "of=" + homefile,
189 "count=%d" % homesizemb,
190 "bs=1M"]
191 else:
192 args = ['dd',
193 "if=/dev/null",
194 "of=" + homefile,
195 "count=1",
196 "bs=1M",
197 "seek=%d" % homesizemb]
198 rc = runner.show(args)
199 if rc:
200 raise CreatorError("Can't create home file")
201
202 mkfscmd = fs_related.find_binary_path("/sbin/mkfs." + fstype)
203 if fstype == "ext2" or fstype == "ext3":
204 args = [mkfscmd, "-F", "-j", homefile]
205 else:
206 args = [mkfscmd, homefile]
207 rc = runner.show(args)
208 if rc:
209 raise CreatorError("Can't mke2fs home file")
210 if fstype == "ext2" or fstype == "ext3":
211 tune2fs = fs_related.find_binary_path("tune2fs")
212 args = [tune2fs,
213 "-c0",
214 "-i0",
215 "-ouser_xattr,acl",
216 homefile]
217 rc = runner.show(args)
218 if rc:
219 raise CreatorError("Can't tune2fs home file")
220
221 if fstype == "vfat" or fstype == "msdos":
222 syslinuxcmd = fs_related.find_binary_path("syslinux")
223 syslinuxcfg = usbmnt + "/syslinux/syslinux.cfg"
224 args = [syslinuxcmd,
225 "-d",
226 "syslinux",
227 usbloop.partitions[0]["device"]]
228
229 elif fstype == "ext2" or fstype == "ext3":
230 extlinuxcmd = fs_related.find_binary_path("extlinux")
231 syslinuxcfg = usbmnt + "/syslinux/extlinux.conf"
232 args = [extlinuxcmd,
233 "-i",
234 usbmnt + "/syslinux"]
235
236 else:
237 raise CreatorError("Invalid file system type: %s" % (fstype))
238
239 os.unlink(usbmnt + "/syslinux/isolinux.cfg")
240 fd = open(syslinuxcfg, "w")
241 fd.write(text)
242 fd.close()
243 rc = runner.show(args)
244 if rc:
245 raise CreatorError("Can't install boot loader.")
246
247 finally:
248 usbloop.unmount()
249 usbloop.cleanup()
250
251 # Need to do this after image is unmounted and device mapper is closed
252 msger.info("set MBR")
253 mbrfile = "/usr/lib/syslinux/mbr.bin"
254 if not os.path.exists(mbrfile):
255 mbrfile = "/usr/share/syslinux/mbr.bin"
256 if not os.path.exists(mbrfile):
257 raise CreatorError("mbr.bin file didn't exist.")
258 mbrsize = os.path.getsize(mbrfile)
259 outimg = "%s/%s.usbimg" % (self._outdir, self.name)
260
261 args = ['dd',
262 "if=" + mbrfile,
263 "of=" + outimg,
264 "seek=0",
265 "conv=notrunc",
266 "bs=1",
267 "count=%d" % (mbrsize)]
268 rc = runner.show(args)
269 if rc:
270 raise CreatorError("Can't set MBR.")
271
272 def _stage_final_image(self):
273 try:
274 isodir = self._get_isodir()
275 fs_related.makedirs(isodir + "/LiveOS")
276
277 minimal_size = self._resparse()
278
279 if not self.skip_minimize:
280 fs_related.create_image_minimizer(isodir + "/LiveOS/osmin.img",
281 self._image,
282 minimal_size)
283
284 if self.skip_compression:
285 shutil.move(self._image,
286 isodir + "/LiveOS/ext3fs.img")
287 else:
288 fs_related.makedirs(os.path.join(
289 os.path.dirname(self._image),
290 "LiveOS"))
291 shutil.move(self._image,
292 os.path.join(os.path.dirname(self._image),
293 "LiveOS", "ext3fs.img"))
294 fs_related.mksquashfs(os.path.dirname(self._image),
295 isodir + "/LiveOS/squashfs.img")
296
297 self._create_usbimg(isodir)
298
299 if self.pack_to:
300 usbimg = os.path.join(self._outdir, self.name + ".usbimg")
301 packimg = os.path.join(self._outdir, self.pack_to)
302 misc.packing(packimg, usbimg)
303 os.unlink(usbimg)
304
305 finally:
306 shutil.rmtree(isodir, ignore_errors = True)
307 self._set_isodir(None)
308