pec2 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +3 -1
- data/exe/bin/pnuke +96 -0
- data/exe/bin/prsync +126 -0
- data/exe/bin/pscp +108 -0
- data/exe/bin/pslurp +129 -0
- data/exe/bin/pssh +118 -0
- data/exe/bin/pssh-askpass +11 -0
- data/exe/man/man1/pnuke.1 +268 -0
- data/exe/man/man1/prsync.1 +299 -0
- data/exe/man/man1/pscp.1 +271 -0
- data/exe/man/man1/pslurp.1 +280 -0
- data/exe/man/man1/pssh.1 +368 -0
- data/exe/psshlib/__init__.py +0 -0
- data/exe/psshlib/askpass_client.py +102 -0
- data/exe/psshlib/askpass_server.py +101 -0
- data/exe/psshlib/cli.py +110 -0
- data/exe/psshlib/color.py +39 -0
- data/exe/psshlib/manager.py +345 -0
- data/exe/psshlib/psshutil.py +108 -0
- data/exe/psshlib/task.py +288 -0
- data/exe/psshlib/version.py +1 -0
- data/lib/pec2/cli.rb +8 -4
- data/lib/pec2/core.rb +1 -1
- data/lib/pec2/version.rb +1 -1
- data/pec2.gemspec +1 -1
- metadata +25 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb281220d6b29ff7d3fee0f3f981680855d5cc08
|
4
|
+
data.tar.gz: de60d8338782ebc4214835e90aba81d7171b0959
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '08a9d23eb9c518f2fd8edc23f19fc5f5077a83626545c40331e202e680f98606547e9c9ceb666013b4e92f754459f53a88a9f97a4f804c25ad31f4255996baff'
|
7
|
+
data.tar.gz: b65d6d2e8b3f7f6a395e1cbd9d1a75b47d28eb828a1af7d49a33c9391eabe04ef309ca9bb6e8320822e4cfbbdf8baaf30d7e99da816928dcb968f1bc7ae8a26f
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -4,6 +4,8 @@ Run parallel ssh command for ec2.
|
|
4
4
|
|
5
5
|
Commands can run to multiple hosts at once using the ec2 tag.
|
6
6
|
|
7
|
+
required python.
|
8
|
+
|
7
9
|
## Examples
|
8
10
|
|
9
11
|
$ bundle exec pec2 -t Project:project_a Stages:production -c 'hostname'
|
@@ -12,7 +14,7 @@ Commands can run to multiple hosts at once using the ec2 tag.
|
|
12
14
|
|
13
15
|
$ bundle exec pec2 -t Project:project_a Stages:production -c 'sudo hostname' -P -s ${sudo_password}
|
14
16
|
|
15
|
-
## Parallel number control
|
17
|
+
## Parallel number control(150 threads)
|
16
18
|
|
17
19
|
$ bundle exec pec2 -t Project:embulk Stages:production -c 'hostname' -P -p 150
|
18
20
|
|
data/exe/bin/pnuke
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- Mode: python -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2009-2012, Andrew McNabb
|
5
|
+
# Copyright (c) 2003-2008, Brent N. Chun
|
6
|
+
|
7
|
+
"""Nukes all processes that match pattern running as user on the set of nodes
|
8
|
+
in hosts.txt.
|
9
|
+
"""
|
10
|
+
|
11
|
+
import os
|
12
|
+
import sys
|
13
|
+
|
14
|
+
parent, bindir = os.path.split(os.path.dirname(os.path.abspath(sys.argv[0])))
|
15
|
+
if os.path.exists(os.path.join(parent, 'psshlib')):
|
16
|
+
sys.path.insert(0, parent)
|
17
|
+
|
18
|
+
from psshlib import psshutil
|
19
|
+
from psshlib.task import Task
|
20
|
+
from psshlib.manager import Manager, FatalError
|
21
|
+
from psshlib.cli import common_parser, common_defaults
|
22
|
+
|
23
|
+
_DEFAULT_TIMEOUT = 60
|
24
|
+
|
25
|
+
def option_parser():
|
26
|
+
parser = common_parser()
|
27
|
+
parser.usage = "%prog [OPTIONS] pattern"
|
28
|
+
parser.epilog = "Example: pnuke -h hosts.txt -l irb2 java"
|
29
|
+
return parser
|
30
|
+
|
31
|
+
def parse_args():
|
32
|
+
parser = option_parser()
|
33
|
+
defaults = common_defaults(timeout=_DEFAULT_TIMEOUT)
|
34
|
+
parser.set_defaults(**defaults)
|
35
|
+
opts, args = parser.parse_args()
|
36
|
+
|
37
|
+
if len(args) < 1:
|
38
|
+
parser.error('Pattern not specified.')
|
39
|
+
|
40
|
+
if len(args) > 1:
|
41
|
+
parser.error('Extra arguments given after the pattern.')
|
42
|
+
|
43
|
+
if not opts.host_files and not opts.host_strings:
|
44
|
+
parser.error('Hosts not specified.')
|
45
|
+
|
46
|
+
return opts, args
|
47
|
+
|
48
|
+
def do_pnuke(hosts, pattern, opts):
|
49
|
+
if opts.outdir and not os.path.exists(opts.outdir):
|
50
|
+
os.makedirs(opts.outdir)
|
51
|
+
if opts.errdir and not os.path.exists(opts.errdir):
|
52
|
+
os.makedirs(opts.errdir)
|
53
|
+
manager = Manager(opts)
|
54
|
+
for host, port, user in hosts:
|
55
|
+
cmd = ['ssh', host, '-o', 'NumberOfPasswordPrompts=1']
|
56
|
+
if opts.options:
|
57
|
+
for opt in opts.options:
|
58
|
+
cmd += ['-o', opt]
|
59
|
+
if user:
|
60
|
+
cmd += ['-l', user]
|
61
|
+
if port:
|
62
|
+
cmd += ['-p', port]
|
63
|
+
if opts.extra:
|
64
|
+
cmd.extend(opts.extra)
|
65
|
+
cmd.append('pkill -9 %s' % pattern)
|
66
|
+
t = Task(host, port, user, cmd, opts)
|
67
|
+
manager.add_task(t)
|
68
|
+
try:
|
69
|
+
statuses = manager.run()
|
70
|
+
except FatalError:
|
71
|
+
sys.exit(1)
|
72
|
+
|
73
|
+
if min(statuses) < 0:
|
74
|
+
# At least one process was killed.
|
75
|
+
sys.exit(3)
|
76
|
+
for status in statuses:
|
77
|
+
if status == 255:
|
78
|
+
sys.exit(4)
|
79
|
+
for status in statuses:
|
80
|
+
if status != 0:
|
81
|
+
sys.exit(5)
|
82
|
+
|
83
|
+
if __name__ == "__main__":
|
84
|
+
opts, args = parse_args()
|
85
|
+
pattern = args[0]
|
86
|
+
try:
|
87
|
+
hosts = psshutil.read_host_files(opts.host_files,
|
88
|
+
default_user=opts.user)
|
89
|
+
except IOError:
|
90
|
+
_, e, _ = sys.exc_info()
|
91
|
+
sys.stderr.write('Could not open hosts file: %s\n' % e.strerror)
|
92
|
+
sys.exit(1)
|
93
|
+
if opts.host_strings:
|
94
|
+
for s in opts.host_strings:
|
95
|
+
hosts.extend(psshutil.parse_host_string(s, default_user=opts.user))
|
96
|
+
do_pnuke(hosts, pattern, opts)
|
data/exe/bin/prsync
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- Mode: python -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2009-2012, Andrew McNabb
|
5
|
+
# Copyright (c) 2003-2008, Brent N. Chun
|
6
|
+
|
7
|
+
"""Parallel rsync to the set of nodes in hosts.txt.
|
8
|
+
|
9
|
+
For each node, we essentially do a rsync -rv -e ssh local user@host:remote.
|
10
|
+
Note that remote must be an absolute path.
|
11
|
+
"""
|
12
|
+
|
13
|
+
import os
|
14
|
+
import re
|
15
|
+
import sys
|
16
|
+
|
17
|
+
parent, bindir = os.path.split(os.path.dirname(os.path.abspath(sys.argv[0])))
|
18
|
+
if os.path.exists(os.path.join(parent, 'psshlib')):
|
19
|
+
sys.path.insert(0, parent)
|
20
|
+
|
21
|
+
from psshlib import psshutil
|
22
|
+
from psshlib.task import Task
|
23
|
+
from psshlib.manager import Manager, FatalError
|
24
|
+
from psshlib.cli import common_parser, common_defaults
|
25
|
+
|
26
|
+
def option_parser():
|
27
|
+
parser = common_parser()
|
28
|
+
parser.usage = "%prog [OPTIONS] local remote"
|
29
|
+
parser.epilog = ("Example: prsync -r -h hosts.txt -l irb2 foo " +
|
30
|
+
"/home/irb2/foo")
|
31
|
+
|
32
|
+
parser.add_option('-r', '--recursive', dest='recursive',
|
33
|
+
action='store_true', help='recusively copy directories (OPTIONAL)')
|
34
|
+
parser.add_option('-a', '--archive', dest='archive', action='store_true',
|
35
|
+
help='use rsync -a (archive mode) (OPTIONAL)')
|
36
|
+
parser.add_option('-z', '--compress', dest='compress', action='store_true',
|
37
|
+
help='use rsync compression (OPTIONAL)')
|
38
|
+
parser.add_option('-S', '--ssh-args', metavar="ARGS", dest='ssh_args',
|
39
|
+
action='store', help='extra arguments for ssh')
|
40
|
+
|
41
|
+
return parser
|
42
|
+
|
43
|
+
def parse_args():
|
44
|
+
parser = option_parser()
|
45
|
+
defaults = common_defaults()
|
46
|
+
parser.set_defaults(**defaults)
|
47
|
+
opts, args = parser.parse_args()
|
48
|
+
|
49
|
+
if len(args) < 1:
|
50
|
+
parser.error('Paths not specified.')
|
51
|
+
|
52
|
+
if len(args) < 2:
|
53
|
+
parser.error('Remote path not specified.')
|
54
|
+
|
55
|
+
if len(args) > 2:
|
56
|
+
parser.error('Extra arguments given after the remote path.')
|
57
|
+
|
58
|
+
if not opts.host_files and not opts.host_strings:
|
59
|
+
parser.error('Hosts not specified.')
|
60
|
+
|
61
|
+
return opts, args
|
62
|
+
|
63
|
+
def do_prsync(hosts, local, remote, opts):
|
64
|
+
if opts.outdir and not os.path.exists(opts.outdir):
|
65
|
+
os.makedirs(opts.outdir)
|
66
|
+
if opts.errdir and not os.path.exists(opts.errdir):
|
67
|
+
os.makedirs(opts.errdir)
|
68
|
+
manager = Manager(opts)
|
69
|
+
for host, port, user in hosts:
|
70
|
+
ssh = ['ssh']
|
71
|
+
if opts.options:
|
72
|
+
for opt in opts.options:
|
73
|
+
ssh += ['-o', opt]
|
74
|
+
if port:
|
75
|
+
ssh += ['-p', port]
|
76
|
+
if opts.ssh_args:
|
77
|
+
ssh += [opts.ssh_args]
|
78
|
+
|
79
|
+
cmd = ['rsync', '-e', ' '.join(ssh)]
|
80
|
+
if opts.verbose:
|
81
|
+
cmd.append('-v')
|
82
|
+
if opts.recursive:
|
83
|
+
cmd.append('-r')
|
84
|
+
if opts.archive:
|
85
|
+
cmd.append('-a')
|
86
|
+
if opts.compress:
|
87
|
+
cmd.append('-z')
|
88
|
+
if opts.extra:
|
89
|
+
cmd.extend(opts.extra)
|
90
|
+
cmd.append(local)
|
91
|
+
if user:
|
92
|
+
cmd.append('%s@%s:%s' % (user, host, remote))
|
93
|
+
else:
|
94
|
+
cmd.append('%s:%s' % (host, remote))
|
95
|
+
t = Task(host, port, user, cmd, opts)
|
96
|
+
manager.add_task(t)
|
97
|
+
try:
|
98
|
+
statuses = manager.run()
|
99
|
+
except FatalError:
|
100
|
+
sys.exit(1)
|
101
|
+
|
102
|
+
if min(statuses) < 0:
|
103
|
+
# At least one process was killed.
|
104
|
+
sys.exit(3)
|
105
|
+
for status in statuses:
|
106
|
+
if status != 0:
|
107
|
+
sys.exit(4)
|
108
|
+
|
109
|
+
if __name__ == "__main__":
|
110
|
+
opts, args = parse_args()
|
111
|
+
local = args[0]
|
112
|
+
remote = args[1]
|
113
|
+
if not re.match("^/", remote):
|
114
|
+
print("Remote path %s must be an absolute path" % remote)
|
115
|
+
sys.exit(3)
|
116
|
+
try:
|
117
|
+
hosts = psshutil.read_host_files(opts.host_files,
|
118
|
+
default_user=opts.user)
|
119
|
+
except IOError:
|
120
|
+
_, e, _ = sys.exc_info()
|
121
|
+
sys.stderr.write('Could not open hosts file: %s\n' % e.strerror)
|
122
|
+
sys.exit(1)
|
123
|
+
if opts.host_strings:
|
124
|
+
for s in opts.host_strings:
|
125
|
+
hosts.extend(psshutil.parse_host_string(s, default_user=opts.user))
|
126
|
+
do_prsync(hosts, local, remote, opts)
|
data/exe/bin/pscp
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- Mode: python -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2009-2012, Andrew McNabb
|
5
|
+
# Copyright (c) 2003-2008, Brent N. Chun
|
6
|
+
|
7
|
+
"""Parallel scp to the set of nodes in hosts.txt.
|
8
|
+
|
9
|
+
For each node, we essentially do a scp [-r] local user@host:remote. This
|
10
|
+
program also uses the -q (quiet) and -C (compression) options. Note that
|
11
|
+
remote must be an absolute path.
|
12
|
+
"""
|
13
|
+
|
14
|
+
import os
|
15
|
+
import re
|
16
|
+
import sys
|
17
|
+
|
18
|
+
parent, bindir = os.path.split(os.path.dirname(os.path.abspath(sys.argv[0])))
|
19
|
+
if os.path.exists(os.path.join(parent, 'psshlib')):
|
20
|
+
sys.path.insert(0, parent)
|
21
|
+
|
22
|
+
from psshlib import psshutil
|
23
|
+
from psshlib.task import Task
|
24
|
+
from psshlib.manager import Manager, FatalError
|
25
|
+
from psshlib.cli import common_parser, common_defaults
|
26
|
+
|
27
|
+
def option_parser():
|
28
|
+
parser = common_parser()
|
29
|
+
parser.usage = "%prog [OPTIONS] local remote"
|
30
|
+
parser.epilog = ("Example: pscp -h hosts.txt -l irb2 foo.txt " +
|
31
|
+
"/home/irb2/foo.txt")
|
32
|
+
|
33
|
+
parser.add_option('-r', '--recursive', dest='recursive',
|
34
|
+
action='store_true', help='recusively copy directories (OPTIONAL)')
|
35
|
+
|
36
|
+
return parser
|
37
|
+
|
38
|
+
def parse_args():
|
39
|
+
parser = option_parser()
|
40
|
+
defaults = common_defaults()
|
41
|
+
parser.set_defaults(**defaults)
|
42
|
+
opts, args = parser.parse_args()
|
43
|
+
|
44
|
+
if len(args) < 1:
|
45
|
+
parser.error('Paths not specified.')
|
46
|
+
|
47
|
+
if len(args) < 2:
|
48
|
+
parser.error('Remote path not specified.')
|
49
|
+
|
50
|
+
if not opts.host_files and not opts.host_strings:
|
51
|
+
parser.error('Hosts not specified.')
|
52
|
+
|
53
|
+
return opts, args
|
54
|
+
|
55
|
+
def do_pscp(hosts, localargs, remote, opts):
|
56
|
+
if opts.outdir and not os.path.exists(opts.outdir):
|
57
|
+
os.makedirs(opts.outdir)
|
58
|
+
if opts.errdir and not os.path.exists(opts.errdir):
|
59
|
+
os.makedirs(opts.errdir)
|
60
|
+
manager = Manager(opts)
|
61
|
+
for host, port, user in hosts:
|
62
|
+
cmd = ['scp', '-qC']
|
63
|
+
if opts.options:
|
64
|
+
for opt in opts.options:
|
65
|
+
cmd += ['-o', opt]
|
66
|
+
if port:
|
67
|
+
cmd += ['-P', port]
|
68
|
+
if opts.recursive:
|
69
|
+
cmd.append('-r')
|
70
|
+
if opts.extra:
|
71
|
+
cmd.extend(opts.extra)
|
72
|
+
cmd.extend(localargs)
|
73
|
+
if user:
|
74
|
+
cmd.append('%s@%s:%s' % (user, host, remote))
|
75
|
+
else:
|
76
|
+
cmd.append('%s:%s' % (host, remote))
|
77
|
+
t = Task(host, port, user, cmd, opts)
|
78
|
+
manager.add_task(t)
|
79
|
+
try:
|
80
|
+
statuses = manager.run()
|
81
|
+
except FatalError:
|
82
|
+
sys.exit(1)
|
83
|
+
|
84
|
+
if min(statuses) < 0:
|
85
|
+
# At least one process was killed.
|
86
|
+
sys.exit(3)
|
87
|
+
for status in statuses:
|
88
|
+
if status != 0:
|
89
|
+
sys.exit(4)
|
90
|
+
|
91
|
+
if __name__ == "__main__":
|
92
|
+
opts, args = parse_args()
|
93
|
+
localargs = args[0:-1]
|
94
|
+
remote = args[-1]
|
95
|
+
if not re.match("^/", remote):
|
96
|
+
print("Remote path %s must be an absolute path" % remote)
|
97
|
+
sys.exit(3)
|
98
|
+
try:
|
99
|
+
hosts = psshutil.read_host_files(opts.host_files,
|
100
|
+
default_user=opts.user)
|
101
|
+
except IOError:
|
102
|
+
_, e, _ = sys.exc_info()
|
103
|
+
sys.stderr.write('Could not open hosts file: %s\n' % e.strerror)
|
104
|
+
sys.exit(1)
|
105
|
+
if opts.host_strings:
|
106
|
+
for s in opts.host_strings:
|
107
|
+
hosts.extend(psshutil.parse_host_string(s, default_user=opts.user))
|
108
|
+
do_pscp(hosts, localargs, remote, opts)
|
data/exe/bin/pslurp
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- Mode: python -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2009-2012, Andrew McNabb
|
5
|
+
# Copyright (c) 2003-2008, Brent N. Chun
|
6
|
+
|
7
|
+
"""Parallel scp from the set of nodes in hosts.txt.
|
8
|
+
|
9
|
+
For each node, we essentially do a scp [-r] user@host:remote
|
10
|
+
outdir/<node>/local. This program also uses the -q (quiet) and -C
|
11
|
+
(compression) options. Note that remote must be an absolute path.
|
12
|
+
"""
|
13
|
+
|
14
|
+
import os
|
15
|
+
import re
|
16
|
+
import sys
|
17
|
+
|
18
|
+
parent, bindir = os.path.split(os.path.dirname(os.path.abspath(sys.argv[0])))
|
19
|
+
if os.path.exists(os.path.join(parent, 'psshlib')):
|
20
|
+
sys.path.insert(0, parent)
|
21
|
+
|
22
|
+
from psshlib import psshutil
|
23
|
+
from psshlib.task import Task
|
24
|
+
from psshlib.manager import Manager, FatalError
|
25
|
+
from psshlib.cli import common_parser, common_defaults
|
26
|
+
|
27
|
+
def option_parser():
|
28
|
+
parser = common_parser()
|
29
|
+
parser.usage = "%prog [OPTIONS] remote local"
|
30
|
+
parser.epilog = ("Example: pslurp -h hosts.txt -L /tmp/outdir -l irb2 " +
|
31
|
+
" /home/irb2/foo.txt foo.txt")
|
32
|
+
|
33
|
+
parser.add_option('-r', '--recursive', dest='recursive',
|
34
|
+
action='store_true', help='recusively copy directories (OPTIONAL)')
|
35
|
+
parser.add_option('-L', '--localdir', dest='localdir',
|
36
|
+
help='output directory for remote file copies')
|
37
|
+
|
38
|
+
return parser
|
39
|
+
|
40
|
+
def parse_args():
|
41
|
+
parser = option_parser()
|
42
|
+
defaults = common_defaults()
|
43
|
+
parser.set_defaults(**defaults)
|
44
|
+
opts, args = parser.parse_args()
|
45
|
+
|
46
|
+
if len(args) < 1:
|
47
|
+
parser.error('Paths not specified.')
|
48
|
+
|
49
|
+
if len(args) < 2:
|
50
|
+
parser.error('Local path not specified.')
|
51
|
+
|
52
|
+
if len(args) > 2:
|
53
|
+
parser.error('Extra arguments given after the local path.')
|
54
|
+
|
55
|
+
if not opts.host_files and not opts.host_strings:
|
56
|
+
parser.error('Hosts not specified.')
|
57
|
+
|
58
|
+
return opts, args
|
59
|
+
|
60
|
+
def do_pslurp(hosts, remote, local, opts):
|
61
|
+
if opts.localdir and not os.path.exists(opts.localdir):
|
62
|
+
os.makedirs(opts.localdir)
|
63
|
+
if opts.outdir and not os.path.exists(opts.outdir):
|
64
|
+
os.makedirs(opts.outdir)
|
65
|
+
if opts.errdir and not os.path.exists(opts.errdir):
|
66
|
+
os.makedirs(opts.errdir)
|
67
|
+
for host, port, user in hosts:
|
68
|
+
if opts.localdir:
|
69
|
+
dirname = "%s/%s" % (opts.localdir, host)
|
70
|
+
else:
|
71
|
+
dirname = host
|
72
|
+
if not os.path.exists(dirname):
|
73
|
+
os.mkdir(dirname)
|
74
|
+
manager = Manager(opts)
|
75
|
+
for host, port, user in hosts:
|
76
|
+
if opts.localdir:
|
77
|
+
localpath = "%s/%s/%s" % (opts.localdir, host, local)
|
78
|
+
else:
|
79
|
+
localpath = "%s/%s" % (host, local)
|
80
|
+
cmd = ['scp', '-qC']
|
81
|
+
if opts.options:
|
82
|
+
for opt in opts.options:
|
83
|
+
cmd += ['-o', opt]
|
84
|
+
if port:
|
85
|
+
cmd += ['-P', port]
|
86
|
+
if opts.recursive:
|
87
|
+
cmd.append('-r')
|
88
|
+
if opts.extra:
|
89
|
+
cmd.extend(opts.extra)
|
90
|
+
if user:
|
91
|
+
cmd.append('%s@%s:%s' % (user, host, remote))
|
92
|
+
else:
|
93
|
+
cmd.append('%s:%s' % (host, remote))
|
94
|
+
cmd.append(localpath)
|
95
|
+
t = Task(host, port, user, cmd, opts)
|
96
|
+
manager.add_task(t)
|
97
|
+
try:
|
98
|
+
statuses = manager.run()
|
99
|
+
except FatalError:
|
100
|
+
sys.exit(1)
|
101
|
+
|
102
|
+
if min(statuses) < 0:
|
103
|
+
# At least one process was killed.
|
104
|
+
sys.exit(3)
|
105
|
+
for status in statuses:
|
106
|
+
if status == 255:
|
107
|
+
sys.exit(4)
|
108
|
+
for status in statuses:
|
109
|
+
if status != 0:
|
110
|
+
sys.exit(5)
|
111
|
+
|
112
|
+
if __name__ == "__main__":
|
113
|
+
opts, args = parse_args()
|
114
|
+
remote = args[0]
|
115
|
+
local = args[1]
|
116
|
+
if not re.match("^/", remote):
|
117
|
+
print("Remote path %s must be an absolute path" % remote)
|
118
|
+
sys.exit(3)
|
119
|
+
try:
|
120
|
+
hosts = psshutil.read_host_files(opts.host_files,
|
121
|
+
default_user=opts.user)
|
122
|
+
except IOError:
|
123
|
+
_, e, _ = sys.exc_info()
|
124
|
+
sys.stderr.write('Could not open hosts file: %s\n' % e.strerror)
|
125
|
+
sys.exit(1)
|
126
|
+
if opts.host_strings:
|
127
|
+
for s in opts.host_strings:
|
128
|
+
hosts.extend(psshutil.parse_host_string(s, default_user=opts.user))
|
129
|
+
do_pslurp(hosts, remote, local, opts)
|