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