33af1a609ca8ffd7ac8fd11342b0d940ab9d6203
[tools/mic.git] / plugins / imager / liveusb_plugin.py
1 #!/usr/bin/python
2 import os.path
3 import sys
4 import subprocess
5 import logging
6 import shutil
7 import tempfile
8
9 from micng.pluginbase.imager_plugin import ImagerPlugin
10 import micng.imager.liveusb as liveusb
11 import micng.utils.misc as misc
12 import micng.utils.fs_related as fs_related
13 import micng.utils.cmdln as cmdln
14 import micng.configmgr as configmgr
15 import micng.pluginmgr as pluginmgr
16 from micng.utils.partitionedfs import PartitionedMount
17 from micng.utils.errors import *
18 import micng.chroot as chroot
19
20 class LiveUSBPlugin(ImagerPlugin):
21     #@cmdln.option
22     @classmethod
23     def do_create(self, subcmd, opts, *args):
24         """${cmd_name}: create livecd image
25
26         ${cmd_usage}
27         ${cmd_option_list}
28         """
29         if len(args) == 0:
30             return
31         if len(args) == 1:
32             ksconf = args[0]
33         else:
34             raise errors.Usage("Extra arguments given")
35
36
37         cfgmgr = configmgr.getConfigMgr()
38         creatoropts = cfgmgr.create
39         cfgmgr.setProperty("ksconf", args[0])
40         plgmgr = pluginmgr.PluginMgr()
41         plgmgr.loadPlugins()       
42
43         for (key, pcls) in plgmgr.getBackendPlugins():
44             if key == creatoropts['pkgmgr']:
45                 pkgmgr = pcls
46     
47         creator = liveusb.LiveUSBImageCreator(creatoropts, pkgmgr)
48         try:
49             creator.check_depend_tools()
50             creator.mount(None, creatoropts["cachedir"])
51             creator.install()
52             creator.configure(creatoropts["repomd"])
53             creator.unmount()
54             creator.package(creatoropts["outdir"])
55             outimage = creator.outimage
56             creator.print_outimage_info()
57             outimage = creator.outimage
58         except CreatorError, e:
59             logging.exception(e)
60             raise CreatorError("failed to create image : %s" % e)
61         finally:
62             creator.cleanup()
63             print "Finished."
64         return 0
65
66     @classmethod    
67     def do_chroot(cls, target):
68         img = target
69         imgsize = misc.get_file_size(img) * 1024L * 1024L
70         imgmnt = misc.mkdtemp()
71         disk = fs_related.SparseLoopbackDisk(img, imgsize)
72         imgloop = PartitionedMount({'/dev/sdb':disk}, imgmnt, skipformat = True)
73         imgloop.add_partition(imgsize/1024/1024, "/dev/sdb", "/", "vfat", boot=False)
74         try:
75             imgloop.mount()
76         except MountError, e:
77             imgloop.cleanup()
78             raise CreatorError("Failed to loopback mount '%s' : %s" %(img, e))
79
80         # legacy LiveOS filesystem layout support, remove for F9 or F10
81         if os.path.exists(imgmnt + "/squashfs.img"):
82             squashimg = imgmnt + "/squashfs.img"
83         else:
84             squashimg = imgmnt + "/LiveOS/squashfs.img"
85
86         tmpoutdir = misc.mkdtemp()
87         # unsquashfs requires outdir mustn't exist
88         shutil.rmtree(tmpoutdir, ignore_errors = True)
89         misc.uncompress_squashfs(squashimg, tmpoutdir)
90
91         # legacy LiveOS filesystem layout support, remove for F9 or F10
92         if os.path.exists(tmpoutdir + "/os.img"):
93             os_image = tmpoutdir + "/os.img"
94         else:
95             os_image = tmpoutdir + "/LiveOS/ext3fs.img"
96
97         if not os.path.exists(os_image):
98             imgloop.cleanup()
99             shutil.rmtree(tmpoutdir, ignore_errors = True)
100             shutil.rmtree(imgmnt, ignore_errors = True)
101             raise CreatorError("'%s' is not a valid live CD ISO : neither "
102                                "LiveOS/ext3fs.img nor os.img exist" %img)
103
104         #unpack image to target dir
105         imgsize = misc.get_file_size(os_image) * 1024L * 1024L
106         extmnt = misc.mkdtemp()
107         tfstype = "ext3"
108         tlabel = "ext3 label"
109         MyDiskMount = fs_related.ExtDiskMount
110         #if imgcreate.fstype_is_btrfs(os_image):
111         #    tfstype = "btrfs"
112         #    tlabel = "btrfs label"
113         #    MyDiskMount = fs_related.BtrfsDiskMount
114         extloop = MyDiskMount(fs_related.SparseLoopbackDisk(os_image, imgsize),
115                                               extmnt,
116                                               tfstype,
117                                               4096,
118                                               tlabel)
119         try:
120             extloop.mount()
121         except MountError, e:
122             extloop.cleanup()
123             shutil.rmtree(extmnt, ignore_errors = True)
124             imgloop.cleanup()
125             shutil.rmtree(tmpoutdir, ignore_errors = True)
126             shutil.rmtree(imgmnt, ignore_errors = True)
127             raise CreatorError("Failed to loopback mount '%s' : %s" %(os_image, e))
128         try:
129             chroot.chroot(extmnt, None,  "/bin/env HOME=/root /bin/bash")
130         except:
131             raise CreatorError("Failed to chroot to %s." %img)
132         finally:
133             imgloop.cleanup()
134             shutil.rmtree(imgmnt, ignore_errors = True) 
135             chroot.cleanup_after_chroot("img", extloop, tmpoutdir, extmnt)
136     
137     @classmethod
138     def do_pack(cls, base_on):
139         def __mkinitrd(instance):
140             kernelver = instance._get_kernel_versions().values()[0][0]
141             args = [ "/usr/libexec/mkliveinitrd", "/boot/initrd-%s.img" % kernelver, "%s" % kernelver ]
142             try:
143                 subprocess.call(args, preexec_fn = instance._chroot)
144             except OSError, (err, msg):
145                raise CreatorError("Failed to execute /usr/libexec/mkliveinitrd: %s" % msg)
146
147         def __run_post_cleanups(instance):
148             kernelver = instance._get_kernel_versions().values()[0][0]
149             args = ["rm", "-f", "/boot/initrd-%s.img" % kernelver]
150             try:
151                 subprocess.call(args, preexec_fn = instance._chroot)
152             except OSError, (err, msg):
153                raise CreatorError("Failed to run post cleanups: %s" % msg)
154
155         convertor = liveusb.LiveUSBImageCreator()
156         srcimgsize = (misc.get_file_size(base_on)) * 1024L * 1024L
157         convertor._set_fstype("ext3")
158         convertor._set_image_size(srcimgsize)
159         base_on_dir = os.path.dirname(base_on)
160         convertor._LoopImageCreator__imgdir = base_on_dir
161         convertor.mount()
162         __mkinitrd(convertor)
163         convertor._create_bootconfig()
164         __run_post_cleanups(convertor)
165         convertor.unmount()
166         convertor.package()
167         convertor.print_outimage_info()
168         shutil.rmtree(base_on_dir, ignore_errors = True)
169
170     @classmethod
171     def do_unpack(cls, srcimg):
172         convertor = liveusb.LiveUSBImageCreator()
173         srcimgsize = (misc.get_file_size(srcimg)) * 1024L * 1024L
174         convertor._srcfmt = 'livecd'
175         convertor._set_fstype("ext3")
176         convertor._set_image_size(srcimgsize)
177         convertor.mount(srcimg, None)
178
179         image = os.path.join(tempfile.mkdtemp(dir = "/var/tmp", prefix = "tmp"), "meego.img")
180         shutil.copyfile(convertor._image, image)
181         return image
182
183 mic_plugin = ["liveusb", LiveUSBPlugin]
184