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

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: Address iannucci's final comments. 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 = {
agable 2015/04/30 21:23:30 Love it, this set of states is great.
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': [
29 'ready_to_fire',
30 'hold_steady',
31 ],
32 }
33
34
35 def collect_evidence(master_directory, connection_timeout=30):
36 """Collects evidence from the OS for late state determination."""
37 evidence = {}
38 evidence['now'] = timestamp.utcnow_ts()
39 evidence['last_boot'] = master.get_last_boot(master_directory)
40 evidence['last_no_new_builds'] = master.get_last_no_new_builds(
41 master_directory)
42 evidence['buildbot_is_running'] = master.buildbot_is_running(master_directory)
43
44 if evidence['buildbot_is_running']:
45 evidence['accepting_builds'] = master.get_accepting_builds(
46 master_directory, timeout=connection_timeout)
47
48 return evidence
49
50
51 def construct_pattern_matcher(
52 boot_timeout_sec=5 * 60, drain_timeout_sec=5 * 60):
53 # There is a bug in pylint which triggers false positives on decorated
54 # decorators with arguments: http://goo.gl/Ln6uyn
55 # pylint: disable=no-value-for-parameter
56 matchlist = pattern_match.MatchList(STATES)
57
58 @matchlist.add_match(
59 buildbot='running',
60 desired_buildbot_state='running',
61 desired_transition_time='hold_steady')
62 @matchlist.add_match(
63 buildbot='drained',
64 desired_buildbot_state='drained',
65 desired_transition_time='hold_steady')
66 @matchlist.add_match(
67 buildbot='offline',
68 desired_buildbot_state='offline')
69 @matchlist.add_match(
70 buildbot='starting',
71 exclusions={'desired_buildbot_state': ['offline']})
72 @matchlist.add_match(
73 buildbot='draining')
74 def _do_nothing():
75 return []
76
77 @matchlist.add_match(
78 buildbot='drained',
79 desired_buildbot_state='running')
80 @matchlist.add_match(
81 buildbot='drained',
82 desired_buildbot_state='drained',
83 desired_transition_time='ready_to_fire')
84 @matchlist.add_match(
85 buildbot='crashed',
86 exclusions={'desired_buildbot_state': ['offline']})
87 def _make_restart():
88 return [
89 master.GclientSync, master.MakeStop, master.MakeWait, master.MakeStart]
90
91 @matchlist.add_match(
92 buildbot='running',
93 desired_buildbot_state='running',
94 desired_transition_time='ready_to_fire')
95 @matchlist.add_match(
96 buildbot='running',
97 desired_buildbot_state='offline')
98 @matchlist.add_match(
99 buildbot='running',
100 desired_buildbot_state='drained')
101 def _make_no_new_builds():
102 return [master.MakeNoNewBuilds]
103
104 @matchlist.add_match(
105 buildbot='offline',
106 exclusions={
107 'desired_buildbot_state': ['offline'],
108 })
109 def _make_start():
110 return [master.GclientSync, master.MakeStart]
111
112 @matchlist.add_match(
113 buildbot='crashed',
114 desired_buildbot_state='offline')
115 @matchlist.add_match(
116 buildbot='starting',
117 desired_buildbot_state='offline')
118 @matchlist.add_match(
119 buildbot='drained',
120 desired_buildbot_state='offline')
121 def _make_stop():
122 return [master.MakeStop]
123
124 @matchlist.add_detector('buildbot')
125 def _check_buildbot_state(data):
126 if not data['buildbot_is_running']:
127 return 'offline'
128 if data['accepting_builds'] is None:
129 if data['last_boot'] > (data['now'] - boot_timeout_sec):
130 return 'starting'
131 return 'crashed'
132 if data['accepting_builds']:
133 return 'running'
134 if data['last_no_new_builds'] > (data['now'] - drain_timeout_sec):
135 return 'draining'
136 return 'drained'
137
138 @matchlist.add_detector('desired_buildbot_state')
139 def _check_desired_state(data):
140 desired_state = data['desired_buildbot_state']['desired_state']
141 if desired_state in STATES['desired_buildbot_state']:
142 return desired_state
143
144 raise ValueError('%s is not a valid desired_buildbot_state' % desired_state)
145
146 @matchlist.add_detector('desired_transition_time')
147 def _check_transition_time(data):
148 transition_time = data['desired_buildbot_state']['transition_time_utc']
149 if transition_time > data['now']:
150 # If we specify a date in the future and request 'running', the state
151 # machine will continually reboot buildbot until that time is reached.
152 raise ValueError(
153 'specifying a date in the future creates ambiguity about now')
154 if transition_time >= data['last_boot']:
155 return 'ready_to_fire'
156 return 'hold_steady'
157
158
159 assert matchlist.is_correct
160 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