From fcc4df5db9ffea1ed6e8697e64d16a10eb722c4a Mon Sep 17 00:00:00 2001 From: Nikos Skalkotos <skalkoto@grnet.gr> Date: Mon, 9 Jun 2014 18:14:16 +0300 Subject: [PATCH] Add device attribute in Disk class This attribute hosts the block device associated with this Disk instance. This can be the original media if the source media is a block device, a loop device of the original media if the original media is a regular file or a loop device of a temporary object if the original media is a directory. --- image_creator/dialog_main.py | 7 +++++-- image_creator/disk.py | 28 ++++++++++++++++++---------- image_creator/main.py | 11 ++++++----- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/image_creator/dialog_main.py b/image_creator/dialog_main.py index 88c295a..b5e2164 100644 --- a/image_creator/dialog_main.py +++ b/image_creator/dialog_main.py @@ -61,8 +61,11 @@ def create_image(d, media, out, tmp): signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) try: - snapshot = disk.snapshot() - image = disk.get_image(snapshot) + # There is no need to snapshot the media if it was created by the Disk + # instance as a temporary object. + device = disk.device if disk.source == '/' else disk.snapshot() + + image = disk.get_image(device) out.output("Collecting image metadata ...") metadata = {} diff --git a/image_creator/disk.py b/image_creator/disk.py index 2dcbac3..d2212c2 100644 --- a/image_creator/disk.py +++ b/image_creator/disk.py @@ -72,6 +72,7 @@ class Disk(object): """ self._cleanup_jobs = [] self._images = [] + self._device = None self.source = source self.out = output self.meta = {} @@ -123,29 +124,36 @@ class Disk(object): job, args = self._cleanup_jobs.pop() job(*args) - def snapshot(self): - """Creates a snapshot of the original source media of the Disk - instance. - """ + @property + def device(self): + """Convert the source media into a block device""" + + if self._device is not None: + return self._device self.out.output("Examining source media `%s' ..." % self.source, False) - sourcedev = self.source mode = os.stat(self.source).st_mode if stat.S_ISDIR(mode): self.out.success('looks like a directory') - return self._dir_to_disk() + self._device = self._dir_to_disk() elif stat.S_ISREG(mode): self.out.success('looks like an image file') - sourcedev = self._losetup(self.source) + self._device = self._losetup(self.source) elif not stat.S_ISBLK(mode): raise FatalError("Invalid media source. Only block devices, " "regular files and directories are supported.") else: self.out.success('looks like a block device') + self._device = self.source - # Take a snapshot and return it to the user + return self._device + + def snapshot(self): + """Creates a snapshot of the original source media of the Disk + instance. + """ self.out.output("Snapshotting media source ...", False) - size = blockdev('--getsz', sourcedev) + size = blockdev('--getsz', self.device) cowfd, cow = tempfile.mkstemp(dir=self.tmp) os.close(cowfd) self._add_cleanup(os.unlink, cow) @@ -158,7 +166,7 @@ class Disk(object): try: try: os.write(tablefd, "0 %d snapshot %s %s n 8" % - (int(size), sourcedev, cowdev)) + (int(size), self.device, cowdev)) finally: os.close(tablefd) diff --git a/image_creator/main.py b/image_creator/main.py index 7b3b5c3..3532cbc 100644 --- a/image_creator/main.py +++ b/image_creator/main.py @@ -257,9 +257,10 @@ def image_creator(): signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) try: - snapshot = disk.snapshot() - - image = disk.get_image(snapshot, sysprep_params=options.sysprep_params) + # There is no need to snapshot the media if it was created by the Disk + # instance as a temporary object. + device = disk.device if disk.source == '/' else disk.snapshot() + image = disk.get_image(device, sysprep_params=options.sysprep_params) if image.is_unsupported() and not options.allow_unsupported: raise FatalError( @@ -323,7 +324,7 @@ def image_creator(): os.path.basename(options.outfile))) out.success('done') - # Destroy the image instance. We only need the snapshot from now on + # Destroy the image instance. We only need the disk device from now on disk.destroy_image(image) out.output() @@ -331,7 +332,7 @@ def image_creator(): uploaded_obj = "" if options.upload: out.output("Uploading image to the storage service:") - with open(snapshot, 'rb') as f: + with open(device, 'rb') as f: uploaded_obj = kamaki.upload( f, size, options.upload, "(1/3) Calculating block hashes", -- GitLab