From: Nikos Skalkotos Date: Mon, 31 Dec 2012 01:05:32 +0000 (+0200) Subject: Fix bugs in rsync module X-Git-Tag: v0.2~21 X-Git-Url: https://code.grnet.gr/git/snf-image-creator/commitdiff_plain/d15368cc7c6256a07c8a0987faaf3e6488c2c20a Fix bugs in rsync module * Fix a bug where the parent process did not wait on the child processes. * Make sure that when updating the copy progress bar, at least 0.1 seconds have passed. This guarantees that we do not experience any flickering in the progress bar. --- diff --git a/image_creator/bundle_volume.py b/image_creator/bundle_volume.py index bd418ce..919a08b 100644 --- a/image_creator/bundle_volume.py +++ b/image_creator/bundle_volume.py @@ -378,8 +378,7 @@ class BundleVolume(object): exclude = self._to_exclude() + [image] rsync = Rsync('/', target, map(lambda p: os.path.relpath(p, '/'), exclude)) - msg = "Copying host files into the image" - rsync.archive().run(self.out, msg) + rsync.archive().run(self.out) self._replace_uuids(target, new_uuid) diff --git a/image_creator/rsync.py b/image_creator/rsync.py index 7c869c2..0c6b639 100644 --- a/image_creator/rsync.py +++ b/image_creator/rsync.py @@ -32,39 +32,74 @@ # or implied, of GRNET S.A. import subprocess +import time +import signal + +from image_creator.util import FatalError class Rsync: + """Wrapper class for the rsync command""" + def __init__(self, src, dest, exclude=[]): + """Create an instance by defining a source, a destinationa and a number + of exclude patterns. + """ self.src = src self.dest = dest self.exclude = exclude self.options = ['-v'] def archive(self): + """Enable the archive option""" self.options.append('-a') return self - def run(self, out, msg): + def run(self, out): + """Run the actual command""" cmd = [] cmd.append('rsync') cmd.extend(self.options) for i in self.exclude: cmd.extend(['--exclude', i]) + out.output("Calculating total number of host files ...", False) dry_run = subprocess.Popen(cmd + ['-n', self.src, self.dest], shell=False, stdout=subprocess.PIPE, bufsize=0) - total = 0 - for line in iter(dry_run.stdout.readline, b''): - total += 1 + try: + total = 0 + for line in iter(dry_run.stdout.readline, b''): + total += 1 + finally: + dry_run.communicate() + if dry_run.returncode != 0: + raise FatalError("rsync failed") + + out.success("%d" % total) - progress = out.Progress(total, msg) + progress = out.Progress(total, "Copying files into the image ... ") run = subprocess.Popen(cmd + [self.src, self.dest], shell=False, stdout=subprocess.PIPE, bufsize=0) - for line in iter(run.stdout.readline, b''): - progress.next() + try: + t = time.time() + i = 0 + for line in iter(run.stdout.readline, b''): + i += 1 + current = time.time() + if current - t > 0.1: + t = current + progress.goto(i) + + progress.success('done') + + finally: + run.poll() + if run.returncode is None: + run.send_signal(signal.SIGHUP) + run.communicate() + if run.returncode != 0: + raise FatalError("rsync failed") - progress.success('done') # vim: set sta sts=4 shiftwidth=4 sw=4 et ai :