FSLABEL_MAXLEN = 32
"""The maximum string length supported for LoopImageCreator.fslabel."""
+def save_mountpoints(dpath, loops):
+ """Save mount points mapping to file
+ :loops, list of tuple (mp, label, name, size, fstype)
+ """
+
+ if not loops:
+ return None
+
+ fname = ".mountpoints"
+ fp = os.path.join(dpath, fname)
+
+ with open(fp, 'w') as wf:
+ for loop in loops:
+ wf.write(':'.join(map(str, loop)) + '\n')
+
+ return fname
+
+def load_mountpoints(dpath):
+ """Load mount points mapping from file
+ """
+ mps = []
+ with open(os.path.join(dpath, '.mountpoints')) as f:
+ for line in f.readlines():
+ try:
+ mps.append(tuple(line.strip().split(':')))
+ except:
+ msger.warning("wrong format line in mountpoints mapping file")
+ return mps
+
class LoopImageCreator(BaseImageCreator):
"""Installs a system into a loopback-mountable filesystem image.
% item['name'])
tar.add(item['name'])
- # append mount map file to tar ball
- mountmap = misc.write_mount_point(self._instloops)
- tar.add(mountmap)
+ # append mount points mapping file to tar ball
+ mountmap_fp = save_mountpoints(self.__imgdir,
+ [(loop['mountpoint'],
+ loop['label'],
+ loop['name'],
+ loop['size'],
+ loop['fstype']) for loop in self._instloops])
+ if mountmap_fp:
+ tar.add(mountmap_fp)
tar.close()
os.chdir(curdir)
from mic.utils import misc, fs_related, errors, cmdln
from mic.conf import configmgr
from mic.plugin import pluginmgr
-import mic.imager.loop as loop
+from mic.imager.loop import LoopImageCreator, load_mountpoints
from mic.pluginbase import ImagerPlugin
class LoopPlugin(ImagerPlugin):
pkgmgrs = pluginmgr.get_plugins('backend').keys()
raise errors.CreatorError("Can't find package manager: %s (availables: %s)" % (creatoropts['pkgmgr'], ', '.join(pkgmgrs)))
- creator = loop.LoopImageCreator(creatoropts, pkgmgr, opts.taring_to)
+ creator = LoopImageCreator(creatoropts, pkgmgr, opts.taring_to)
if len(recording_pkgs) > 0:
creator._recording_pkgs = recording_pkgs
imagefile = "%s.tar" % os.path.join(creator.destdir, opts.taring_to)
else:
imagefile = "%s.img" % os.path.join(creator.destdir, creator.name)
+
if os.path.exists(imagefile):
if msger.ask('The target image: %s already exists, cleanup and continue?' % imagefile):
os.unlink(imagefile)
return 0
@classmethod
- def do_chroot_tar(cls, target):
+ def _do_chroot_tar(cls, target):
import tarfile
-
tar = tarfile.open(target, 'r')
tmpdir = misc.mkdtemp()
tar.extractall(path=tmpdir)
tar.close()
- loops = []
mntdir = misc.mkdtemp()
- with open(os.path.join(tmpdir, '.mountpoints'), 'r') as f:
- for line in f.readlines():
- try:
- mp, label, name, size, fstype = line.strip('\n').split(':')
- except:
- msger.error("Wrong format image tarball: %s" % target)
-
- if fstype in ("ext2", "ext3", "ext4"):
- myDiskMount = fs_related.ExtDiskMount
- elif fstype == "btrfs":
- myDiskMount = fs_related.BtrfsDiskMount
- elif fstype in ("vfat", "msdos"):
- myDiskMount = fs_related.VfatDiskMount
- else:
- msger.error("Cannot support fstype: %s" % fstype)
-
- name = os.path.join(tmpdir, name)
- size = int(size) * 1024L * 1024L
- loop = myDiskMount(fs_related.SparseLoopbackDisk(name, size),
- os.path.join(mntdir, mp.lstrip('/')),
- fstype, size, label)
- loops.append(loop)
-
- try:
- msger.verbose("Mount %s to %s" % (mp, mntdir + mp))
- fs_related.makedirs(os.path.join(mntdir, mp.lstrip('/')))
- loop.mount()
- except:
- loop.cleanup()
- shutil.rmtree(mntdir, ignore_errors = True)
- raise
+
+ loops = []
+ for (mp, label, name, size, fstype) in load_mountpoints(tmpdir):
+ if fstype in ("ext2", "ext3", "ext4"):
+ myDiskMount = fs_related.ExtDiskMount
+ elif fstype == "btrfs":
+ myDiskMount = fs_related.BtrfsDiskMount
+ elif fstype in ("vfat", "msdos"):
+ myDiskMount = fs_related.VfatDiskMount
+ else:
+ msger.error("Cannot support fstype: %s" % fstype)
+
+ name = os.path.join(tmpdir, name)
+ size = int(size) * 1024L * 1024L
+ loop = myDiskMount(fs_related.SparseLoopbackDisk(name, size),
+ os.path.join(mntdir, mp.lstrip('/')),
+ fstype, size, label)
+
+ try:
+ msger.verbose("Mount %s to %s" % (mp, mntdir + mp))
+ fs_related.makedirs(os.path.join(mntdir, mp.lstrip('/')))
+ loop.mount()
+
+ except:
+ loop.cleanup()
+ for lp in reversed(loops):
+ chroot.cleanup_after_chroot("img", lp, None, mntdir)
+
+ shutil.rmtree(mntdir, ignore_errors = True)
+ shutil.rmtree(tmpdir, ignore_errors = True)
+ raise
+
+ loops.append(loop)
+
try:
chroot.chroot(mntdir, None, "/bin/env HOME=/root /bin/bash")
except:
finally:
for loop in reversed(loops):
chroot.cleanup_after_chroot("img", loop, None, mntdir)
+
shutil.rmtree(tmpdir, ignore_errors = True)
@classmethod
def do_chroot(cls, target):#chroot.py parse opts&args
import tarfile
if tarfile.is_tarfile(target):
- LoopPlugin.do_chroot_tar(target)
+ LoopPlugin._do_chroot_tar(target)
return
+
img = target
imgsize = misc.get_file_size(img) * 1024L * 1024L
imgtype = misc.get_image_type(img)