-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpscp
118 lines (100 loc) · 3.49 KB
/
pscp
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
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python
# -*- Mode: python -*-
# Copyright (c) 2009-2012, Andrew McNabb
# Copyright (c) 2003-2008, Brent N. Chun
# Modified 2012 by knktc
"""Parallel scp to the set of nodes in hosts.txt.
For each node, we essentially do a scp [-r] local user@host:remote. This
program also uses the -q (quiet) and -C (compression) options. Note that
remote must be an absolute path.
Modify note:
2012-5-5
I've delete some security parts in this tool, so that you can write a hosts.txt
with password in it. It is much convenient when you manage servers with different
password.
Remember! This modified tool is INSECURITY! You must take the RISK by yourself!
"""
import os
import re
import sys
from psshlib import psshutil
from psshlib.task import Task
from psshlib.manager import Manager, FatalError
from psshlib.cli import common_parser, common_defaults
def option_parser():
parser = common_parser()
parser.usage = "%prog [OPTIONS] local remote"
parser.epilog = ("Example: pscp -h hosts.txt -l irb2 foo.txt " +
"/home/irb2/foo.txt")
parser.add_option('-r', '--recursive', dest='recursive',
action='store_true', help='recusively copy directories (OPTIONAL)')
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 not opts.host_files and not opts.host_strings:
parser.error('Hosts not specified.')
return opts, args
def do_pscp(hosts, localargs, 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, password in hosts:
cmd = ['scp', '-qC', '-o',
'StrictHostKeyChecking=no']
if opts.options:
for opt in opts.options:
cmd += ['-o', opt]
if port:
cmd += ['-P', port]
if opts.recursive:
cmd.append('-r')
if opts.extra:
cmd.extend(opts.extra)
cmd.extend(localargs)
if user:
cmd.append('%s@%s:%s' % (user, host, remote))
else:
cmd.append('%s:%s' % (host, remote))
t = Task(host, port, user, password, cmd, opts)
manager.add_task(t)
try:
statuses = manager.run()
except FatalError:
sys.exit(1)
if min(statuses) < 0:
# At least one process was killed.
sys.exit(3)
for status in statuses:
if status != 0:
sys.exit(4)
if __name__ == "__main__":
opts, args = parse_args()
localargs = args[0:-1]
remote = args[-1]
if not re.match("^/", remote):
print("Remote path %s must be an absolute path" % remote)
sys.exit(3)
try:
hosts = psshutil.read_host_files(opts.host_files,
default_user=opts.user)
except IOError:
_, e, _ = sys.exc_info()
sys.stderr.write('Could not open hosts file: %s\n' % e.strerror)
sys.exit(1)
if opts.host_strings:
for s in opts.host_strings:
hosts.extend(psshutil.parse_host_string(s, default_user=opts.user))
#check if the hosts if empty
if hosts == []:
print "There are no hosts specified!"
sys.exit(1)
do_pscp(hosts, localargs, remote, opts)