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