| 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 |