pec2 0.5.1 → 0.6.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/lib/pec2/cli.rb +1 -9
- data/lib/pec2/pssh.rb +58 -28
- data/lib/pec2/version.rb +1 -1
- data/pec2.gemspec +4 -1
- data/spec/cli_spec.rb +0 -1
- data/spec/pssh_spec.rb +1 -54
- metadata +46 -24
- data/exe/bin/pnuke +0 -96
- data/exe/bin/prsync +0 -126
- data/exe/bin/pscp +0 -108
- data/exe/bin/pslurp +0 -129
- data/exe/bin/pssh +0 -118
- data/exe/bin/pssh-askpass +0 -11
- data/exe/man/man1/pnuke.1 +0 -268
- data/exe/man/man1/prsync.1 +0 -299
- data/exe/man/man1/pscp.1 +0 -271
- data/exe/man/man1/pslurp.1 +0 -280
- data/exe/man/man1/pssh.1 +0 -368
- data/exe/psshlib/__init__.py +0 -0
- data/exe/psshlib/askpass_client.py +0 -102
- data/exe/psshlib/askpass_server.py +0 -101
- data/exe/psshlib/cli.py +0 -110
- data/exe/psshlib/color.py +0 -39
- data/exe/psshlib/manager.py +0 -345
- data/exe/psshlib/psshutil.py +0 -108
- data/exe/psshlib/task.py +0 -288
- data/exe/psshlib/version.py +0 -1
data/exe/bin/prsync
DELETED
@@ -1,126 +0,0 @@
|
|
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
DELETED
@@ -1,108 +0,0 @@
|
|
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
DELETED
@@ -1,129 +0,0 @@
|
|
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)
|
data/exe/bin/pssh
DELETED
@@ -1,118 +0,0 @@
|
|
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 ssh to the set of nodes in hosts.txt.
|
8
|
-
|
9
|
-
For each node, this essentially does an "ssh host -l user prog [arg0] [arg1]
|
10
|
-
...". The -o option can be used to store stdout from each remote node in a
|
11
|
-
directory. Each output file in that directory will be named by the
|
12
|
-
corresponding remote node's hostname or IP address.
|
13
|
-
"""
|
14
|
-
|
15
|
-
import fcntl
|
16
|
-
import os
|
17
|
-
import sys
|
18
|
-
|
19
|
-
parent, bindir = os.path.split(os.path.dirname(os.path.abspath(sys.argv[0])))
|
20
|
-
if os.path.exists(os.path.join(parent, 'psshlib')):
|
21
|
-
sys.path.insert(0, parent)
|
22
|
-
|
23
|
-
from psshlib import psshutil
|
24
|
-
from psshlib.manager import Manager, FatalError
|
25
|
-
from psshlib.task import Task
|
26
|
-
from psshlib.cli import common_parser, common_defaults
|
27
|
-
|
28
|
-
_DEFAULT_TIMEOUT = 60
|
29
|
-
|
30
|
-
def option_parser():
|
31
|
-
parser = common_parser()
|
32
|
-
parser.usage = "%prog [OPTIONS] command [...]"
|
33
|
-
parser.epilog = "Example: pssh -h hosts.txt -l irb2 -o /tmp/foo uptime"
|
34
|
-
|
35
|
-
parser.add_option('-i', '--inline', dest='inline', action='store_true',
|
36
|
-
help='inline aggregated output and error for each server')
|
37
|
-
parser.add_option('--inline-stdout', dest='inline_stdout',
|
38
|
-
action='store_true',
|
39
|
-
help='inline standard output for each server')
|
40
|
-
parser.add_option('-I', '--send-input', dest='send_input',
|
41
|
-
action='store_true',
|
42
|
-
help='read from standard input and send as input to ssh')
|
43
|
-
parser.add_option('-P', '--print', dest='print_out', action='store_true',
|
44
|
-
help='print output as we get it')
|
45
|
-
|
46
|
-
return parser
|
47
|
-
|
48
|
-
def parse_args():
|
49
|
-
parser = option_parser()
|
50
|
-
defaults = common_defaults(timeout=_DEFAULT_TIMEOUT)
|
51
|
-
parser.set_defaults(**defaults)
|
52
|
-
opts, args = parser.parse_args()
|
53
|
-
|
54
|
-
if len(args) == 0 and not opts.send_input:
|
55
|
-
parser.error('Command not specified.')
|
56
|
-
|
57
|
-
if not opts.host_files and not opts.host_strings:
|
58
|
-
parser.error('Hosts not specified.')
|
59
|
-
|
60
|
-
return opts, args
|
61
|
-
|
62
|
-
def do_pssh(hosts, cmdline, opts):
|
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
|
-
if opts.send_input:
|
68
|
-
stdin = sys.stdin.read()
|
69
|
-
else:
|
70
|
-
stdin = None
|
71
|
-
manager = Manager(opts)
|
72
|
-
for host, port, user in hosts:
|
73
|
-
cmd = ['ssh', host, '-o', 'NumberOfPasswordPrompts=1',
|
74
|
-
'-o', 'SendEnv=PSSH_NODENUM PSSH_HOST']
|
75
|
-
if opts.options:
|
76
|
-
for opt in opts.options:
|
77
|
-
cmd += ['-o', opt]
|
78
|
-
if user:
|
79
|
-
cmd += ['-l', user]
|
80
|
-
if port:
|
81
|
-
cmd += ['-p', port]
|
82
|
-
if opts.extra:
|
83
|
-
cmd.extend(opts.extra)
|
84
|
-
if cmdline:
|
85
|
-
cmd.append(cmdline)
|
86
|
-
t = Task(host, port, user, cmd, opts, stdin)
|
87
|
-
manager.add_task(t)
|
88
|
-
try:
|
89
|
-
statuses = manager.run()
|
90
|
-
except FatalError:
|
91
|
-
sys.exit(1)
|
92
|
-
|
93
|
-
if min(statuses) < 0:
|
94
|
-
# At least one process was killed.
|
95
|
-
sys.exit(3)
|
96
|
-
# The any builtin was introduced in Python 2.5 (so we can't use it yet):
|
97
|
-
#elif any(x==255 for x in statuses):
|
98
|
-
for status in statuses:
|
99
|
-
if status == 255:
|
100
|
-
sys.exit(4)
|
101
|
-
for status in statuses:
|
102
|
-
if status != 0:
|
103
|
-
sys.exit(5)
|
104
|
-
|
105
|
-
if __name__ == "__main__":
|
106
|
-
opts, args = parse_args()
|
107
|
-
cmdline = " ".join(args)
|
108
|
-
try:
|
109
|
-
hosts = psshutil.read_host_files(opts.host_files,
|
110
|
-
default_user=opts.user)
|
111
|
-
except IOError:
|
112
|
-
_, e, _ = sys.exc_info()
|
113
|
-
sys.stderr.write('Could not open hosts file: %s\n' % e.strerror)
|
114
|
-
sys.exit(1)
|
115
|
-
if opts.host_strings:
|
116
|
-
for s in opts.host_strings:
|
117
|
-
hosts.extend(psshutil.parse_host_string(s, default_user=opts.user))
|
118
|
-
do_pssh(hosts, cmdline, opts)
|