| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2013 The Chromium Authors. All rights reserved. | 2 # Copyright 2013 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Closes tree if configured masters have failed tree-closing steps. | 6 """Closes tree if configured masters have failed tree-closing steps. |
| 7 | 7 |
| 8 Given a list of masters, gatekeeper_ng will get a list of the latest builds from | 8 Given a list of masters, gatekeeper_ng will get a list of the latest builds from |
| 9 the specified masters. It then checks if any tree-closing steps have failed, and | 9 the specified masters. It then checks if any tree-closing steps have failed, and |
| 10 if so closes the tree and emails appropriate parties. Configuration for which | 10 if so closes the tree and emails appropriate parties. Configuration for which |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 'password': password | 80 'password': password |
| 81 }) | 81 }) |
| 82 | 82 |
| 83 # Standard urllib doesn't raise an exception on 403, urllib2 does. | 83 # Standard urllib doesn't raise an exception on 403, urllib2 does. |
| 84 status_url = status_url_root + "/status" | 84 status_url = status_url_root + "/status" |
| 85 f = logging_urlopen(status_url, params) | 85 f = logging_urlopen(status_url, params) |
| 86 f.close() | 86 f.close() |
| 87 logging.info('success') | 87 logging.info('success') |
| 88 | 88 |
| 89 | 89 |
| 90 def get_tree_status(status_url_root): | 90 def get_tree_status(status_url_root, username, password): |
| 91 status_url = status_url_root + "/current?format=json" | 91 status_url = status_url_root + "/current?format=json" |
| 92 return json.load(logging_urlopen(status_url)) | 92 data = logging_urlopen(status_url).read() |
| 93 try: |
| 94 return json.loads(data) |
| 95 except ValueError: |
| 96 if 'Login Required' not in data: |
| 97 raise |
| 98 # try using bot password to authenticate |
| 99 params = urllib.urlencode({ |
| 100 'username': username, |
| 101 'password': password |
| 102 }) |
| 103 try: |
| 104 data = logging_urlopen(status_url, params).read() |
| 105 except urllib2.HTTPError, e: |
| 106 if e.code == 405: |
| 107 logging.warn("update your chromium_status app.") |
| 108 raise |
| 109 return json.loads(data) |
| 93 | 110 |
| 94 | 111 |
| 95 def get_builder_section(gatekeeper_section, builder): | 112 def get_builder_section(gatekeeper_section, builder): |
| 96 """Returns the applicable gatekeeper config for the builder. | 113 """Returns the applicable gatekeeper config for the builder. |
| 97 | 114 |
| 98 If the builder isn't present or is excluded, return None. | 115 If the builder isn't present or is excluded, return None. |
| 99 """ | 116 """ |
| 100 if builder in gatekeeper_section: | 117 if builder in gatekeeper_section: |
| 101 builder_section = gatekeeper_section[builder] | 118 builder_section = gatekeeper_section[builder] |
| 102 elif '*' in gatekeeper_section: | 119 elif '*' in gatekeeper_section: |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 ','.join(still_failing_steps), builder, master_url, | 519 ','.join(still_failing_steps), builder, master_url, |
| 503 urllib.quote(builder), buildnum)) | 520 urllib.quote(builder), buildnum)) |
| 504 | 521 |
| 505 if previously_failed_builds: | 522 if previously_failed_builds: |
| 506 logging.debug( | 523 logging.debug( |
| 507 'Not opening tree because previous builds weren\'t successful:') | 524 'Not opening tree because previous builds weren\'t successful:') |
| 508 for build in previously_failed_builds: | 525 for build in previously_failed_builds: |
| 509 logging.debug(' %s' % build) | 526 logging.debug(' %s' % build) |
| 510 return | 527 return |
| 511 | 528 |
| 512 status = get_tree_status(status_url_root) | 529 status = get_tree_status(status_url_root, username, password) |
| 513 # Don't change the status unless the tree is currently closed. | 530 # Don't change the status unless the tree is currently closed. |
| 514 if status['general_state'] != 'closed': | 531 if status['general_state'] != 'closed': |
| 515 return | 532 return |
| 516 | 533 |
| 517 # Don't override human closures. | 534 # Don't override human closures. |
| 518 # FIXME: We could check that we closed the tree instead? | 535 # FIXME: We could check that we closed the tree instead? |
| 519 if not re.search(r"automatic", status['message'], re.IGNORECASE): | 536 if not re.search(r"automatic", status['message'], re.IGNORECASE): |
| 520 return | 537 return |
| 521 | 538 |
| 522 logging.info('All builders are green, opening the tree...') | 539 logging.info('All builders are green, opening the tree...') |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 | 574 |
| 558 def close_tree_if_necessary(failed_builds, username, password, status_url_root, | 575 def close_tree_if_necessary(failed_builds, username, password, status_url_root, |
| 559 set_status, revision_properties): | 576 set_status, revision_properties): |
| 560 """Given a list of failed builds, close the tree if necessary.""" | 577 """Given a list of failed builds, close the tree if necessary.""" |
| 561 | 578 |
| 562 closing_builds = [b for b in failed_builds if b['close_tree']] | 579 closing_builds = [b for b in failed_builds if b['close_tree']] |
| 563 if not closing_builds: | 580 if not closing_builds: |
| 564 logging.info('no tree-closing failures!') | 581 logging.info('no tree-closing failures!') |
| 565 return | 582 return |
| 566 | 583 |
| 567 status = get_tree_status(status_url_root) | 584 status = get_tree_status(status_url_root, username, password) |
| 568 # Don't change the status unless the tree is currently open. | 585 # Don't change the status unless the tree is currently open. |
| 569 if status['general_state'] != 'open': | 586 if status['general_state'] != 'open': |
| 570 return | 587 return |
| 571 | 588 |
| 572 logging.info('%d failed builds found, closing the tree...' % | 589 logging.info('%d failed builds found, closing the tree...' % |
| 573 len(closing_builds)) | 590 len(closing_builds)) |
| 574 | 591 |
| 575 template_build = closing_builds[0] | 592 template_build = closing_builds[0] |
| 576 template_vars = { | 593 template_vars = { |
| 577 'blamelist': ','.join(template_build['build']['blame']), | 594 'blamelist': ','.join(template_build['build']['blame']), |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 | 898 |
| 882 if not options.skip_build_db_update: | 899 if not options.skip_build_db_update: |
| 883 build_scan_db.save_build_db(build_db, gatekeeper_config, | 900 build_scan_db.save_build_db(build_db, gatekeeper_config, |
| 884 options.build_db) | 901 options.build_db) |
| 885 | 902 |
| 886 return 0 | 903 return 0 |
| 887 | 904 |
| 888 | 905 |
| 889 if __name__ == '__main__': | 906 if __name__ == '__main__': |
| 890 sys.exit(main()) | 907 sys.exit(main()) |
| OLD | NEW |