add qcow image support
[tools/mic.git] / plugins / imager / qcow_plugin.py
1 #
2 # Copyright (c) 2014 Intel, Inc.
3 #
4 # This program is free software; you can redistribute it and/or modify it
5 # under the terms of the GNU General Public License as published by the Free
6 # Software Foundation; version 2 of the License
7 #
8 # This program is distributed in the hope that it will be useful, but
9 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11 # for more details.
12 #
13 # You should have received a copy of the GNU General Public License along
14 # with this program; if not, write to the Free Software Foundation, Inc., 59
15 # Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16
17 import os
18 import shutil
19
20 from mic import msger, rt_util
21 from mic.conf import configmgr
22 from mic.plugin import pluginmgr
23 from mic.pluginbase import ImagerPlugin
24 from mic.imager.loop import LoopImageCreator
25 from mic.utils import errors, fs_related, runner
26
27 class QcowImageCreator(LoopImageCreator):
28     img_format = 'qcow'
29
30     def __init__(self, creatoropts=None, pkgmgr=None):
31         LoopImageCreator.__init__(self, creatoropts, pkgmgr) 
32         self.cmd_qemuimg = 'qemu-img'
33
34     def _stage_final_image(self):
35         try:
36             self.cmd_qemuimg = fs_related.find_binary_path('qemu-img')
37         except errors.CreatorError:
38             return LoopImageCreator._stage_final_image(self)
39
40         self._resparse()
41
42         imgfile = None
43         for item in self._instloops:
44             if item['mountpoint'] == '/':
45                 if item['fstype'] == "ext4":
46                     runner.show('/sbin/tune2fs -O ^huge_file,extents,uninit_bg %s'
47                                 % imgfile)
48                 self.image_files.setdefault('partitions', {}).update(
49                          {item['mountpoint']: item['label']})
50                 imgfile = os.path.join(self._imgdir, item['name'])
51
52         if imgfile:
53             qemuimage = imgfile + ".x86"
54             runner.show("%s convert -O qcow2 %s %s"
55                         % (self.cmd_qemuimg, imgfile, qemuimage))
56             os.unlink(imgfile)
57             os.rename(qemuimage, imgfile)
58
59         for item in os.listdir(self._imgdir):
60             shutil.move(os.path.join(self._imgdir, item),
61                         os.path.join(self._outdir, item))
62
63 class QcowPlugin(ImagerPlugin):
64     name = 'qcow'
65
66     @classmethod
67     def do_create(cls, subcmd, opts, *args):
68         """${cmd_name}: create qcow image
69
70         Usage:
71             ${name} ${cmd_name} <ksfile> [OPTS]
72
73         ${cmd_option_list}
74         """
75         if len(args) != 1:
76             raise errors.Usage("Extra arguments given")
77
78         creatoropts = configmgr.create
79         ksconf = args[0]
80
81         if creatoropts['runtime'] == "bootstrap":
82             configmgr._ksconf = ksconf
83             rt_util.bootstrap_mic()
84         elif not rt_util.inbootstrap():
85             try:
86                 fs_related.find_binary_path('mic-native')
87             except errors.CreatorError:
88                 if not msger.ask("Subpackage \"mic-native\" has not been "
89                                  "installed in your host system, still "
90                                  "continue with \"native\" running mode?",
91                                  False):
92                     raise errors.Abort("Abort because subpackage 'mic-native' "
93                                        "has not been installed")
94
95         recording_pkgs = []
96         if len(creatoropts['record_pkgs']) > 0:
97             recording_pkgs = creatoropts['record_pkgs']
98
99         if creatoropts['release'] is not None:
100             if 'name' not in recording_pkgs:
101                 recording_pkgs.append('name')
102             if 'vcs' not in recording_pkgs:
103                 recording_pkgs.append('vcs')
104
105         configmgr._ksconf = ksconf
106
107         # try to find the pkgmgr
108         pkgmgr = None
109         backends = pluginmgr.get_plugins('backend')
110         if 'auto' == creatoropts['pkgmgr']:
111             for key in configmgr.prefer_backends:
112                 if key in backends:
113                     pkgmgr = backends[key]
114                     break
115         else:
116             for key in backends.keys():
117                 if key == creatoropts['pkgmgr']:
118                     pkgmgr = backends[key]
119                     break
120
121         if not pkgmgr:
122             raise errors.CreatorError("Can't find backend: %s, "
123                                       "available choices: %s" %
124                                       (creatoropts['pkgmgr'],
125                                        ','.join(backends.keys())))
126
127         creator = QcowImageCreator(creatoropts,
128                                    pkgmgr)
129
130         if len(recording_pkgs) > 0:
131             creator._recording_pkgs = recording_pkgs
132
133         image_names = [creator.name + ".img"]
134         image_names.extend(creator.get_image_names())
135         cls.check_image_exists(creator.destdir,
136                                 creator.pack_to,
137                                 image_names,
138                                 creatoropts['release'])
139
140         try:
141             creator.check_depend_tools()
142             creator.mount(None, creatoropts["cachedir"])
143             creator.install()
144             creator.configure(creatoropts["repomd"])
145             creator.copy_kernel()
146             creator.unmount()
147             creator.package(creatoropts["destdir"])
148             creator.create_manifest()
149
150             if creatoropts['release'] is not None:
151                 creator.release_output(ksconf,
152                                        creatoropts['destdir'],
153                                        creatoropts['release'])
154             creator.print_outimage_info()
155
156         except errors.CreatorError:
157             raise
158         finally:
159             creator.cleanup()
160
161         msger.info("Finished.")
162         return 0
163
164     @classmethod
165     def do_chroot(cls, target, cmd=[]):
166         pass
167
168     @classmethod
169     def do_unpack(cls, srcimg):
170         pass