cleanup the code related with mic-native
[platform/upstream/mic.git] / plugins / imager / liveusb_plugin.py
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
18 import os
19 import shutil
20 import tempfile
21
22 from mic import chroot, msger, rt_util
23 from mic.utils import misc, fs_related, errors
24 from mic.utils.partitionedfs import PartitionedMount
25 from mic.conf import configmgr
26 from mic.plugin import pluginmgr
27
28 import mic.imager.liveusb as liveusb
29
30 from mic.pluginbase import ImagerPlugin
31 class LiveUSBPlugin(ImagerPlugin):
32     name = 'liveusb'
33
34     @classmethod
35     def do_create(self, subcmd, opts, *args):
36         """${cmd_name}: create liveusb image
37
38         Usage:
39             ${name} ${cmd_name} <ksfile> [OPTS]
40
41         ${cmd_option_list}
42         """
43
44         if len(args) != 1:
45             raise errors.Usage("Extra arguments given")
46
47         creatoropts = configmgr.create
48         ksconf = args[0]
49
50         if creatoropts['runtime'] == "bootstrap":
51             configmgr._ksconf = ksconf
52             rt_util.bootstrap_mic()
53
54         if creatoropts['arch'] and creatoropts['arch'].startswith('arm'):
55             msger.warning('liveusb cannot support arm images, Quit')
56             return
57
58         recording_pkgs = []
59         if len(creatoropts['record_pkgs']) > 0:
60             recording_pkgs = creatoropts['record_pkgs']
61
62         if creatoropts['release'] is not None:
63             if 'name' not in recording_pkgs:
64                 recording_pkgs.append('name')
65             if 'vcs' not in recording_pkgs:
66                 recording_pkgs.append('vcs')
67
68         configmgr._ksconf = ksconf
69
70         # try to find the pkgmgr
71         pkgmgr = None
72         backends = pluginmgr.get_plugins('backend')
73         if 'auto' == creatoropts['pkgmgr']:
74             for key in configmgr.prefer_backends:
75                 if key in backends:
76                     pkgmgr = backends[key]
77                     break
78         else:
79             for key in backends.keys():
80                 if key == creatoropts['pkgmgr']:
81                     pkgmgr = backends[key]
82                     break
83
84         if not pkgmgr:
85             raise errors.CreatorError("Can't find backend: %s, "
86                                       "available choices: %s" %
87                                       (creatoropts['pkgmgr'],
88                                        ','.join(backends.keys())))
89
90         creator = liveusb.LiveUSBImageCreator(creatoropts, pkgmgr)
91
92         if len(recording_pkgs) > 0:
93             creator._recording_pkgs = recording_pkgs
94
95         self.check_image_exists(creator.destdir,
96                                 creator.pack_to,
97                                 [creator.name + ".usbimg"],
98                                 creatoropts['release'])
99         try:
100             creator.check_depend_tools()
101             creator.mount(None, creatoropts["cachedir"])
102             creator.install()
103             creator.configure(creatoropts["repomd"])
104             creator.copy_kernel()
105             creator.unmount()
106             creator.package(creatoropts["destdir"])
107             creator.create_manifest()
108             if creatoropts['release'] is not None:
109                 creator.release_output(ksconf, creatoropts['destdir'], creatoropts['release'])
110             creator.print_outimage_info()
111
112         except errors.CreatorError:
113             raise
114         finally:
115             creator.cleanup()
116
117         msger.info("Finished.")
118         return 0
119
120     @classmethod
121     def do_chroot(cls, target, cmd=[]):
122         os_image = cls.do_unpack(target)
123         os_image_dir = os.path.dirname(os_image)
124
125         # unpack image to target dir
126         imgsize = misc.get_file_size(os_image) * 1024L * 1024L
127         imgtype = misc.get_image_type(os_image)
128         if imgtype == "btrfsimg":
129             fstype = "btrfs"
130             myDiskMount = fs_related.BtrfsDiskMount
131         elif imgtype in ("ext3fsimg", "ext4fsimg"):
132             fstype = imgtype[:4]
133             myDiskMount = fs_related.ExtDiskMount
134         else:
135             raise errors.CreatorError("Unsupported filesystem type: %s" % fstype)
136
137         extmnt = misc.mkdtemp()
138         extloop = myDiskMount(fs_related.SparseLoopbackDisk(os_image, imgsize),
139                               extmnt,
140                               fstype,
141                               4096,
142                               "%s label" % fstype)
143
144         try:
145             extloop.mount()
146
147         except errors.MountError:
148             extloop.cleanup()
149             shutil.rmtree(extmnt, ignore_errors = True)
150             raise
151
152         try:
153             if len(cmd) != 0:
154                 cmdline = ' '.join(cmd)
155             else:
156                 cmdline = "/bin/bash"
157             envcmd = fs_related.find_binary_inchroot("env", extmnt)
158             if envcmd:
159                 cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
160             chroot.chroot(extmnt, None, cmdline)
161         except:
162             raise errors.CreatorError("Failed to chroot to %s." %target)
163         finally:
164             chroot.cleanup_after_chroot("img", extloop, os_image_dir, extmnt)
165
166     @classmethod
167     def do_pack(cls, base_on):
168         import subprocess
169
170         def __mkinitrd(instance):
171             kernelver = instance._get_kernel_versions().values()[0][0]
172             args = [ "/usr/libexec/mkliveinitrd", "/boot/initrd-%s.img" % kernelver, "%s" % kernelver ]
173             try:
174                 subprocess.call(args, preexec_fn = instance._chroot)
175
176             except OSError, (err, msg):
177                 raise errors.CreatorError("Failed to execute /usr/libexec/mkliveinitrd: %s" % msg)
178
179         def __run_post_cleanups(instance):
180             kernelver = instance._get_kernel_versions().values()[0][0]
181             args = ["rm", "-f", "/boot/initrd-%s.img" % kernelver]
182
183             try:
184                 subprocess.call(args, preexec_fn = instance._chroot)
185             except OSError, (err, msg):
186                 raise errors.CreatorError("Failed to run post cleanups: %s" % msg)
187
188         convertoropts = configmgr.convert
189         convertoropts['name'] = os.path.splitext(os.path.basename(base_on))[0]
190         convertor = liveusb.LiveUSBImageCreator(convertoropts)
191         imgtype = misc.get_image_type(base_on)
192         if imgtype == "btrfsimg":
193             fstype = "btrfs"
194         elif imgtype in ("ext3fsimg", "ext4fsimg"):
195             fstype = imgtype[:4]
196         else:
197             raise errors.CreatorError("Unsupported filesystem type: %s" % fstyp)
198         convertor._set_fstype(fstype)
199         try:
200             convertor.mount(base_on)
201             __mkinitrd(convertor)
202             convertor._create_bootconfig()
203             __run_post_cleanups(convertor)
204             convertor.launch_shell(convertoropts['shell'])
205             convertor.unmount()
206             convertor.package()
207             convertor.print_outimage_info()
208         finally:
209             shutil.rmtree(os.path.dirname(base_on), ignore_errors = True)
210
211     @classmethod
212     def do_unpack(cls, srcimg):
213         img = srcimg
214         imgsize = misc.get_file_size(img) * 1024L * 1024L
215         imgmnt = misc.mkdtemp()
216         disk = fs_related.SparseLoopbackDisk(img, imgsize)
217         imgloop = PartitionedMount(imgmnt, skipformat = True)
218         imgloop.add_disk('/dev/sdb', disk)
219         imgloop.add_partition(imgsize/1024/1024, "/dev/sdb", "/", "vfat", boot=False)
220         try:
221             imgloop.mount()
222         except errors.MountError:
223             imgloop.cleanup()
224             raise
225
226         # legacy LiveOS filesystem layout support, remove for F9 or F10
227         if os.path.exists(imgmnt + "/squashfs.img"):
228             squashimg = imgmnt + "/squashfs.img"
229         else:
230             squashimg = imgmnt + "/LiveOS/squashfs.img"
231
232         tmpoutdir = misc.mkdtemp()
233         # unsquashfs requires outdir mustn't exist
234         shutil.rmtree(tmpoutdir, ignore_errors = True)
235         misc.uncompress_squashfs(squashimg, tmpoutdir)
236
237         try:
238             # legacy LiveOS filesystem layout support, remove for F9 or F10
239             if os.path.exists(tmpoutdir + "/os.img"):
240                 os_image = tmpoutdir + "/os.img"
241             else:
242                 os_image = tmpoutdir + "/LiveOS/ext3fs.img"
243
244             if not os.path.exists(os_image):
245                 raise errors.CreatorError("'%s' is not a valid live CD ISO : neither "
246                                           "LiveOS/ext3fs.img nor os.img exist" %img)
247             imgname = os.path.basename(srcimg)
248             imgname = os.path.splitext(imgname)[0] + ".img"
249             rtimage = os.path.join(tempfile.mkdtemp(dir = "/var/tmp", prefix = "tmp"), imgname)
250             shutil.copyfile(os_image, rtimage)
251
252         finally:
253             imgloop.cleanup()
254             shutil.rmtree(tmpoutdir, ignore_errors = True)
255             shutil.rmtree(imgmnt, ignore_errors = True)
256
257         return rtimage