Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: scripts/master/buildbucket/integration.py

Issue 2157703002: buildbucket: support unique change urls (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: nits Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """BuildBucketIntegrator integrates Buildbot and Buildbucket.""" 5 """BuildBucketIntegrator integrates Buildbot and Buildbucket."""
6 6
7 import datetime 7 import datetime
8 import itertools
9 import json 8 import json
10 import logging 9 import logging
11 import traceback
12 10
13 from buildbot.util import deferredLocked 11 from buildbot.util import deferredLocked
14 from master.buildbucket import common, changestore 12 from master.buildbucket import changestore
15 from master.buildbucket.common import log
16 from twisted.internet import defer, reactor 13 from twisted.internet import defer, reactor
17 from twisted.internet.defer import inlineCallbacks, returnValue 14 from twisted.internet.defer import inlineCallbacks, returnValue
18 15
19 from . import common 16 from . import common
20 17
21 # buildbucket API-related constants. 18 # buildbucket API-related constants.
22 # time enough to schedule and start a build. 19 # time enough to schedule and start a build.
23 LEASE_DURATION = datetime.timedelta(hours=1) 20 LEASE_DURATION = datetime.timedelta(hours=1)
24 DEFAULT_HEARTBEAT_INTERVAL = datetime.timedelta(minutes=5) 21 DEFAULT_HEARTBEAT_INTERVAL = datetime.timedelta(minutes=5)
25 # Maximum integer that max_builds buildbucket parameter can take. 22 # Maximum integer that max_builds buildbucket parameter can take.
(...skipping 21 matching lines...) Expand all
47 # It is a dict build_id -> lease, where lease is a dict with keys: 44 # It is a dict build_id -> lease, where lease is a dict with keys:
48 # - key: lease key 45 # - key: lease key
49 # - build_request: BuildRequestGateway 46 # - build_request: BuildRequestGateway
50 # - build: if build_started with same build_id was called, 47 # - build: if build_started with same build_id was called,
51 # the associated build. 48 # the associated build.
52 # _lease is None on creation, but it gets loaded from the database in 49 # _lease is None on creation, but it gets loaded from the database in
53 # _ensure_leases_loaded(). 50 # _ensure_leases_loaded().
54 51
55 def __init__( 52 def __init__(
56 self, buckets, build_params_hook=None, max_lease_count=None, 53 self, buckets, build_params_hook=None, max_lease_count=None,
57 heartbeat_interval=None): 54 heartbeat_interval=None, change_store_factory=None):
58 """Creates a BuildBucketIntegrator. 55 """Creates a BuildBucketIntegrator.
59 56
60 Args: 57 Args:
61 buckets (list of str): poll only builds in any of |buckets|. 58 buckets (list of str): poll only builds in any of |buckets|.
62 build_params_hook (func): If not None, a callable with arguments 59 build_params_hook (func): If not None, a callable with arguments
63 (params, build) that can modify the supplied parameters during 60 (params, build) that can modify the supplied parameters during
64 validation. 61 validation.
65 62
66 If a ValueError is raised, the build will be marked as an 63 If a ValueError is raised, the build will be marked as an
67 INVALID_BUILD_DEFINITION failure and the error message will be 64 INVALID_BUILD_DEFINITION failure and the error message will be
68 propagated to the BuildBucket status. 65 propagated to the BuildBucket status.
69 max_lease_count (int): maximum number of builds that can be leased at a 66 max_lease_count (int): maximum number of builds that can be leased at a
70 time. Defaults to the number of connected slaves. 67 time. Defaults to the number of connected slaves.
71 heartbeat_interval (datetime.timedelta): frequency of build heartbeats. 68 heartbeat_interval (datetime.timedelta): frequency of build heartbeats.
72 Defaults to 1 minute. 69 Defaults to 1 minute.
70 change_store_factory: function (BuildbotGateway) => ChangeStore.
73 """ 71 """
74 assert buckets, 'Buckets not specified' 72 assert buckets, 'Buckets not specified'
75 assert max_lease_count is None or isinstance(max_lease_count, int) 73 assert max_lease_count is None or isinstance(max_lease_count, int)
76 if max_lease_count is not None: 74 if max_lease_count is not None:
77 assert max_lease_count >= 1 75 assert max_lease_count >= 1
78 self.buckets = buckets[:] 76 self.buckets = buckets[:]
79 self.build_params_hook = build_params_hook 77 self.build_params_hook = build_params_hook
80 self.buildbot = None 78 self.buildbot = None
81 self.buildbucket_service = None 79 self.buildbucket_service = None
82 self._find_change_cache = None 80 self._find_change_cache = None
83 self.started = False 81 self.started = False
84 self.changes = None 82 self.changes = None
85 self.poll_lock = defer.DeferredLock() 83 self.poll_lock = defer.DeferredLock()
86 self._max_lease_count = max_lease_count 84 self._max_lease_count = max_lease_count
87 self._leases = None 85 self._leases = None
88 self.heartbeat_interval = heartbeat_interval or DEFAULT_HEARTBEAT_INTERVAL 86 self.heartbeat_interval = heartbeat_interval or DEFAULT_HEARTBEAT_INTERVAL
87 self.change_store_factory = change_store_factory or changestore.ChangeStore
89 88
90 def get_max_lease_count(self): 89 def get_max_lease_count(self):
91 if self._max_lease_count: 90 if self._max_lease_count:
92 return self._max_lease_count 91 return self._max_lease_count
93 if not self.buildbot: 92 if not self.buildbot:
94 return 0 93 return 0
95 return len(self.buildbot.get_connected_slaves()) 94 return len(self.buildbot.get_connected_slaves())
96 95
97 def log(self, message, level=None): 96 def log(self, message, level=None):
98 common.log(message, level) 97 common.log(message, level)
99 98
100 def start(self, buildbot, buildbucket_service, change_store_factory=None): 99 def start(self, buildbot, buildbucket_service):
101 assert not self.started, 'BuildBucketIntegrator is already started' 100 assert not self.started, 'BuildBucketIntegrator is already started'
102 assert buildbot 101 assert buildbot
103 assert buildbucket_service 102 assert buildbucket_service
104 change_store_factory = change_store_factory or changestore.ChangeStore
105 self.buildbot = buildbot 103 self.buildbot = buildbot
106 self.buildbucket_service = buildbucket_service 104 self.buildbucket_service = buildbucket_service
107 self.buildbucket_service.start() 105 self.buildbucket_service.start()
108 self.changes = change_store_factory(buildbot) 106 self.changes = self.change_store_factory(buildbot)
109 self.started = True 107 self.started = True
110 self.log('integrator started') 108 self.log('integrator started')
111 self._do_until_stopped(self.heartbeat_interval, self.send_heartbeats) 109 self._do_until_stopped(self.heartbeat_interval, self.send_heartbeats)
112 self._do_until_stopped( 110 self._do_until_stopped(
113 LEASE_CLEANUP_INTERVAL, self.clean_completed_build_requests) 111 LEASE_CLEANUP_INTERVAL, self.clean_completed_build_requests)
114 112
115 @inlineCallbacks 113 @inlineCallbacks
116 def _get_leases_from_db(self): 114 def _get_leases_from_db(self):
117 """Returns currently held leases from the database. 115 """Returns currently held leases from the database.
118 116
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 'properties': properties_to_send, 641 'properties': properties_to_send,
644 }, sort_keys=True), 642 }, sort_keys=True),
645 } 643 }
646 if status == 'SUCCESS': 644 if status == 'SUCCESS':
647 yield self._leased_build_call('succeed', build, body) 645 yield self._leased_build_call('succeed', build, body)
648 else: 646 else:
649 body['failure_reason'] = ( 647 body['failure_reason'] = (
650 'BUILD_FAILURE' if status == 'FAILURE' 648 'BUILD_FAILURE' if status == 'FAILURE'
651 else 'INFRA_FAILURE') 649 else 'INFRA_FAILURE')
652 yield self._leased_build_call('fail', build, body) 650 yield self._leased_build_call('fail', build, body)
OLDNEW
« no previous file with comments | « scripts/master/buildbucket/changestore.py ('k') | scripts/master/buildbucket/unittests/changestore_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698