Statistics
| Branch: | Tag: | Revision:

root / image_creator / rsync.py @ d15368cc

History | View | Annotate | Download (3.6 kB)

1
# Copyright 2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
import subprocess
35
import time
36
import signal
37

    
38
from image_creator.util import FatalError
39

    
40

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

    
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
        """
48
        self.src = src
49
        self.dest = dest
50
        self.exclude = exclude
51
        self.options = ['-v']
52

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

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

    
66
        out.output("Calculating total number of host files ...", False)
67
        dry_run = subprocess.Popen(cmd + ['-n', self.src, self.dest],
68
                                   shell=False, stdout=subprocess.PIPE,
69
                                   bufsize=0)
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)
80

    
81
        progress = out.Progress(total, "Copying files into the image ... ")
82
        run = subprocess.Popen(cmd + [self.src, self.dest], shell=False,
83
                               stdout=subprocess.PIPE, bufsize=0)
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")
103

    
104

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