Skip to content

Commit a3e0e92

Browse files
authored
Merge pull request #413 from nix-community/worker-count
builder_worker: make number of workers configureable
2 parents 9534a32 + be4eae7 commit a3e0e92

File tree

10 files changed

+123
-25
lines changed

10 files changed

+123
-25
lines changed

buildbot_nix/buildbot_nix/__init__.py

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,7 @@ async def run_vc(
988988
pr_head = build_props.getProperty("github.head.sha") or build_props.getProperty(
989989
"head_sha"
990990
)
991+
auth_workdir = self._get_auth_data_workdir()
991992

992993
# Not a PR, fallback to default behavior
993994
if merge_base is None or pr_head is None:
@@ -1007,33 +1008,42 @@ async def run_vc(
10071008
self.build.path_module.join(self.workdir, ".git")
10081009
)
10091010

1010-
if not has_git:
1011-
await self._dovccmd(["clone", "--recurse-submodules", self.repourl, "."])
1011+
try:
1012+
await self._git_auth.download_auth_files_if_needed(auth_workdir)
10121013

1013-
patched = await self.sourcedirIsPatched()
1014+
if not has_git:
1015+
await self._dovccmd(
1016+
["clone", "--recurse-submodules", self.repourl, "."]
1017+
)
10141018

1015-
if patched:
1016-
await self._dovccmd(["clean", "-f", "-f", "-d", "-x"])
1019+
patched = await self.sourcedirIsPatched()
10171020

1018-
await self._dovccmd(["fetch", "-f", "-t", self.repourl, merge_base, pr_head])
1021+
if patched:
1022+
await self._dovccmd(["clean", "-f", "-f", "-d", "-x"])
10191023

1020-
await self._dovccmd(["checkout", "--detach", "-f", pr_head])
1024+
await self._dovccmd(
1025+
["fetch", "-f", "-t", self.repourl, merge_base, pr_head]
1026+
)
10211027

1022-
await self._dovccmd(
1023-
[
1024-
"-c",
1025-
"user.email=buildbot@example.com",
1026-
"-c",
1027-
"user.name=buildbot",
1028-
"merge",
1029-
"--no-ff",
1030-
"-m",
1031-
f"Merge {merge_base} into {pr_head}",
1032-
merge_base,
1033-
]
1034-
)
1035-
self.updateSourceProperty("got_revision", pr_head)
1036-
return await self.parseCommitDescription()
1028+
await self._dovccmd(["checkout", "--detach", "-f", pr_head])
1029+
1030+
await self._dovccmd(
1031+
[
1032+
"-c",
1033+
"user.email=buildbot@example.com",
1034+
"-c",
1035+
"user.name=buildbot",
1036+
"merge",
1037+
"--no-ff",
1038+
"-m",
1039+
f"Merge {merge_base} into {pr_head}",
1040+
merge_base,
1041+
]
1042+
)
1043+
self.updateSourceProperty("got_revision", pr_head)
1044+
return await self.parseCommitDescription()
1045+
finally:
1046+
await self._git_auth.remove_auth_files_if_needed(auth_workdir)
10371047

10381048

10391049
def nix_eval_config(
@@ -1060,6 +1070,12 @@ def nix_eval_config(
10601070
submodules=True,
10611071
haltOnFailure=True,
10621072
logEnviron=False,
1073+
sshPrivateKey=project.private_key_path.read_text()
1074+
if project.private_key_path
1075+
else None,
1076+
sshKnownHosts=project.known_hosts_path.read_text()
1077+
if project.known_hosts_path
1078+
else None,
10631079
),
10641080
)
10651081
drv_gcroots_dir = util.Interpolate(
@@ -1368,6 +1384,8 @@ def nix_skipped_build_config(
13681384
collapseRequests=False,
13691385
env={},
13701386
factory=factory,
1387+
do_build_if=lambda build: do_register_gcroot_if(build, branch_config_dict)
1388+
and outputs_path is not None,
13711389
)
13721390

13731391

@@ -1417,6 +1435,12 @@ def buildbot_effects_config(
14171435
method="clean",
14181436
submodules=True,
14191437
haltOnFailure=True,
1438+
sshPrivateKey=project.private_key_path.read_text()
1439+
if project.private_key_path
1440+
else None,
1441+
sshKnownHosts=project.known_hosts_path.read_text()
1442+
if project.known_hosts_path
1443+
else None,
14201444
),
14211445
)
14221446
secrets_list = []

buildbot_nix/buildbot_nix/gitea_projects.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ def __init__(
6161

6262
def get_project_url(self) -> str:
6363
url = urlparse(self.config.instance_url)
64+
if self.config.ssh_private_key_file:
65+
return self.data.ssh_url
6466
return f"{url.scheme}://git:%(secret:{self.config.token_file})s@{url.hostname}/{self.name}"
6567

6668
def create_change_source(self) -> ChangeSource | None:
@@ -113,6 +115,14 @@ def belongs_to_org(self) -> bool:
113115
# TODO Gitea doesn't include this information
114116
return False # self.data["owner"]["type"] == "Organization"
115117

118+
@property
119+
def private_key_path(self) -> Path | None:
120+
return self.config.ssh_private_key_file
121+
122+
@property
123+
def known_hosts_path(self) -> Path | None:
124+
return self.config.ssh_known_hosts_file
125+
116126

117127
class GiteaBackend(GitBackend):
118128
config: GiteaConfig

buildbot_nix/buildbot_nix/github_projects.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,14 @@ def topics(self) -> list[str]:
770770
def belongs_to_org(self) -> bool:
771771
return self.data.owner.ttype == "Organization"
772772

773+
@property
774+
def private_key_path(self) -> Path | None:
775+
return None
776+
777+
@property
778+
def known_hosts_path(self) -> Path | None:
779+
return None
780+
773781

774782
def refresh_projects(
775783
github_token: str,

buildbot_nix/buildbot_nix/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ class GiteaConfig(BaseModel):
6767
oauth_id: str | None
6868
oauth_secret_file: Path | None
6969

70+
ssh_private_key_file: Path | None
71+
ssh_known_hosts_file: Path | None
72+
7073
@property
7174
def token(self) -> str:
7275
return read_secret_file(self.token_file)

buildbot_nix/buildbot_nix/projects.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from abc import ABC, abstractmethod
2+
from pathlib import Path
23
from typing import Any
34

45
from buildbot.changes.base import ChangeSource
@@ -125,3 +126,13 @@ def topics(self) -> list[str]:
125126
@abstractmethod
126127
def belongs_to_org(self) -> bool:
127128
pass
129+
130+
@property
131+
@abstractmethod
132+
def private_key_path(self) -> Path | None:
133+
pass
134+
135+
@property
136+
@abstractmethod
137+
def known_hosts_path(self) -> Path | None:
138+
pass

buildbot_nix/buildbot_nix/pull_based/project.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from pathlib import Path
12
from typing import Any
23
from urllib.parse import ParseResult, urlparse
34

@@ -99,3 +100,11 @@ def topics(self) -> list[str]:
99100
@property
100101
def belongs_to_org(self) -> bool:
101102
return False
103+
104+
@property
105+
def private_key_path(self) -> Path | None:
106+
return None
107+
108+
@property
109+
def known_hosts_path(self) -> Path | None:
110+
return None

buildbot_nix/buildbot_nix/worker.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ class WorkerConfig:
2525
worker_name: str = field(
2626
default_factory=lambda: os.environ.get("WORKER_NAME", socket.gethostname())
2727
)
28-
worker_count: int = int(
29-
os.environ.get("WORKER_COUNT", str(multiprocessing.cpu_count())),
30-
)
28+
worker_count_str: str | None = os.environ.get("WORKER_COUNT")
29+
if worker_count_str is not None:
30+
worker_count = int(worker_count_str)
31+
else:
32+
worker_count = multiprocessing.cpu_count()
3133
buildbot_dir: Path = field(
3234
default_factory=lambda: Path(require_env("BUILDBOT_DIR"))
3335
)

examples/worker.nix

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,8 @@
33
services.buildbot-nix.worker = {
44
enable = true;
55
workerPasswordFile = pkgs.writeText "worker-password-file" "XXXXXXXXXXXXXXXXXXXX";
6+
# The number of workers to start (default: 0 == the number of CPU cores).
7+
# If you experience flaky builds under high load, try to reduce this value.
8+
# workers = 0;
69
};
710
}

nix/master.nix

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,23 @@ in
313313
If null, all projects that the buildbot Gitea user has access to, are built.
314314
'';
315315
};
316+
317+
sshPrivateKeyFile = lib.mkOption {
318+
type = lib.types.nullOr lib.types.path;
319+
default = null;
320+
description = ''
321+
If non-null the specified SSH key will be used to fetch all configured repositories.
322+
'';
323+
};
324+
325+
sshKnownHostsFile = lib.mkOption {
326+
type = lib.types.nullOr lib.types.path;
327+
default = null;
328+
description = ''
329+
If non-null the specified known hosts file will be matched against when connecting to
330+
repositories over SSH.
331+
'';
332+
};
316333
};
317334
github = {
318335
enable = lib.mkEnableOption "Enable GitHub integration" // {
@@ -702,6 +719,8 @@ in
702719
instance_url = cfg.gitea.instanceUrl;
703720
oauth_id = cfg.gitea.oauthId;
704721
topic = cfg.gitea.topic;
722+
ssh_private_key_file = cfg.gitea.sshPrivateKeyFile;
723+
ssh_known_hosts_file = cfg.gitea.sshKnownHostsFile;
705724
};
706725
github =
707726
if !cfg.github.enable then

nix/worker.nix

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ in
5656
default = pkgs.nix-eval-jobs;
5757
description = "nix-eval-jobs to use for evaluation";
5858
};
59+
workers = lib.mkOption {
60+
type = lib.types.int;
61+
default = 0;
62+
description = ''
63+
The number of workers to start (default: 0 == to the number of CPU cores).
64+
If you experience flaky builds under high load, try to reduce this value.
65+
'';
66+
};
5967
masterUrl = lib.mkOption {
6068
type = lib.types.str;
6169
default = "tcp:host=localhost:port=9989";
@@ -114,6 +122,7 @@ in
114122
}/${packages.python.sitePackages}";
115123
environment.MASTER_URL = cfg.masterUrl;
116124
environment.BUILDBOT_DIR = buildbotDir;
125+
environment.WORKER_COUNT = builtins.toString cfg.workers;
117126

118127
serviceConfig = {
119128
# We rather want the CI job to fail on OOM than to have a broken buildbot worker.

0 commit comments

Comments
 (0)