3 # Copyright (c) 2011 Intel, Inc.
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
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
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.
22 from mic import chroot, msger, rt_util
23 from mic.utils import misc, fs_related, errors, cmdln
24 from mic.conf import configmgr
25 from mic.plugin import pluginmgr
26 from mic.imager.loop import LoopImageCreator, load_mountpoints
28 from mic.pluginbase import ImagerPlugin
29 class LoopPlugin(ImagerPlugin):
33 @cmdln.option("--compress-disk-image", dest="compress_image",
34 type='choice', choices=("gz", "bz2"), default=None,
35 help="Same with --compress-image")
36 # alias to compress-image for compatibility
37 @cmdln.option("--compress-image", dest="compress_image",
38 type='choice', choices=("gz", "bz2"), default=None,
39 help="Compress all loop images wiht 'gz' or 'bz2'")
40 @cmdln.option("--shrink", action='store_true', default=False,
41 help="Whether to shrink loop images to minimal size")
42 def do_create(self, subcmd, opts, *args):
43 """${cmd_name}: create loop image
46 ${name} ${cmd_name} <ksfile> [OPTS]
52 raise errors.Usage("need one argument as the path of ks file")
55 raise errors.Usage("Extra arguments given")
57 creatoropts = configmgr.create
60 if not os.path.exists(ksconf):
61 raise errors.CreatorError("Can't find the file: %s" % ksconf)
64 if len(creatoropts['record_pkgs']) > 0:
65 recording_pkgs = creatoropts['record_pkgs']
67 if creatoropts['release'] is not None:
68 if 'name' not in recording_pkgs:
69 recording_pkgs.append('name')
71 ksconf = misc.normalize_ksfile(ksconf,
72 creatoropts['release'],
74 configmgr._ksconf = ksconf
76 # Called After setting the configmgr._ksconf
77 # as the creatoropts['name'] is reset there.
78 if creatoropts['release'] is not None:
79 creatoropts['outdir'] = "%s/%s/images/%s/" % (creatoropts['outdir'],
80 creatoropts['release'],
83 # try to find the pkgmgr
85 for (key, pcls) in pluginmgr.get_plugins('backend').iteritems():
86 if key == creatoropts['pkgmgr']:
91 pkgmgrs = pluginmgr.get_plugins('backend').keys()
92 raise errors.CreatorError("Can't find package manager: %s "
94 % (creatoropts['pkgmgr'],
97 if creatoropts['runtime']:
98 rt_util.runmic_in_runtime(creatoropts['runtime'], creatoropts, ksconf, None)
100 creator = LoopImageCreator(creatoropts,
105 if len(recording_pkgs) > 0:
106 creator._recording_pkgs = recording_pkgs
108 self.check_image_exists(creator.destdir,
110 [creator.name + ".img"],
111 creatoropts['release'])
114 creator.check_depend_tools()
115 creator.mount(None, creatoropts["cachedir"])
117 creator.configure(creatoropts["repomd"])
118 creator.copy_kernel()
120 creator.package(creatoropts["outdir"])
122 if creatoropts['release'] is not None:
123 creator.release_output(ksconf,
124 creatoropts['outdir'],
125 creatoropts['release'])
126 creator.print_outimage_info()
128 except errors.CreatorError:
133 msger.info("Finished.")
137 def _do_chroot_tar(cls, target):
138 mountfp_xml = os.path.splitext(target)[0] + '.xml'
139 if not os.path.exists(mountfp_xml):
140 raise errors.CreatorError("No mount point file found for this tar "
141 "image, please check %s" % mountfp_xml)
144 tar = tarfile.open(target, 'r')
145 tmpdir = misc.mkdtemp()
146 tar.extractall(path=tmpdir)
149 mntdir = misc.mkdtemp()
152 for (mp, label, name, size, fstype) in load_mountpoints(mountfp_xml):
153 if fstype in ("ext2", "ext3", "ext4"):
154 myDiskMount = fs_related.ExtDiskMount
155 elif fstype == "btrfs":
156 myDiskMount = fs_related.BtrfsDiskMount
157 elif fstype in ("vfat", "msdos"):
158 myDiskMount = fs_related.VfatDiskMount
160 msger.error("Cannot support fstype: %s" % fstype)
162 name = os.path.join(tmpdir, name)
163 size = size * 1024L * 1024L
164 loop = myDiskMount(fs_related.SparseLoopbackDisk(name, size),
165 os.path.join(mntdir, mp.lstrip('/')),
169 msger.verbose("Mount %s to %s" % (mp, mntdir + mp))
170 fs_related.makedirs(os.path.join(mntdir, mp.lstrip('/')))
175 for lp in reversed(loops):
176 chroot.cleanup_after_chroot("img", lp, None, mntdir)
178 shutil.rmtree(tmpdir, ignore_errors=True)
184 chroot.chroot(mntdir, None, "/usr/bin/env HOME=/root /bin/bash")
186 raise errors.CreatorError("Failed to chroot to %s." % target)
188 for loop in reversed(loops):
189 chroot.cleanup_after_chroot("img", loop, None, mntdir)
191 shutil.rmtree(tmpdir, ignore_errors=True)
194 def do_chroot(cls, target):
195 if target.endswith('.tar'):
197 if tarfile.is_tarfile(target):
198 LoopPlugin._do_chroot_tar(target)
201 raise errors.CreatorError("damaged tarball for loop images")
204 imgsize = misc.get_file_size(img) * 1024L * 1024L
205 imgtype = misc.get_image_type(img)
206 if imgtype == "btrfsimg":
208 myDiskMount = fs_related.BtrfsDiskMount
209 elif imgtype in ("ext3fsimg", "ext4fsimg"):
211 myDiskMount = fs_related.ExtDiskMount
213 raise errors.CreatorError("Unsupported filesystem type: %s" \
216 extmnt = misc.mkdtemp()
217 extloop = myDiskMount(fs_related.SparseLoopbackDisk(img, imgsize),
225 except errors.MountError:
227 shutil.rmtree(extmnt, ignore_errors=True)
231 envcmd = fs_related.find_binary_inchroot("env", extmnt)
233 cmdline = "%s HOME=/root /bin/bash" % envcmd
235 cmdline = "/bin/bash"
236 chroot.chroot(extmnt, None, cmdline)
238 raise errors.CreatorError("Failed to chroot to %s." % img)
240 chroot.cleanup_after_chroot("img", extloop, None, extmnt)
243 def do_unpack(cls, srcimg):
244 image = os.path.join(tempfile.mkdtemp(dir="/var/tmp", prefix="tmp"),
246 msger.info("Copying file system ...")
247 shutil.copyfile(srcimg, image)