Skip to content

Commit befe468

Browse files
authored
Move worker downtime configuration to workers.py (GH-701)
We use `builder.canStartBuild` for scheduled downtime, which is per-worker configuration. Move it out of `master.cfg` to the appropriate places: - config in `workers.py` - implementation details in a new module, `worker_downtime.py` This applies `ambv-bb-win11`'s maintenance window to the PR builds, for which it was left out in GH-589.
1 parent 9bca131 commit befe468

File tree

3 files changed

+80
-77
lines changed

3 files changed

+80
-77
lines changed

master/custom/worker_downtime.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from datetime import datetime, timedelta
2+
3+
4+
def no_builds_between(start, end, *, day_of_week=None, tz=None):
5+
"""A function for "builder.canStartBuild" that implements planned downtime
6+
7+
Avoid a build to be started between start and end time and delay such
8+
builds until end time.
9+
"""
10+
11+
start = datetime.strptime(start, "%H:%M").time()
12+
end = datetime.strptime(end, "%H:%M").time()
13+
def canStartBuild(builder, wfb, request):
14+
now_dt = datetime.now(tz=tz)
15+
if day_of_week is not None and now_dt.weekday() != day_of_week:
16+
return True
17+
now = now_dt.time()
18+
if is_within_time_range(now, start, end):
19+
delay = get_delay(now, end)
20+
# Adapted from: https://docs.buildbot.net/current/manual/customization.html#canstartbuild-functions
21+
wfb.worker.quarantine_timeout = delay
22+
wfb.worker.putInQuarantine()
23+
# This does not take the worker out of quarantine, it only resets
24+
# the timeout value to default (restarting the default
25+
# exponential backoff)
26+
wfb.worker.resetQuarantine()
27+
return False
28+
# Schedule the build now
29+
return True
30+
return canStartBuild
31+
32+
33+
def is_within_time_range(now, start, end):
34+
if start <= end:
35+
return start <= now <= end
36+
else:
37+
return now >= start or now <= end
38+
39+
40+
def get_delay(now, end):
41+
today = datetime.today()
42+
now = datetime.combine(today, now)
43+
end = datetime.combine(today, end)
44+
45+
if now > end:
46+
end += timedelta(days=1)
47+
48+
difference = end - now
49+
return difference.total_seconds()

master/custom/workers.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
# vim:set ts=8 sw=4 sts=4 et:
44

55
from functools import partial
6+
from zoneinfo import ZoneInfo
7+
import calendar
68

79
from buildbot.plugins import worker as _worker
810

911
from custom.factories import MAIN_BRANCH_NAME
12+
from custom.worker_downtime import no_builds_between
1013

1114

1215
# By default, the buildmaster sends a simple, non-blocking message to each
@@ -32,6 +35,7 @@ def __init__(
3235
parallel_tests=None,
3336
timeout_factor=1,
3437
exclude_test_resources=None,
38+
downtime=None
3539
):
3640
self.name = name
3741
self.tags = tags or set()
@@ -41,6 +45,7 @@ def __init__(
4145
self.parallel_tests = parallel_tests
4246
self.timeout_factor = timeout_factor
4347
self.exclude_test_resources = exclude_test_resources or []
48+
self.downtime = downtime
4449

4550
worker_settings = settings.workers[name]
4651
owner = name.split("-")[0]
@@ -55,6 +60,14 @@ def __init__(
5560
notify_on_missing=emails,
5661
keepalive_interval=KEEPALIVE)
5762

63+
# Some of Itamar's workers are reprovisioned every Wednesday at 9am PT.
64+
# Builds scheduled between 8am - 10am PT on Wednesdays will be delayed to
65+
# 10am PT.
66+
itamaro_downtime = no_builds_between(
67+
"8:00", "10:00",
68+
day_of_week=calendar.WEDNESDAY,
69+
tz=ZoneInfo("America/Los_Angeles"),
70+
)
5871

5972
def get_workers(settings):
6073
cpw = partial(CPythonWorker, settings)
@@ -160,6 +173,10 @@ def get_workers(settings):
160173
tags=['linux', 'unix', 'ubuntu', 'arm', 'arm64', 'aarch64', 'bigmem'],
161174
not_branches=['3.10', '3.11', '3.12', '3.13', '3.14'],
162175
parallel_tests=8,
176+
# This worker runs pyperformance at 12am UTC.
177+
# If a build is scheduled between 10pm UTC and 2am UTC,
178+
# it will be delayed to 2am UTC.
179+
downtime=no_builds_between("22:00", "2:00")
163180
),
164181
cpw(
165182
name="cstratak-fedora-rawhide-s390x",
@@ -294,20 +311,28 @@ def get_workers(settings):
294311
tags=['windows', 'win11', 'amd64', 'x86-64', 'bigmem'],
295312
not_branches=['3.10', '3.11', '3.12', '3.13', '3.14'],
296313
parallel_tests=4,
314+
# This worker restarts every day at 9am UTC to work around issues
315+
# stemming from failing bigmem tests trashing disk space and
316+
# fragmenting RAM.
317+
# Builds scheduled between 07:20am - 9:20am UTC will be delayed
318+
# to 9:20am UTC.
319+
downtime=no_builds_between("7:20", "9:20")
297320
),
298321
cpw(
299322
name="itamaro-centos-aws",
300323
tags=['linux', 'unix', 'rhel', 'amd64', 'x86-64'],
301324
not_branches=['3.10', '3.11', '3.12'],
302325
parallel_tests=10,
303326
parallel_builders=2,
327+
downtime=itamaro_downtime,
304328
),
305329
cpw(
306330
name="itamaro-win64-srv-22-aws",
307331
tags=['windows', 'win-srv-22', 'amd64', 'x86-64'],
308332
not_branches=['3.10', '3.11', '3.12'],
309333
parallel_tests=10,
310334
parallel_builders=2,
335+
downtime=itamaro_downtime,
311336
),
312337
cpw(
313338
name="itamaro-macos-intel-aws",

master/master.cfg

Lines changed: 6 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ import os
1414
import subprocess
1515
import sys
1616

17-
from datetime import datetime, timedelta
17+
from datetime import timedelta
1818
from functools import partial
19-
from zoneinfo import ZoneInfo
2019

2120
from buildbot.plugins import reporters, schedulers, util
2221
from buildbot import locks
@@ -194,57 +193,13 @@ def is_important_change(change):
194193
return any(is_important_file(filename) for filename in change.files)
195194

196195

197-
def is_within_time_range(now, start, end):
198-
if start <= end:
199-
return start <= now <= end
200-
else:
201-
return now >= start or now <= end
202-
203-
204-
def get_delay(now, end):
205-
today = datetime.today()
206-
now = datetime.combine(today, now)
207-
end = datetime.combine(today, end)
208-
209-
if now > end:
210-
end += timedelta(days=1)
211-
212-
difference = end - now
213-
return difference.total_seconds()
214-
215-
216-
# Avoid a build to be started between start and end time and delay such build
217-
# at end time
218-
def no_builds_between(start, end, *, day_of_week=None, tz=None):
219-
start = datetime.strptime(start, "%H:%M").time()
220-
end = datetime.strptime(end, "%H:%M").time()
221-
def canStartBuild(builder, wfb, request):
222-
now_dt = datetime.now(tz=tz)
223-
if day_of_week is not None and now_dt.weekday() != day_of_week:
224-
return True
225-
now = now_dt.time()
226-
if is_within_time_range(now, start, end):
227-
delay = get_delay(now, end)
228-
# Adapted from: https://docs.buildbot.net/current/manual/customization.html#canstartbuild-functions
229-
wfb.worker.quarantine_timeout = delay
230-
wfb.worker.putInQuarantine()
231-
# This does not take the worker out of quarantine, it only resets
232-
# the timeout value to default (restarting the default
233-
# exponential backoff)
234-
wfb.worker.resetQuarantine()
235-
return False
236-
# Schedule the build now
237-
return True
238-
return canStartBuild
239-
240-
241196
github_status_builders = []
242197
release_status_builders = []
243198
mail_status_builders = []
244199

245200
# Regular builders
246201

247-
for branch_num, (git_url, branchname, git_branch) in enumerate(git_branches):
202+
for git_url, branchname, git_branch in git_branches:
248203
buildernames = []
249204
refleakbuildernames = []
250205
for name, worker, buildfactory, stability, tier in BUILDERS:
@@ -308,24 +263,8 @@ for branch_num, (git_url, branchname, git_branch) in enumerate(git_branches):
308263
locks=[cpulock.access("counting")],
309264
)
310265

311-
# This worker runs pyperformance at 12am UTC. If a build is scheduled between
312-
# 10pm UTC and 2am UTC, it will be delayed to 2am UTC.
313-
if worker.name == "diegorusso-aarch64-bigmem":
314-
builder.canStartBuild = no_builds_between("22:00", "2:00")
315-
316-
# This worker restarts every day at 9am UTC to work around issues stemming from
317-
# failing bigmem tests trashing disk space and fragmenting RAM. Builds scheduled
318-
# between 07:20am - 9:20am UTC will be delayed to 9:20am UTC.
319-
if worker.name == "ambv-bb-win11":
320-
builder.canStartBuild = no_builds_between("7:20", "9:20")
321-
322-
# These workers are reprovisioned every Wednesday at 9am PT. Builds
323-
# scheduled between 8am - 10am PT on Wednesdays will be delayed to
324-
# 10am PT.
325-
if worker.name in ("itamaro-win64-srv-22-aws", "itamaro-centos-aws"):
326-
builder.canStartBuild = no_builds_between(
327-
"8:00", "10:00", day_of_week=2, tz=ZoneInfo("America/Los_Angeles")
328-
)
266+
if worker.downtime:
267+
builder.canStartBuild = worker.downtime
329268

330269
c["builders"].append(builder)
331270

@@ -397,18 +336,8 @@ for name, worker, buildfactory, stability, tier in BUILDERS:
397336
locks=[cpulock.access("counting")],
398337
)
399338

400-
# This worker runs pyperformance at 12am. If a build is scheduled between
401-
# 10pm and 2am, it will be delayed at 2am.
402-
if worker.name == "diegorusso-aarch64-bigmem":
403-
builder.canStartBuild = no_builds_between("22:00", "2:00")
404-
405-
# These workers are reprovisioned every Wednesday at 9am PT. Builds
406-
# scheduled between 8am - 10am PT on Wednesdays will be delayed to
407-
# 10am PT.
408-
if worker.name in ("itamaro-win64-srv-22-aws", "itamaro-centos-aws"):
409-
builder.canStartBuild = no_builds_between(
410-
"8:00", "10:00", day_of_week=2, tz=ZoneInfo("America/Los_Angeles")
411-
)
339+
if worker.downtime:
340+
builder.canStartBuild = worker.downtime
412341

413342
c["builders"].append(builder)
414343

0 commit comments

Comments
 (0)