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

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: Created 5 years, 8 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 'booting',
18 'started_serving_accept',
19 'started_serving_not_accept',
20 'started_serving_not_accept_drained',
21 'started_not_serving',
22 ],
23 'desired_buildbot_state': [
agable 2015/04/27 20:23:08 As noted in the comments below, the desired states
ghost stip (do not use) 2015/04/29 01:30:33 After online discussion, adjusted to three dimensi
24 'offline',
25 'future',
agable 2015/04/27 20:23:08 I have no earthly idea what "desired buildbot stat
26 'needs_reboot',
agable 2015/04/27 20:23:08 Desired state: needs reboot? I would like this bui
27 'up_to_date',
28 ],
29 }
30
31
32 def collect_evidence(master_directory, connection_timeout=30):
33 """Collects evidence from the OS for late state determination."""
34 evidence = {}
35 evidence['now'] = timestamp.utcnow_ts()
36 evidence['last_boot'] = master.get_last_boot(master_directory)
37 evidence['last_no_new_builds'] = master.get_last_no_new_builds(
38 master_directory)
39 evidence['buildbot_is_running'] = master.buildbot_is_running(master_directory)
40
41 if evidence['buildbot_is_running']:
42 evidence['accepting_builds'] = master.get_accepting_builds(
43 master_directory, timeout=connection_timeout)
44
45 return evidence
46
47
48 def construct_pattern_matcher(
49 boot_timeout_sec=5 * 60, drain_timeout_sec=5 * 60):
50 # There is a bug in pylint which triggers false positives on decorated
51 # decorators with arguments: http://goo.gl/Ln6uyn
52 # pylint: disable=no-value-for-parameter
53 matchlist = pattern_match.MatchList(STATES)
54
55 @matchlist.add_match(
56 buildbot='started_serving_accept',
57 desired_buildbot_state='up_to_date')
58 @matchlist.add_match(
59 buildbot='started_serving_accept',
60 desired_buildbot_state='future')
61 @matchlist.add_match(
62 buildbot='offline',
63 exclusions={'desired_buildbot_state': ['up_to_date', 'needs_reboot']})
64 @matchlist.add_match(
65 buildbot='booting',
66 exclusions={'desired_buildbot_state': ['offline']})
67 @matchlist.add_match(
68 buildbot='started_serving_not_accept')
69 def _do_nothing():
70 return []
71
72 @matchlist.add_match(
73 buildbot='started_serving_not_accept_drained',
74 exclusions={'desired_buildbot_state': ['offline']})
75 @matchlist.add_match(
76 buildbot='started_not_serving',
77 exclusions={'desired_buildbot_state': ['offline']})
78 def _make_restart():
79 return [
80 master.GclientSync, master.MakeStop, master.MakeWait, master.MakeStart]
81
82 @matchlist.add_match(
83 buildbot='started_serving_accept',
84 desired_buildbot_state='needs_reboot')
85 @matchlist.add_match(
86 buildbot='started_serving_accept',
87 desired_buildbot_state='offline')
88 def _make_no_new_builds():
89 return [master.MakeNoNewBuilds]
90
91 @matchlist.add_match(
92 buildbot='offline',
93 desired_buildbot_state='up_to_date')
94 @matchlist.add_match(
95 buildbot='offline',
96 desired_buildbot_state='needs_reboot')
97 def _make_start():
98 return [master.GclientSync, master.MakeStart]
99
100 @matchlist.add_match(
101 buildbot='started_not_serving',
102 desired_buildbot_state='offline')
103 @matchlist.add_match(
104 buildbot='booting',
105 desired_buildbot_state='offline')
106 @matchlist.add_match(
107 buildbot='started_serving_not_accept_drained',
108 desired_buildbot_state='offline')
109 def _make_stop():
110 return [master.MakeStop]
111
112 @matchlist.add_detector('buildbot')
113 def _check_buildbot_state(data):
114 if not data['buildbot_is_running']:
115 return 'offline'
116 if data['accepting_builds'] is None:
117 if data['last_boot'] > (data['now'] - boot_timeout_sec):
118 return 'booting'
119 return 'started_not_serving'
120 if data['accepting_builds']:
121 return 'started_serving_accept'
122 if data['last_no_new_builds'] > (data['now'] - drain_timeout_sec):
123 return 'started_serving_not_accept'
124 return 'started_serving_not_accept_drained'
125
126 @matchlist.add_detector('desired_buildbot_state')
127 def _check_desired_state(data):
128 if not data['desired_buildbot_state']['desired_state']:
129 return 'offline'
130 if data['desired_buildbot_state']['desired_state'] > data['now']:
131 return 'future'
132 if not data['last_boot']:
133 return 'needs_reboot'
134 if data['desired_buildbot_state']['desired_state'] >= data['last_boot']:
135 return 'needs_reboot'
136 return 'up_to_date'
137
138 assert matchlist.is_correct
139 return matchlist
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698