3 # Copyright (c) 2011 Intel, Inc.
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
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
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.
22 from mic import configmgr, pluginmgr, chroot, msger
23 from mic.utils import misc, fs_related, errors
24 from mic.utils.partitionedfs import PartitionedMount
26 import mic.imager.liveusb as liveusb
28 from mic.pluginbase import ImagerPlugin
29 class LiveUSBPlugin(ImagerPlugin):
33 def do_create(self, subcmd, opts, *args):
34 """${cmd_name}: create liveusb image
41 raise errors.Usage("More arguments needed")
44 raise errors.Usage("Extra arguments given")
46 cfgmgr = configmgr.getConfigMgr()
47 creatoropts = cfgmgr.create
50 if not os.path.exists(ksconf):
51 raise errors.CreatorError("Can't find the file: %s" % ksconf)
53 if creatoropts['arch'] and creatoropts['arch'].startswith('arm'):
54 msger.warning('liveusb cannot support arm images, Quit')
58 if len(creatoropts['record_pkgs']) > 0:
59 recording_pkgs = creatoropts['record_pkgs']
60 if creatoropts['release'] is not None:
61 if 'name' not in recording_pkgs:
62 recording_pkgs.append('name')
63 ksconf = misc.save_ksconf_file(ksconf, creatoropts['release'])
64 name = os.path.splitext(os.path.basename(ksconf))[0]
65 creatoropts['outdir'] = "%s/%s/images/%s/" % (creatoropts['outdir'], creatoropts['release'], name)
66 cfgmgr._ksconf = ksconf
68 # try to find the pkgmgr
70 for (key, pcls) in pluginmgr.PluginMgr().get_plugins('backend').iteritems():
71 if key == creatoropts['pkgmgr']:
76 pkgmgrs = pluginmgr.PluginMgr().get_plugins('backend').keys()
77 raise errors.CreatorError("Can't find package manager: %s (availables: %s)" % (creatoropts['pkgmgr'], ', '.join(pkgmgrs)))
79 creator = liveusb.LiveUSBImageCreator(creatoropts, pkgmgr)
81 if len(recording_pkgs) > 0:
82 creator._recording_pkgs = recording_pkgs
84 if creatoropts['release'] is None:
85 imagefile = "%s.usbimg" % os.path.join(creator.destdir, creator.name)
86 if os.path.exists(imagefile):
87 if msger.ask('The target image: %s already exists, need to delete it?' % imagefile):
91 creator.check_depend_tools()
92 creator.mount(None, creatoropts["cachedir"])
94 creator.configure(creatoropts["repomd"])
96 creator.package(creatoropts["outdir"])
97 if creatoropts['release'] is not None:
98 creator.release_output(ksconf, creatoropts['outdir'], creatoropts['release'])
99 creator.print_outimage_info()
101 except errors.CreatorError:
106 msger.info("Finished.")
110 def do_chroot(cls, target):
111 os_image = cls.do_unpack(target)
112 os_image_dir = os.path.dirname(os_image)
114 #unpack image to target dir
115 imgsize = misc.get_file_size(os_image) * 1024L * 1024L
116 extmnt = misc.mkdtemp()
118 tlabel = "ext3 label"
120 MyDiskMount = fs_related.ExtDiskMount
121 extloop = MyDiskMount(fs_related.SparseLoopbackDisk(os_image, imgsize),
129 except errors.MountError:
131 shutil.rmtree(extmnt, ignore_errors = True)
135 chroot.chroot(extmnt, None, "/bin/env HOME=/root /bin/bash")
137 raise errors.CreatorError("Failed to chroot to %s." %target)
139 chroot.cleanup_after_chroot("img", extloop, os_image_dir, extmnt)
142 def do_pack(cls, base_on):
145 def __mkinitrd(instance):
146 kernelver = instance._get_kernel_versions().values()[0][0]
147 args = [ "/usr/libexec/mkliveinitrd", "/boot/initrd-%s.img" % kernelver, "%s" % kernelver ]
149 subprocess.call(args, preexec_fn = instance._chroot)
151 except OSError, (err, msg):
152 raise errors.CreatorError("Failed to execute /usr/libexec/mkliveinitrd: %s" % msg)
154 def __run_post_cleanups(instance):
155 kernelver = instance._get_kernel_versions().values()[0][0]
156 args = ["rm", "-f", "/boot/initrd-%s.img" % kernelver]
159 subprocess.call(args, preexec_fn = instance._chroot)
160 except OSError, (err, msg):
161 raise errors.CreatorError("Failed to run post cleanups: %s" % msg)
163 convertor = liveusb.LiveUSBImageCreator()
164 srcimgsize = (misc.get_file_size(base_on)) * 1024L * 1024L
165 convertor._set_fstype("ext3")
166 convertor._set_image_size(srcimgsize)
167 base_on_dir = os.path.dirname(base_on)
168 convertor._LoopImageCreator__imgdir = base_on_dir
171 __mkinitrd(convertor)
172 convertor._create_bootconfig()
173 __run_post_cleanups(convertor)
176 convertor.print_outimage_info()
178 shutil.rmtree(base_on_dir, ignore_errors = True)
181 def do_unpack(cls, srcimg):
183 imgsize = misc.get_file_size(img) * 1024L * 1024L
184 imgmnt = misc.mkdtemp()
185 disk = fs_related.SparseLoopbackDisk(img, imgsize)
186 imgloop = PartitionedMount({'/dev/sdb':disk}, imgmnt, skipformat = True)
187 imgloop.add_partition(imgsize/1024/1024, "/dev/sdb", "/", "vfat", boot=False)
190 except errors.MountError:
194 # legacy LiveOS filesystem layout support, remove for F9 or F10
195 if os.path.exists(imgmnt + "/squashfs.img"):
196 squashimg = imgmnt + "/squashfs.img"
198 squashimg = imgmnt + "/LiveOS/squashfs.img"
200 tmpoutdir = misc.mkdtemp()
201 # unsquashfs requires outdir mustn't exist
202 shutil.rmtree(tmpoutdir, ignore_errors = True)
203 misc.uncompress_squashfs(squashimg, tmpoutdir)
206 # legacy LiveOS filesystem layout support, remove for F9 or F10
207 if os.path.exists(tmpoutdir + "/os.img"):
208 os_image = tmpoutdir + "/os.img"
210 os_image = tmpoutdir + "/LiveOS/ext3fs.img"
212 if not os.path.exists(os_image):
213 raise errors.CreatorError("'%s' is not a valid live CD ISO : neither "
214 "LiveOS/ext3fs.img nor os.img exist" %img)
215 rtimage = os.path.join(tempfile.mkdtemp(dir = "/var/tmp", prefix = "tmp"), "target.img")
216 shutil.copyfile(os_image, rtimage)
220 shutil.rmtree(tmpoutdir, ignore_errors = True)
221 shutil.rmtree(imgmnt, ignore_errors = True)