OLD | NEW |
(Empty) | |
| 1 # Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 """Post a try job to the Try server to produce build. It communicates |
| 6 to server by directly connecting via HTTP. |
| 7 """ |
| 8 |
| 9 import getpass |
| 10 import optparse |
| 11 import os |
| 12 import sys |
| 13 import urllib |
| 14 import urllib2 |
| 15 |
| 16 |
| 17 class ServerAccessError(Exception): |
| 18 def __str__(self): |
| 19 return '%s\nSorry, cannot connect to server.' % self.args[0] |
| 20 |
| 21 |
| 22 def PostTryJob(url_params): |
| 23 """Sends a build request to the server using the HTTP protocol. |
| 24 |
| 25 Args: |
| 26 url_params: A dictionary of query parameters to be sent in the request. |
| 27 In order to post build request to try server, this dictionary |
| 28 should contain information for following keys: |
| 29 'host': Hostname of the try server. |
| 30 'port': Port of the try server. |
| 31 'revision': SVN Revision to build. |
| 32 'bot': Name of builder bot which would be used. |
| 33 Returns: |
| 34 True if the request is posted successfully. Otherwise throws an exception. |
| 35 """ |
| 36 # Parse url parameters to be sent to Try server. |
| 37 if not url_params.get('host'): |
| 38 raise ValueError('Hostname of server to connect is missing.') |
| 39 if not url_params.get('port'): |
| 40 raise ValueError('Port of server to connect is missing.') |
| 41 if not url_params.get('revision'): |
| 42 raise ValueError('Missing revision details. Please specify revision' |
| 43 ' information.') |
| 44 if not url_params.get('bot'): |
| 45 raise ValueError('Missing bot details. Please specify bot information.') |
| 46 |
| 47 url = 'http://%s:%s/send_try_patch' % (url_params['host'], url_params['port']) |
| 48 |
| 49 print 'Sending by HTTP' |
| 50 query_params = '&'.join('%s=%s' % (k, v) for k, v in url_params.iteritems()) |
| 51 print 'url: %s?%s' % (url, query_params) |
| 52 |
| 53 connection = None |
| 54 try: |
| 55 print 'Opening connection...' |
| 56 connection = urllib2.urlopen(url, urllib.urlencode(url_params)) |
| 57 print 'Done, request sent to server to produce build.' |
| 58 except IOError, e: |
| 59 raise ServerAccessError('%s is unaccessible. Reason: %s' % (url, e)) |
| 60 if not connection: |
| 61 raise ServerAccessError('%s is unaccessible.' % url) |
| 62 response = connection.read() |
| 63 print 'Received %s from server' % response |
| 64 if response != 'OK': |
| 65 raise ServerAccessError('%s is unaccessible. Got:\n%s' % (url, response)) |
| 66 return True |
| 67 |
| 68 |
| 69 def _GetQueryParams(options): |
| 70 """Parses common query parameters which will be passed to PostTryJob. |
| 71 |
| 72 Args: |
| 73 options: The options object parsed from the command line. |
| 74 |
| 75 Returns: |
| 76 A dictionary consists of query parameters. |
| 77 """ |
| 78 values = {'host': options.host, |
| 79 'port': options.port, |
| 80 'user': options.user, |
| 81 'name': options.name |
| 82 } |
| 83 if options.email: |
| 84 values['email'] = options.email |
| 85 if options.revision: |
| 86 values['revision'] = options.revision |
| 87 if options.root: |
| 88 values['root'] = options.root |
| 89 if options.bot: |
| 90 values['bot'] = options.bot |
| 91 if options.patch: |
| 92 values['patch'] = options.patch |
| 93 return values |
| 94 |
| 95 |
| 96 def _GenParser(): |
| 97 """Parses the command line for posting build request.""" |
| 98 usage = ('%prog [options]\n' |
| 99 'Post a build request to the try server for the given revision.\n') |
| 100 parser = optparse.OptionParser(usage=usage) |
| 101 parser.add_option('-H', '--host', |
| 102 help='Host address of the try server.') |
| 103 parser.add_option('-P', '--port', type='int', |
| 104 help='HTTP port of the try server.') |
| 105 parser.add_option('-u', '--user', default=getpass.getuser(), |
| 106 dest='user', |
| 107 help='Owner user name [default: %default]') |
| 108 parser.add_option('-e', '--email', |
| 109 default=os.environ.get('TRYBOT_RESULTS_EMAIL_ADDRESS', |
| 110 os.environ.get('EMAIL_ADDRESS')), |
| 111 help='Email address where to send the results. Use either ' |
| 112 'the TRYBOT_RESULTS_EMAIL_ADDRESS environment ' |
| 113 'variable or EMAIL_ADDRESS to set the email address ' |
| 114 'the try bots report results to [default: %default]') |
| 115 parser.add_option('-n', '--name', |
| 116 default= 'try_job_http', |
| 117 help='Descriptive name of the try job') |
| 118 parser.add_option('-b', '--bot', |
| 119 help=('IMPORTANT: specify ONE builder per run is supported.' |
| 120 'Run script for each builders separately.')) |
| 121 parser.add_option('-r', '--revision', |
| 122 help='Revision to use for the try job; default: the ' |
| 123 'revision will be determined by the try server; see ' |
| 124 'its waterfall for more info') |
| 125 parser.add_option('--root', |
| 126 help='Root to use for the patch; base subdirectory for ' |
| 127 'patch created in a subdirectory') |
| 128 parser.add_option('--patch', |
| 129 help='Patch information.') |
| 130 return parser |
| 131 |
| 132 |
| 133 def Main(argv): |
| 134 parser = _GenParser() |
| 135 options, args = parser.parse_args() |
| 136 if not options.host: |
| 137 raise ServerAccessError('Please use the --host option to specify the try ' |
| 138 'server host to connect to.') |
| 139 if not options.port: |
| 140 raise ServerAccessError('Please use the --port option to specify the try ' |
| 141 'server port to connect to.') |
| 142 params = _GetQueryParams(options) |
| 143 PostTryJob(params) |
| 144 |
| 145 |
| 146 if __name__ == '__main__': |
| 147 sys.exit(Main(sys.argv)) |
OLD | NEW |