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

Side by Side Diff: infra/services/master_lifecycle/buildbot_state.py

Issue 1108523002: Add buildbot state machine and master_manager tool. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@daemon_bot_lib_merge
Patch Set: Fix lockfile issues. Created 5 years, 7 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
OLDNEW
(Empty)
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
3 # found in the LICENSE file.
4
5
6 """A state machine to determine and act on a buildbot master's state."""
7
8
9 from infra.libs.state_machine import pattern_match
10 from infra.libs.time_functions import timestamp
11 from infra.libs.buildbot import master
12
13
14 STATES = {
15 'buildbot': [
16 'offline',
17 'starting',
18 'running',
19 'draining',
20 'drained',
21 'crashed',
22 ],
23 'desired_buildbot_state': [
24 'offline',
25 'running',
26 'drained',
27 ],
28 'desired_transition_time_utc': [
29 'transition_hasnt_happened',
30 'transition_happened',
31 'future_transition',
iannucci 2015/04/29 01:55:12 ready, done, future
32 ],
33 }
34
35
36 def collect_evidence(master_directory, connection_timeout=30):
37 """Collects evidence from the OS for late state determination."""
38 evidence = {}
39 evidence['now'] = timestamp.utcnow_ts()
40 evidence['last_boot'] = master.get_last_boot(master_directory)
41 evidence['last_no_new_builds'] = master.get_last_no_new_builds(
42 master_directory)
43 evidence['buildbot_is_running'] = master.buildbot_is_running(master_directory)
44
45 if evidence['buildbot_is_running']:
46 evidence['accepting_builds'] = master.get_accepting_builds(
47 master_directory, timeout=connection_timeout)
48
49 return evidence
50
51
52 def construct_pattern_matcher(
53 boot_timeout_sec=5 * 60, drain_timeout_sec=5 * 60):
54 # There is a bug in pylint which triggers false positives on decorated
55 # decorators with arguments: http://goo.gl/Ln6uyn
56 # pylint: disable=no-value-for-parameter
57 matchlist = pattern_match.MatchList(STATES)
58
59 @matchlist.add_match(
iannucci 2015/04/29 01:55:12 what about a @matchlist.add_match( desired_tran
60 buildbot='running',
61 desired_buildbot_state='running',
62 exclusions={'desired_transition_time_utc': ['transition_hasnt_happened']})
iannucci 2015/04/29 01:55:12 what about desired_transition_time_utc=matchlis
63 @matchlist.add_match(
64 buildbot='running',
65 desired_transition_time_utc='future_transition')
66 @matchlist.add_match(
67 buildbot='drained',
68 desired_buildbot_state='drained',
69 exclusions={'desired_transition_time_utc': ['transition_hasnt_happened']})
70 @matchlist.add_match(
71 buildbot='offline',
72 desired_buildbot_state='offline')
73 @matchlist.add_match(
74 buildbot='offline',
75 desired_transition_time_utc='future_transition')
76 @matchlist.add_match(
77 buildbot='starting',
78 exclusions={'desired_buildbot_state': ['offline']})
79 @matchlist.add_match(
80 buildbot='draining')
81 def _do_nothing():
82 return []
83
84 @matchlist.add_match(
85 buildbot='drained',
86 desired_buildbot_state='running')
87 @matchlist.add_match(
88 buildbot='drained',
89 desired_buildbot_state='drained',
90 desired_transition_time_utc='transition_hasnt_happened')
91 @matchlist.add_match(
92 buildbot='crashed',
93 exclusions={'desired_buildbot_state': ['offline']})
94 def _make_restart():
95 return [
96 master.GclientSync, master.MakeStop, master.MakeWait, master.MakeStart]
97
98 @matchlist.add_match(
99 buildbot='running',
100 desired_buildbot_state='running',
101 desired_transition_time_utc='transition_hasnt_happened')
102 @matchlist.add_match(
103 buildbot='running',
104 desired_buildbot_state='offline',
105 exclusions={'desired_transition_time_utc': ['future_transition']})
106 @matchlist.add_match(
107 buildbot='running',
108 desired_buildbot_state='drained',
109 exclusions={'desired_transition_time_utc': ['future_transition']})
110 def _make_no_new_builds():
111 return [master.MakeNoNewBuilds]
112
113 @matchlist.add_match(
114 buildbot='offline',
115 exclusions={
116 'desired_buildbot_state': ['offline'],
117 'desired_transition_time_utc': ['future_transition'],
118 })
119 def _make_start():
120 return [master.GclientSync, master.MakeStart]
121
122 @matchlist.add_match(
123 buildbot='crashed',
124 desired_buildbot_state='offline')
125 @matchlist.add_match(
126 buildbot='starting',
127 desired_buildbot_state='offline')
128 @matchlist.add_match(
129 buildbot='drained',
130 desired_buildbot_state='offline')
131 def _make_stop():
132 return [master.MakeStop]
133
134 @matchlist.add_detector('buildbot')
135 def _check_buildbot_state(data):
136 if not data['buildbot_is_running']:
137 return 'offline'
138 if data['accepting_builds'] is None:
iannucci 2015/04/29 01:55:12 later: let's invert this and call it 'draining_bui
139 if data['last_boot'] > (data['now'] - boot_timeout_sec):
140 return 'starting'
141 return 'crashed'
142 if data['accepting_builds']:
143 return 'running'
144 if data['last_no_new_builds'] > (data['now'] - drain_timeout_sec):
145 return 'draining'
146 return 'drained'
147
148 @matchlist.add_detector('desired_buildbot_state')
149 def _check_desired_state(data):
150 desired_state = data['desired_buildbot_state']['desired_state']
151 if desired_state in STATES['desired_buildbot_state']:
152 return desired_state
153
154 raise ValueError('%s is not a valid desired_buildbot_state' % desired_state)
155
156 @matchlist.add_detector('desired_transition_time_utc')
157 def _check_transition_time(data):
158 transition_time = data['desired_buildbot_state']['transition_time_utc']
159 if transition_time > data['now']:
160 return 'future_transition'
161 if transition_time >= data['last_boot']:
162 return 'transition_hasnt_happened'
163 return 'transition_happened'
164
165
166 assert matchlist.is_correct
167 return matchlist
OLDNEW
« no previous file with comments | « infra/services/master_lifecycle/__init__.py ('k') | infra/services/master_lifecycle/test/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698