X-Git-Url: https://code.grnet.gr/git/snf-image-creator/blobdiff_plain/88f83027df65608a70e1a88f96b4a3055427dd52..17649dd681e2d2f1c98ca8764cc77043740c9e97:/image_creator/bundle_volume.py diff --git a/image_creator/bundle_volume.py b/image_creator/bundle_volume.py index c4cc83c..215afb2 100644 --- a/image_creator/bundle_volume.py +++ b/image_creator/bundle_volume.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- +# # Copyright 2012 GRNET S.A. All rights reserved. # # Redistribution and use in source and binary forms, with or @@ -31,6 +33,11 @@ # interpreted as representing official policies, either expressed # or implied, of GRNET S.A. +"""This module hosts the code that performes the host bundling operation. By +using the create_image method of the BundleVolume class the user can create an +image out of the running system. +""" + import os import re import tempfile @@ -53,6 +60,7 @@ losetup = get_command('losetup') mount = get_command('mount') umount = get_command('umount') blkid = get_command('blkid') +tune2fs = get_command('tune2fs') MKFS_OPTS = {'ext2': ['-F'], 'ext3': ['-F'], @@ -259,8 +267,11 @@ class BundleVolume(object): name = os.path.basename(dev) + "_" + uuid.uuid4().hex tablefd, table = tempfile.mkstemp() try: - size = end - start + 1 - os.write(tablefd, "0 %d linear %s %d" % (size, dev, start)) + try: + size = end - start + 1 + os.write(tablefd, "0 %d linear %s %d" % (size, dev, start)) + finally: + os.close(tablefd) dmsetup('create', "%sp%d" % (name, num), table) finally: os.unlink(table) @@ -277,11 +288,15 @@ class BundleVolume(object): def _mount(self, target, devs): """Mount a list of filesystems in mountpoints relative to target""" devs.sort(key=lambda d: d[1]) - for dev, mpoint in devs: + for dev, mpoint, options in devs: absmpoint = os.path.abspath(target + mpoint) if not os.path.exists(absmpoint): os.makedirs(absmpoint) - mount(dev, absmpoint) + + if len(options) > 0: + mount(dev, absmpoint, '-o', ",".join(options)) + else: + mount(dev, absmpoint) def _umount_all(self, target): """Unmount all filesystems that are mounted under the directory target @@ -369,8 +384,10 @@ class BundleVolume(object): """ filesystem = {} + orig_dev = {} for p in self.disk.partitions: filesystem[p.number] = self._get_mount_options(p.path) + orig_dev[p.number] = p.path unmounted = filter(lambda p: filesystem[p.num] is None, partitions) mounted = filter(lambda p: filesystem[p.num] is not None, partitions) @@ -385,6 +402,8 @@ class BundleVolume(object): self.out.success("done") loop = str(losetup('-f', '--show', image)).strip() + + # Recreate mounted file systems mapped = {} try: for p in mounted: @@ -398,15 +417,34 @@ class BundleVolume(object): self.out.output('Creating %s filesystem on partition %d ... ' % (fs, i), False) get_command('mkfs.%s' % fs)(*(MKFS_OPTS[fs] + [dev])) + + # For ext[234] enable the default mount options + if re.match('^ext[234]$', fs): + mopts = filter( + lambda p: p.startswith('Default mount options:'), + tune2fs('-l', orig_dev[i]).splitlines() + )[0].split(':')[1].strip().split() + + if not (len(mopts) == 1 and mopts[0] == '(none)'): + for opt in mopts: + tune2fs('-o', opt, dev) + self.out.success('done') new_uuid[i] = blkid( '-s', 'UUID', '-o', 'value', dev).stdout.strip() target = tempfile.mkdtemp() + devs = [] + for i in mapped.keys(): + fs = filesystem[i].fs + mpoint = filesystem[i].mpoint + opts = [] + for opt in filesystem[i].opts.split(','): + if opt in ('acl', 'user_xattr'): + opts.append(opt) + devs.append((mapped[i], mpoint, opts)) try: - self._mount( - target, - [(mapped[i], filesystem[i].mpoint) for i in mapped.keys()]) + self._mount(target, devs) excluded = self._to_exclude()