| Left: | ||
| Right: |
| LEFT | RIGHT |
|---|---|
| 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 argparse |
| 5 import sys | 5 import sys |
| 6 import os | 6 import os |
| 7 import re | 7 import re |
| 8 import subprocess | 8 import subprocess |
| 9 import getopt | |
| 10 import yaml | 9 import yaml |
| 11 | 10 |
| 12 def createArgumentParser(**kwargs): | 11 def createArgumentParser(**kwargs): |
| 13 parser = argparse.ArgumentParser(**kwargs) | 12 parser = argparse.ArgumentParser(**kwargs) |
| 14 parser.add_argument( | 13 parser.add_argument( |
| 15 '-u', metavar='<user>', dest='user', type=str, default='vagrant', | 14 '-u', '--user', metavar='user', dest='user', type=str, default='vagrant', |
| 16 help='user name for use with SSH, must exist on all hosts' | 15 help='user name for use with SSH, must exist on all hosts' |
| 17 ) | |
| 18 | |
| 19 parser.add_argument( | |
| 20 '-?', action='help', | |
| 21 help='print this message and exit' | |
| 22 ) | 16 ) |
| 23 | 17 |
|
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
| |
| 24 return parser | 18 return parser |
| 25 | 19 |
| 26 def parseOptions(args): | 20 def parseOptions(args): |
| 27 description = "Run a command on the given hosts or groups of hosts" | 21 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.
| |
| 28 parser = createArgumentParser(description=description, add_help=False) | 22 parser = createArgumentParser(description=description) |
| 29 parser.add_argument( | 23 parser.add_argument( |
| 30 '-i', action='store_true', dest='ignore_errors', | 24 '-i', '--ignore-errors', action='store_true', dest='ignore_errors', |
| 31 help='continue execution on next host in case of an error' | 25 help='continue execution on next host in case of an error' |
| 32 ) | 26 ) |
| 33 | 27 |
| 34 hosts = set() | 28 hosts = set() |
| 35 parser.add_argument( | 29 parser.add_argument( |
| 36 '-h', metavar='<host|group>', | 30 '-t', '--target', metavar='host|group', |
| 37 help='target host or group, can be specified multiple times', | 31 help='target host or group, can be specified multiple times', |
| 38 type=lambda value: hosts.update((value,)) | 32 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.
| |
| 39 ) | 33 ) |
| 40 | 34 |
| 41 parser.add_argument( | 35 parser.add_argument( |
| 42 'args', metavar='command', type=str, nargs='+', | 36 'args', metavar='command', type=str, nargs='+', |
| 43 help='The command to run on the specified hosts' | 37 help='the command to run on the specified hosts' |
| 44 ) | 38 ) |
| 45 | 39 |
| 46 options = parser.parse_args(args) | 40 options = parser.parse_args(args) |
| 47 options.hosts = hosts | 41 options.hosts = hosts |
| 48 return options | 42 return options |
| 49 | 43 |
| 50 def getValidHosts(): | 44 def getValidHosts(): |
| 51 dirname = os.path.dirname(sys.argv[0]) | 45 dirname = os.path.dirname(sys.argv[0]) |
| 52 path_name = os.path.join(dirname, "modules", "private", "hiera", "hosts.yaml") | 46 path_name = os.path.join(dirname, 'modules', 'private', 'hiera', 'hosts.yaml') |
| 53 with open(path_name, 'rb') as handle: | 47 with open(path_name, 'rb') as handle: |
| 54 config = yaml.load(handle) | 48 config = yaml.load(handle) |
| 55 servers = config.get('servers', {}) | 49 servers = config.get('servers', {}) |
| 56 return servers | 50 return servers |
| 57 | 51 |
| 58 def resolveHostList(hosts): | 52 def resolveHostList(hosts): |
| 59 | 53 |
| 60 result = set() | 54 result = set() |
| 61 | 55 |
| 62 try: | 56 try: |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 78 if len(chunk) == 0: | 72 if len(chunk) == 0: |
| 79 print >>sys.stderr, 'Warning: failed to recognize host or group', name | 73 print >>sys.stderr, 'Warning: failed to recognize host or group', name |
| 80 else: | 74 else: |
| 81 result.update(chunk) | 75 result.update(chunk) |
| 82 | 76 |
| 83 return result | 77 return result |
| 84 | 78 |
| 85 def runCommand(user, host, command, ignore_errors=False): | 79 def runCommand(user, host, command, ignore_errors=False): |
| 86 if not isinstance(command, list): | 80 if not isinstance(command, list): |
| 87 command = [command] | 81 command = [command] |
| 88 command = ["ssh"] + (["-l", user] if user else []) + [host] + command | 82 command = ['ssh'] + (['-l', user] if user else []) + [host] + command |
| 89 if ignore_errors: | 83 if ignore_errors: |
| 90 subprocess.call(command) | 84 subprocess.call(command) |
| 91 else: | 85 else: |
| 92 subprocess.check_call(command) | 86 subprocess.check_call(command) |
| 93 | 87 |
| 94 if __name__ == "__main__": | 88 if __name__ == '__main__': |
| 95 options = parseOptions(sys.argv[1:]) | 89 options = parseOptions(sys.argv[1:]) |
| 96 selectedHosts = resolveHostList(options.hosts) | 90 selectedHosts = resolveHostList(options.hosts) |
| 97 if len(selectedHosts) == 0: | 91 if len(selectedHosts) == 0: |
| 98 print >>sys.stderr, 'No valid hosts or groups specified, nothing to do' | 92 print >>sys.stderr, 'No valid hosts or groups specified, nothing to do' |
| 99 sys.exit(0) | 93 sys.exit(0) |
| 100 for host in selectedHosts: | 94 for host in selectedHosts: |
| 101 print >>sys.stderr, 'Running on %s...' % host | 95 print >>sys.stderr, 'Running on %s...' % host |
| 102 runCommand(options.user, host, options.args, options.ignore_errors) | 96 runCommand(options.user, host, options.args, options.ignore_errors) |
| LEFT | RIGHT |