2023-09-10 08:11:56 +00:00
|
|
|
import multiprocessing
|
|
|
|
import os
|
|
|
|
import socket
|
2023-12-26 20:56:36 +00:00
|
|
|
from dataclasses import dataclass, field
|
2023-09-10 08:11:56 +00:00
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
from buildbot_worker.bot import Worker
|
|
|
|
from twisted.application import service
|
2024-01-01 07:32:22 +00:00
|
|
|
from twisted.python import components
|
2023-09-10 08:11:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
def require_env(key: str) -> str:
|
|
|
|
val = os.environ.get(key)
|
|
|
|
assert val is not None, "val is not set"
|
|
|
|
return val
|
|
|
|
|
|
|
|
|
2023-09-15 07:09:41 +00:00
|
|
|
@dataclass
|
|
|
|
class WorkerConfig:
|
2023-12-26 20:56:36 +00:00
|
|
|
password: str = field(
|
|
|
|
default_factory=lambda: Path(require_env("WORKER_PASSWORD_FILE"))
|
|
|
|
.read_text()
|
|
|
|
.rstrip("\r\n")
|
|
|
|
)
|
2024-04-05 13:13:11 +00:00
|
|
|
worker_arch_list: dict[str, int] = field(
|
|
|
|
default_factory=lambda: dict(other=1) | {
|
|
|
|
arch: int(count)
|
|
|
|
for arch, count in (
|
|
|
|
e.split("=")
|
|
|
|
for e in os.environ.get("WORKER_ARCH_LIST", "").split(",")
|
|
|
|
)
|
|
|
|
},
|
2024-03-15 13:47:49 +00:00
|
|
|
)
|
2023-12-26 20:56:36 +00:00
|
|
|
buildbot_dir: Path = field(
|
|
|
|
default_factory=lambda: Path(require_env("BUILDBOT_DIR"))
|
2023-09-15 07:09:41 +00:00
|
|
|
)
|
2023-12-26 20:56:36 +00:00
|
|
|
master_url: str = field(default_factory=lambda: require_env("MASTER_URL"))
|
2023-09-10 08:11:56 +00:00
|
|
|
|
|
|
|
|
2023-09-15 07:09:41 +00:00
|
|
|
def setup_worker(
|
2024-01-01 07:32:22 +00:00
|
|
|
application: components.Componentized,
|
2023-12-26 20:56:36 +00:00
|
|
|
builder_id: int,
|
2024-03-15 13:47:49 +00:00
|
|
|
arch: str,
|
2023-12-26 20:56:36 +00:00
|
|
|
config: WorkerConfig,
|
2023-09-15 07:09:41 +00:00
|
|
|
) -> None:
|
2024-03-15 13:47:49 +00:00
|
|
|
basedir = config.buildbot_dir.parent / f"{config.buildbot_dir.name}-{builder_id:03}/{arch}"
|
2023-12-26 20:56:36 +00:00
|
|
|
basedir.mkdir(parents=True, exist_ok=True, mode=0o700)
|
2023-09-10 08:11:56 +00:00
|
|
|
|
|
|
|
hostname = socket.gethostname()
|
2024-03-15 13:47:49 +00:00
|
|
|
workername = f"{hostname}-{builder_id:03}-{arch}"
|
2023-09-10 08:11:56 +00:00
|
|
|
keepalive = 600
|
|
|
|
umask = None
|
|
|
|
maxdelay = 300
|
|
|
|
numcpus = None
|
|
|
|
allow_shutdown = None
|
|
|
|
|
|
|
|
s = Worker(
|
|
|
|
None,
|
|
|
|
None,
|
|
|
|
workername,
|
2023-09-15 07:09:41 +00:00
|
|
|
config.password,
|
2023-12-27 00:12:08 +00:00
|
|
|
str(basedir),
|
2023-09-10 08:11:56 +00:00
|
|
|
keepalive,
|
2023-09-15 07:09:41 +00:00
|
|
|
connection_string=config.master_url,
|
2023-09-10 08:11:56 +00:00
|
|
|
umask=umask,
|
|
|
|
maxdelay=maxdelay,
|
|
|
|
numcpus=numcpus,
|
|
|
|
allow_shutdown=allow_shutdown,
|
|
|
|
)
|
|
|
|
# defaults to 4096, bump to 10MB for nix-eval-jobs
|
|
|
|
s.bot.max_line_length = 10485760
|
|
|
|
s.setServiceParent(application)
|
|
|
|
|
|
|
|
|
2024-01-01 07:32:22 +00:00
|
|
|
def setup_workers(application: components.Componentized, config: WorkerConfig) -> None:
|
2024-04-05 13:13:11 +00:00
|
|
|
for arch, jobs in config.worker_arch_list.items():
|
|
|
|
for i in range(jobs):
|
2024-03-15 13:47:49 +00:00
|
|
|
setup_worker(application, i, arch, config)
|
2023-09-15 07:09:41 +00:00
|
|
|
|
|
|
|
|
2023-09-10 08:11:56 +00:00
|
|
|
# note: this line is matched against to check that this is a worker
|
|
|
|
# directory; do not edit it.
|
2024-01-01 07:32:22 +00:00
|
|
|
application = service.Application("buildbot-worker") # type: ignore[no-untyped-call]
|
2023-09-15 07:09:41 +00:00
|
|
|
setup_workers(application, WorkerConfig())
|