File: prsync

package info (click to toggle)
pssh 2.1.1-1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 220 kB
  • ctags: 157
  • sloc: python: 1,369; makefile: 53; sh: 24
file content (109 lines) | stat: -rwxr-xr-x 3,471 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/env python
# -*- Mode: python -*-

# Copyright (c) 2009, Andrew McNabb
# Copyright (c) 2003-2008, Brent N. Chun

"""Parallel rsync to the set of nodes in hosts.txt.

For each node, we essentially do a rsync -rv -e ssh local user@host:remote.
Note that remote must be an absolute path.
"""

import os
import re
import sys

parent, bindir = os.path.split(os.path.dirname(os.path.abspath(sys.argv[0])))
if os.path.exists(os.path.join(parent, 'psshlib')):
    sys.path.insert(0, parent)

from psshlib import psshutil
from psshlib.task import Task
from psshlib.manager import Manager
from psshlib.cli import common_parser, common_defaults

def option_parser():
    parser = common_parser()
    parser.usage = "%prog [OPTIONS] -h hosts.txt local remote"
    parser.epilog = ("Example: prsync -r -h hosts.txt -l irb2 foo " +
          "/home/irb2/foo")

    parser.add_option('-r', '--recursive', dest='recursive',
            action='store_true', help='recusively copy directories (OPTIONAL)')
    parser.add_option('-a', '--archive', dest='archive', action='store_true',
            help='use rsync -a (archive mode) (OPTIONAL)')
    parser.add_option('-z', '--compress', dest='compress', action='store_true',
            help='use rsync compression (OPTIONAL)')
    parser.add_option('-S', '--ssh-args', metavar="ARGS", dest='ssh_args',
            action='store', help='extra arguments for ssh')

    return parser

def parse_args():
    parser = option_parser()
    defaults = common_defaults()
    parser.set_defaults(**defaults)
    opts, args = parser.parse_args()

    if len(args) < 1:
        parser.error('Paths not specified.')

    if len(args) < 2:
        parser.error('Remote path not specified.')

    if len(args) > 2:
        parser.error('Extra arguments given after the remote path.')

    if not opts.host_files and not opts.host_entries:
        parser.error('Hosts not specified.')

    return opts, args

def do_prsync(hosts, local, remote, opts):
    if opts.outdir and not os.path.exists(opts.outdir):
        os.makedirs(opts.outdir)
    if opts.errdir and not os.path.exists(opts.errdir):
        os.makedirs(opts.errdir)
    manager = Manager(opts)
    for host, port, user in hosts:
        ssh = ['ssh']
        if opts.options:
            ssh += ['-o', opts.options]
        if port:
            ssh += ['-p', port]
        if opts.ssh_args:
            ssh += opts.ssh_args

        cmd = ['rsync', '-e', ' '.join(ssh)]
        if opts.verbose:
            cmd.append('-v')
        if opts.recursive:
            cmd.append('-r')
        if opts.archive:
            cmd.append('-a')
        if opts.compress:
            cmd.append('-z')
        if opts.extra:
            cmd.extend(opts.extra)
        cmd.append(local)
        if user:
            cmd.append('%s@%s:%s' % (user, host, remote))
        else:
            cmd.append('%s:%s' % (host, remote))
        t = Task(host, port, user, cmd, opts)
        manager.add_task(t)
    manager.run()

if __name__ == "__main__":
    opts, args = parse_args()
    local = args[0]
    remote = args[1]
    if not re.match("^/", remote):
        print("Remote path %s must be an absolute path" % remote)
        sys.exit(3)
    hosts = psshutil.read_hosts(opts.host_files, default_user=opts.user)
    if opts.host_entries:
        for entry in opts.host_entries:
            hosts.append(psshutil.parse_host(entry, default_user=opts.user))
    do_prsync(hosts, local, remote, opts)