Left: | ||
Right: |
OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # coding: utf-8 | 2 # coding: utf-8 |
3 | 3 |
4 import argparse | |
4 import sys | 5 import sys |
5 import os | 6 import os |
6 import re | 7 import re |
7 import subprocess | 8 import subprocess |
8 import getopt | 9 import getopt |
9 import yaml | 10 import yaml |
10 | 11 |
11 def usage(): | 12 def createArgumentParser(**kwargs): |
12 print >>sys.stderr, ''' | 13 parser = argparse.ArgumentParser(**kwargs) |
13 Usage: %s [-u <user>] [-h <host>|<group>] [-i] ... <command> | 14 parser.add_argument( |
15 '-u', metavar='<user>', dest='user', type=str, default='vagrant', | |
16 help='user name for use with SSH, must exist on all hosts' | |
17 ) | |
14 | 18 |
15 Runs a command on the given hosts or groups of hosts. | 19 parser.add_argument( |
20 '-?', action='help', | |
21 help='print this message and exit' | |
22 ) | |
16 | 23 |
Wladimir Palant
2015/04/07 14:58:04
This is just wrong...
1) This assumes add_help=Fa
mathias
2015/04/07 15:36:51
I just tried to stay consistent with the existing
| |
17 Options: | 24 return parser |
18 -u <user> User name to use with the SSH command | |
19 -h <host|group> Host or group to run the command on (can be specified multiple times) | |
20 -i If specified, command will be executed on all hosts despite er rors | |
21 ''' % sys.argv[0] | |
22 | 25 |
23 def parseOptions(args): | 26 def parseOptions(args): |
24 try: | 27 description = "Run a command on the given hosts or groups of hosts" |
Wladimir Palant
2015/04/07 14:58:04
Nit: single quotes, for consistency.
mathias
2015/04/07 15:36:51
Done.
| |
25 options, args = getopt.getopt(args, 'u:h:i') | 28 parser = createArgumentParser(description=description, add_help=False) |
26 except getopt.GetoptError, e: | 29 parser.add_argument( |
27 print >>sys.stderr, e | 30 '-i', action='store_true', dest='ignore_errors', |
28 usage() | 31 help='continue execution on next host in case of an error' |
29 sys.exit(1) | 32 ) |
30 | 33 |
31 user = None | 34 hosts = set() |
32 hosts = [] | 35 parser.add_argument( |
33 ignore_errors = False | 36 '-h', metavar='<host|group>', |
34 for option, value in options: | 37 help='target host or group, can be specified multiple times', |
35 if option == '-u': | 38 type=lambda value: hosts.update((value,)) |
Wladimir Palant
2015/04/07 14:58:04
Nit: I think this should be a list semantically -
mathias
2015/04/07 15:36:51
Done.
| |
36 user = value | 39 ) |
37 elif option == '-h': | |
38 hosts.append(value) | |
39 elif option == '-i': | |
40 ignore_errors = True | |
41 | 40 |
42 return user, hosts, ignore_errors, args | 41 parser.add_argument( |
42 'args', metavar='command', type=str, nargs='+', | |
43 help='The command to run on the specified hosts' | |
44 ) | |
43 | 45 |
46 options = parser.parse_args(args) | |
47 options.hosts = hosts | |
48 return options | |
44 | 49 |
45 def getValidHosts(): | 50 def getValidHosts(): |
46 dirname = os.path.dirname(sys.argv[0]) | 51 dirname = os.path.dirname(sys.argv[0]) |
47 path_name = os.path.join(dirname, "modules", "private", "hiera", "hosts.yaml") | 52 path_name = os.path.join(dirname, "modules", "private", "hiera", "hosts.yaml") |
48 with open(path_name, 'rb') as handle: | 53 with open(path_name, 'rb') as handle: |
49 config = yaml.load(handle) | 54 config = yaml.load(handle) |
50 servers = config.get('servers', {}) | 55 servers = config.get('servers', {}) |
51 return servers | 56 return servers |
52 | 57 |
53 def resolveHostList(hosts): | 58 def resolveHostList(hosts): |
(...skipping 26 matching lines...) Expand all Loading... | |
80 def runCommand(user, host, command, ignore_errors=False): | 85 def runCommand(user, host, command, ignore_errors=False): |
81 if not isinstance(command, list): | 86 if not isinstance(command, list): |
82 command = [command] | 87 command = [command] |
83 command = ["ssh"] + (["-l", user] if user else []) + [host] + command | 88 command = ["ssh"] + (["-l", user] if user else []) + [host] + command |
84 if ignore_errors: | 89 if ignore_errors: |
85 subprocess.call(command) | 90 subprocess.call(command) |
86 else: | 91 else: |
87 subprocess.check_call(command) | 92 subprocess.check_call(command) |
88 | 93 |
89 if __name__ == "__main__": | 94 if __name__ == "__main__": |
90 user, hosts, ignore_errors, args = parseOptions(sys.argv[1:]) | 95 options = parseOptions(sys.argv[1:]) |
91 selectedHosts = resolveHostList(hosts) | 96 selectedHosts = resolveHostList(options.hosts) |
92 if len(selectedHosts) == 0: | 97 if len(selectedHosts) == 0: |
93 print >>sys.stderr, 'No valid hosts or groups specified, nothing to do' | 98 print >>sys.stderr, 'No valid hosts or groups specified, nothing to do' |
94 sys.exit(0) | 99 sys.exit(0) |
95 for host in selectedHosts: | 100 for host in selectedHosts: |
96 print >>sys.stderr, 'Running on %s...' % host | 101 print >>sys.stderr, 'Running on %s...' % host |
97 runCommand(user, host, args, ignore_errors=ignore_errors) | 102 runCommand(options.user, host, options.args, options.ignore_errors) |
OLD | NEW |