~ubuntu-branches/debian/stretch/s3ql/stretch

« back to all changes in this revision

Viewing changes to contrib/pcp.py

  • Committer: Bazaar Package Importer
  • Author(s): Nikolaus Rath
  • Date: 2011-07-01 14:02:17 UTC
  • Revision ID: james.westby@ubuntu.com-20110701140217-cyyclk7tusagxucf
Tags: upstream-1.0.1
ImportĀ upstreamĀ versionĀ 1.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
'''
 
3
pcp.py - this file is part of S3QL (http://s3ql.googlecode.com)
 
4
 
 
5
Parallel, recursive copy of directory trees.
 
6
 
 
7
---
 
8
Copyright (C) 2010 Nikolaus Rath <Nikolaus@rath.org>
 
9
 
 
10
This program can be distributed under the terms of the GNU LGPL.
 
11
'''
 
12
 
 
13
from __future__ import division, print_function, absolute_import
 
14
 
 
15
import sys
 
16
import os
 
17
import logging
 
18
import subprocess
 
19
 
 
20
# We are running from the S3QL source directory, make sure
 
21
# that we use modules from this directory
 
22
basedir = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..'))
 
23
if (os.path.exists(os.path.join(basedir, 'setup.py')) and
 
24
    os.path.exists(os.path.join(basedir, 'src', 's3ql', '__init__.py'))):
 
25
    sys.path = [os.path.join(basedir, 'src')] + sys.path
 
26
 
 
27
from s3ql.common import (setup_logging)
 
28
from s3ql.parse_args import ArgumentParser
 
29
 
 
30
log = logging.getLogger('pcp')
 
31
 
 
32
def parse_args(args):
 
33
    '''Parse command line'''
 
34
 
 
35
    parser = ArgumentParser(
 
36
        description='Recursively copy source(s) to destination using multiple '
 
37
                    'parallel rsync processes.')
 
38
 
 
39
    parser.add_quiet()
 
40
    parser.add_debug()
 
41
    parser.add_version()
 
42
    
 
43
    parser.add_argument("-a", action="store_true",
 
44
                      help='Pass -aHAX option to rsync.')      
 
45
    parser.add_argument("--processes", action="store", type=int, metavar='<no>',
 
46
                      default=10,
 
47
                      help='Number of rsync processes to use (default: %(default)s).')
 
48
    
 
49
    parser.add_argument('source', metavar='<source>', nargs='+',
 
50
                        help='Directories to copy')
 
51
    parser.add_argument('dest', metavar='<destination>',
 
52
                        help="Target directory")
 
53
    
 
54
    options = parser.parse_args(args)
 
55
    options.pps = options.source + [ options.dest ]
 
56
 
 
57
    return options
 
58
 
 
59
def main(args=None):
 
60
    if args is None:
 
61
        args = sys.argv[1:]
 
62
 
 
63
    options = parse_args(args)
 
64
    setup_logging(options)
 
65
 
 
66
    pool = ( 'abcdefghijklmnopqrstuvwxyz',
 
67
             'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
 
68
             '0123456789' )
 
69
    steps = [ len(x) / (options.processes-1) for x in pool ]
 
70
    prefixes = list()
 
71
    for i in range(options.processes - 1):
 
72
        parts = [ x[int(i*y):int((i+1)*y)] for (x, y) in zip(pool, steps) ]
 
73
        prefixes.append(''.join(parts))
 
74
 
 
75
    filters = [ '-! [%s]*' % x for x in prefixes ]
 
76
    
 
77
    # Catch all
 
78
    filters.append( '- [%s]*' % ''.join(prefixes))
 
79
        
 
80
    rsync_args = [ 'rsync', '-f', '+ */' ]
 
81
    if not options.quiet:
 
82
        rsync_args.append('--out-format')
 
83
        rsync_args.append('%n%L')
 
84
    if options.a:
 
85
        rsync_args.append('-aHAX')
 
86
    
 
87
    processes = list()
 
88
    for filter_ in filters:
 
89
        cmd = rsync_args + [ '-f', filter_ ] + options.pps
 
90
        log.debug('Calling %s', cmd)
 
91
        processes.append(subprocess.Popen(cmd))
 
92
        
 
93
    if all([ c.wait() == 0 for c in processes]):
 
94
        sys.exit(0)
 
95
    else:
 
96
        sys.exit(1)
 
97
    
 
98
 
 
99
if __name__ == '__main__':
 
100
    main(sys.argv[1:])
 
 
b'\\ No newline at end of file'