diff --git a/image_creator/dialog_main.py b/image_creator/dialog_main.py index 88c295a38cc3fc77428b5146fe24a20161e0f90e..b5e2164210903ed045d728d98cedb44bf972efb4 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 2dcbac31efe491659ada149964636e835b74a045..d2212c2dbdb784af4a515a25e8b02626ab3fee48 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 7b3b5c3ce0de03f2ff0516482ab29b8b31eae6f2..3532cbca157ad209733269625fcb79f99e332081 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",