Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: run.py

Issue 29341151: Issue 4019 - Added "Edge" to platform choices in Issues tracker at issues1. (Closed)
Patch Set: Created May 10, 2016, 3:35 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « modules/web/templates/adblockplus.org.conf.erb ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 posixpath 7 import posixpath
8 import re 8 import re
9 import subprocess 9 import subprocess
10 import yaml 10 import yaml
11 11
12 def createArgumentParser(**kwargs):
13 parser = argparse.ArgumentParser(**kwargs)
14 parser.add_argument(
15 '-u', '--user', metavar='user', dest='user', type=str,
16 help='user name for use with SSH, must exist on all hosts'
17 )
12 18
13 def createArgumentParser(**kwargs): 19 parser.add_argument(
14 parser = argparse.ArgumentParser(**kwargs) 20 '-l', '--local', action='store_false', dest='remote', default=None,
15 parser.add_argument( 21 help='use the local version of hosts.yaml'
16 '-u', '--user', metavar='user', dest='user', type=str, 22 )
17 help='user name for use with SSH, must exist on all hosts'
18 )
19 23
20 parser.add_argument( 24 parser.add_argument(
21 '-l', '--local', action='store_false', dest='remote', default=None, 25 '-r', '--remote', metavar='master', dest='remote', type=str,
22 help='use the local version of hosts.yaml' 26 help='use a remote (puppet-master) version of hosts.yaml'
23 ) 27 )
24 28
25 parser.add_argument( 29 return parser
26 '-r', '--remote', metavar='master', dest='remote', type=str,
27 help='use a remote (puppet-master) version of hosts.yaml'
28 )
29
30 return parser
31
32 30
33 def parseOptions(args): 31 def parseOptions(args):
34 description = 'Run a command on the given hosts or groups of hosts' 32 description = 'Run a command on the given hosts or groups of hosts'
35 parser = createArgumentParser(description=description) 33 parser = createArgumentParser(description=description)
36 parser.add_argument( 34 parser.add_argument(
37 '-i', '--ignore-errors', action='store_true', dest='ignore_errors', 35 '-i', '--ignore-errors', action='store_true', dest='ignore_errors',
38 help='continue execution on next host in case of an error' 36 help='continue execution on next host in case of an error'
39 ) 37 )
40 38
41 hosts = set() 39 hosts = set()
42 parser.add_argument( 40 parser.add_argument(
43 '-t', '--target', metavar='host|group', 41 '-t', '--target', metavar='host|group',
44 help='target host or group, can be specified multiple times', 42 help='target host or group, can be specified multiple times',
45 type=lambda value: hosts.update([value]) 43 type=lambda value: hosts.update([value])
46 ) 44 )
47 45
48 parser.add_argument( 46 parser.add_argument(
49 'args', metavar='command', type=str, nargs='+', 47 'args', metavar='command', type=str, nargs='+',
50 help='the command to run on the specified hosts' 48 help='the command to run on the specified hosts'
51 ) 49 )
52 50
53 options = parser.parse_args(args) 51 options = parser.parse_args(args)
54 options.hosts = hosts 52 options.hosts = hosts
55 return options 53 return options
56
57 54
58 def getValidHosts(options): 55 def getValidHosts(options):
59 path_canonical = ('modules', 'private', 'hiera', 'hosts.yaml') 56 path_canonical = ('modules', 'private', 'hiera', 'hosts.yaml')
60 57
61 if options.remote: 58 if options.remote:
62 login = ['-l', options.user] if options.user else [] 59 login = ['-l', options.user] if options.user else []
63 path_name = posixpath.join('/etc/puppet/infrastructure', *path_canonical ) 60 path_name = posixpath.join('/etc/puppet/infrastructure', *path_canonical)
64 command = ['ssh'] + login + [options.remote, '--', 'sudo', 'cat', path_n ame] 61 command = ['ssh'] + login + [options.remote, '--', 'sudo', 'cat', path_name]
65 child = subprocess.Popen(command, stderr=sys.stderr, stdout=subprocess.P IPE) 62 child = subprocess.Popen(command, stderr=sys.stderr, stdout=subprocess.PIPE)
66 try: 63 try:
67 config = yaml.load(child.stdout) 64 config = yaml.load(child.stdout)
68 finally: 65 finally:
69 child.stdout.close() 66 child.stdout.close()
70 child.wait() 67 child.wait()
71 elif options.remote is False: 68 elif options.remote is False:
72 dirname = os.path.dirname(sys.argv[0]) 69 dirname = os.path.dirname(sys.argv[0])
73 path_name = os.path.join(dirname, *path_canonical) 70 path_name = os.path.join(dirname, *path_canonical)
74 with open(path_name, 'rb') as handle: 71 with open(path_name, 'rb') as handle:
75 config = yaml.load(handle) 72 config = yaml.load(handle)
76 else: 73 else:
77 sys.exit('Please either specify a --remote host or use --local') 74 sys.exit('Please either specify a --remote host or use --local')
78 75
79 servers = config.get('servers', {}) 76 servers = config.get('servers', {})
80 return servers 77 return servers
81
82 78
83 def resolveHostList(options): 79 def resolveHostList(options):
84 80
85 result = set() 81 result = set()
86 82
87 try: 83 try:
88 valid_hosts = getValidHosts(options) 84 valid_hosts = getValidHosts(options)
89 except Warning as error: 85 except Warning as error:
90 print >>sys.stderr, 'Warning: failed to determine valid hosts:', error 86 print >>sys.stderr, 'Warning: failed to determine valid hosts:', error
91 result.update(options.hosts) 87 result.update(options.hosts)
92 else: 88 else:
93 for name in options.hosts: 89 for name in options.hosts:
94 chunk = [ 90 chunk = [
95 value.get('dns', key) for (key, value) in valid_hosts.items() 91 value.get('dns', key) for (key, value) in valid_hosts.items()
96 92
97 if name == key 93 if name == key
98 or name == '*' 94 or name == '*'
99 or name == value.get('dns', None) 95 or name == value.get('dns', None)
100 or name in value.get('groups', ()) 96 or name in value.get('groups', ())
101 ] 97 ]
102 98
103 if len(chunk) == 0: 99 if len(chunk) == 0:
104 print >>sys.stderr, 'Warning: failed to recognize host or group' , name 100 print >>sys.stderr, 'Warning: failed to recognize host or group', name
105 else: 101 else:
106 result.update(chunk) 102 result.update(chunk)
107 103
108 return result 104 return result
109
110 105
111 def runCommand(user, host, command, ignore_errors=False): 106 def runCommand(user, host, command, ignore_errors=False):
112 if not isinstance(command, list): 107 if not isinstance(command, list):
113 command = [command] 108 command = [command]
114 command = ['ssh'] + (['-l', user] if user else []) + [host] + command 109 command = ['ssh'] + (['-l', user] if user else []) + [host] + command
115 if ignore_errors: 110 if ignore_errors:
116 subprocess.call(command) 111 subprocess.call(command)
117 else: 112 else:
118 subprocess.check_call(command) 113 subprocess.check_call(command)
119 114
120 if __name__ == '__main__': 115 if __name__ == '__main__':
121 options = parseOptions(sys.argv[1:]) 116 options = parseOptions(sys.argv[1:])
122 selectedHosts = resolveHostList(options) 117 selectedHosts = resolveHostList(options)
123 if len(selectedHosts) == 0: 118 if len(selectedHosts) == 0:
124 print >>sys.stderr, 'No valid hosts or groups specified, nothing to do' 119 print >>sys.stderr, 'No valid hosts or groups specified, nothing to do'
125 sys.exit(0) 120 sys.exit(0)
126 for host in selectedHosts: 121 for host in selectedHosts:
127 print >>sys.stderr, 'Running on %s...' % host 122 print >>sys.stderr, 'Running on %s...' % host
128 runCommand(options.user, host, options.args, options.ignore_errors) 123 runCommand(options.user, host, options.args, options.ignore_errors)
OLDNEW
« no previous file with comments | « modules/web/templates/adblockplus.org.conf.erb ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld