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