Revision d15368cc image_creator/rsync.py

b/image_creator/rsync.py
32 32
# or implied, of GRNET S.A.
33 33

  
34 34
import subprocess
35
import time
36
import signal
37

  
38
from image_creator.util import FatalError
35 39

  
36 40

  
37 41
class Rsync:
42
    """Wrapper class for the rsync command"""
43

  
38 44
    def __init__(self, src, dest, exclude=[]):
45
        """Create an instance by defining a source, a destinationa and a number
46
        of exclude patterns.
47
        """
39 48
        self.src = src
40 49
        self.dest = dest
41 50
        self.exclude = exclude
42 51
        self.options = ['-v']
43 52

  
44 53
    def archive(self):
54
        """Enable the archive option"""
45 55
        self.options.append('-a')
46 56
        return self
47 57

  
48
    def run(self, out, msg):
58
    def run(self, out):
59
        """Run the actual command"""
49 60
        cmd = []
50 61
        cmd.append('rsync')
51 62
        cmd.extend(self.options)
52 63
        for i in self.exclude:
53 64
            cmd.extend(['--exclude', i])
54 65

  
66
        out.output("Calculating total number of host files ...", False)
55 67
        dry_run = subprocess.Popen(cmd + ['-n', self.src, self.dest],
56 68
                                   shell=False, stdout=subprocess.PIPE,
57 69
                                   bufsize=0)
58
        total = 0
59
        for line in iter(dry_run.stdout.readline, b''):
60
            total += 1
70
        try:
71
            total = 0
72
            for line in iter(dry_run.stdout.readline, b''):
73
                total += 1
74
        finally:
75
            dry_run.communicate()
76
            if dry_run.returncode != 0:
77
                raise FatalError("rsync failed")
78

  
79
        out.success("%d" % total)
61 80

  
62
        progress = out.Progress(total, msg)
81
        progress = out.Progress(total, "Copying files into the image ... ")
63 82
        run = subprocess.Popen(cmd + [self.src, self.dest], shell=False,
64 83
                               stdout=subprocess.PIPE, bufsize=0)
65
        for line in iter(run.stdout.readline, b''):
66
            progress.next()
84
        try:
85
            t = time.time()
86
            i = 0
87
            for line in iter(run.stdout.readline, b''):
88
                i += 1
89
                current = time.time()
90
                if current - t > 0.1:
91
                    t = current
92
                    progress.goto(i)
93

  
94
            progress.success('done')
95

  
96
        finally:
97
            run.poll()
98
            if run.returncode is None:
99
                run.send_signal(signal.SIGHUP)
100
            run.communicate()
101
            if run.returncode != 0:
102
                raise FatalError("rsync failed")
67 103

  
68
        progress.success('done')
69 104

  
70 105
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :

Also available in: Unified diff