Skip to content

Commit cbc79e1

Browse files
authored
Merge pull request #430 from nix-community/flake-restructure
Add a local dev workflow
2 parents 004e4a4 + 9d34651 commit cbc79e1

File tree

10 files changed

+148
-46
lines changed

10 files changed

+148
-46
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
result
22
result-*
33

4+
.buildbot-dev
5+
46
# Byte-compiled / optimized / DLL files
57
__pycache__/
68
*.py[cod]

buildbot_nix/buildbot_nix/__init__.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,7 @@ def config_for_project(
10791079
config["builders"].extend(
10801080
[
10811081
# Since all workers run on the same machine, we only assign one of them to do the evaluation.
1082-
# This should prevent exessive memory usage.
1082+
# This should prevent excessive memory usage.
10831083
nix_eval_config(
10841084
project,
10851085
worker_names,
@@ -1289,6 +1289,10 @@ def configure(self, config: dict[str, Any]) -> None:
12891289
config.setdefault("projects", [])
12901290
config.setdefault("secretsProviders", [])
12911291
config.setdefault("www", {})
1292+
config.setdefault("workers", [])
1293+
config.setdefault("services", [])
1294+
config.setdefault("schedulers", [])
1295+
config.setdefault("builders", [])
12921296

12931297
worker_names = []
12941298
for w in self.config.nix_worker_secrets().workers:
@@ -1297,8 +1301,13 @@ def configure(self, config: dict[str, Any]) -> None:
12971301
config["workers"].append(worker.Worker(worker_name, w.password))
12981302
worker_names.append(worker_name)
12991303

1304+
for i in range(self.config.local_workers):
1305+
worker_name = f"local-{i}"
1306+
config["workers"].append(worker.LocalWorker(worker_name))
1307+
worker_names.append(worker_name)
1308+
13001309
if worker_names == []:
1301-
msg = f"No workers configured in {self.config.nix_workers_secret_file}"
1310+
msg = f"No workers configured in {self.config.nix_workers_secret_file} and {self.config.local_workers} local workers."
13021311
raise BuildbotNixError(msg)
13031312

13041313
eval_lock = util.MasterLock("nix-eval")
@@ -1362,9 +1371,9 @@ def configure(self, config: dict[str, Any]) -> None:
13621371
config.setdefault("secretsProviders", [])
13631372
config["secretsProviders"].extend(backend.create_secret_providers())
13641373

1365-
systemd_secrets = SecretInAFile(
1366-
dirname=os.environ["CREDENTIALS_DIRECTORY"],
1367-
)
1374+
credentials_directory = os.environ.get("CREDENTIALS_DIRECTORY", "./secrets")
1375+
Path(credentials_directory).mkdir(exist_ok=True, parents=True)
1376+
systemd_secrets = SecretInAFile(dirname=credentials_directory)
13681377
config["secretsProviders"].append(systemd_secrets)
13691378

13701379
config["www"].setdefault("plugins", {})

buildbot_nix/buildbot_nix/models.py

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import json
22
import os
33
import re
4-
import sys
54
from collections.abc import Callable, Mapping
65
from enum import Enum
76
from pathlib import Path
@@ -32,8 +31,7 @@ class AuthBackendConfig(str, Enum):
3231
def read_secret_file(secret_file: Path) -> str:
3332
directory = os.environ.get("CREDENTIALS_DIRECTORY")
3433
if directory is None:
35-
print("directory not set", file=sys.stderr)
36-
sys.exit(1)
34+
return secret_file.read_text().rstrip()
3735
return Path(directory).joinpath(secret_file).read_text().rstrip()
3836

3937

@@ -92,10 +90,10 @@ class PullBasedRepository(BaseModel):
9290
name: str
9391
default_branch: str
9492
url: str
95-
poll_interval: int
93+
poll_interval: int = 60
9694

97-
ssh_private_key_file: Path | None
98-
ssh_known_hosts_file: Path | None
95+
ssh_private_key_file: Path | None = None
96+
ssh_known_hosts_file: Path | None = None
9997

10098
@property
10199
def ssh_private_key(self) -> str | None:
@@ -112,7 +110,7 @@ def ssh_known_hosts(self) -> str | None:
112110

113111
class PullBasedConfig(BaseModel):
114112
repositories: dict[str, PullBasedRepository]
115-
poll_spread: int | None
113+
poll_spread: int | None = None
116114

117115

118116
class GitHubLegacyConfig(BaseModel):
@@ -263,28 +261,32 @@ class WorkerConfig(BaseModel):
263261

264262
class BuildbotNixConfig(BaseModel):
265263
db_url: str
266-
auth_backend: AuthBackendConfig
267-
gitea: GiteaConfig | None
268-
github: GitHubConfig | None
269-
pull_based: PullBasedConfig | None
270-
admins: list[str]
271-
workers_file: Path
272264
build_systems: list[str]
273-
eval_max_memory_size: int
274-
eval_worker_count: int | None
275-
nix_workers_secret_file: Path = Field(default=Path("buildbot-nix-workers"))
276265
domain: str
277266
webhook_base_url: str
278-
use_https: bool
279-
outputs_path: Path | None
280267
url: str
281-
post_build_steps: list[PostBuildStep]
282-
job_report_limit: int | None
283-
http_basic_auth_password_file: Path | None
284-
effects_per_repo_secrets: dict[str, str]
285-
branches: BranchConfigDict
268+
269+
use_https: bool = False
270+
auth_backend: AuthBackendConfig = AuthBackendConfig.none
271+
eval_max_memory_size: int = 4096
272+
admins: list[str] = []
273+
local_workers: int = 0
274+
eval_worker_count: int | None = None
275+
gitea: GiteaConfig | None = None
276+
github: GitHubConfig | None = None
277+
pull_based: PullBasedConfig | None
278+
outputs_path: Path | None = None
279+
post_build_steps: list[PostBuildStep] = []
280+
job_report_limit: int | None = None
281+
http_basic_auth_password_file: Path | None = None
282+
branches: BranchConfigDict = BranchConfigDict({})
283+
284+
nix_workers_secret_file: Path | None = None
285+
effects_per_repo_secrets: dict[str, str] = {}
286286

287287
def nix_worker_secrets(self) -> WorkerConfig:
288+
if self.nix_workers_secret_file is None:
289+
return WorkerConfig(workers=[])
288290
try:
289291
data = json.loads(read_secret_file(self.nix_workers_secret_file))
290292
except json.JSONDecodeError as e:

buildbot_nix/pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,18 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "buildbot-nix"
7+
license = "MIT"
78
authors = [
89
{ name = "Jörg Thalheim", email = "joerg@thalheim.io" },
910
]
1011
description = "A nixos module to make buildbot a proper Nix-CI."
1112
readme = "README.rst"
1213
requires-python = ">=3.9"
13-
license = {text = "MIT"}
1414
classifiers = [
1515
"Programming Language :: Python :: 3",
1616
"Development Status :: 5 - Production/Stable",
1717
"Environment :: Console",
1818
"Topic :: Utilities",
19-
"License :: OSI Approved :: MIT License",
2019
"Operating System :: OS Independent",
2120
"Programming Language :: Python"
2221
]

nixosModules/master.nix

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ let
1313
name = "interpolate";
1414

1515
description = ''
16-
A type represnting a Buildbot interpolation string, supports interpolations like `result-%(prop:attr)s`.
16+
A type representing a Buildbot interpolation string, supports interpolations like `result-%(prop:attr)s`.
1717
'';
1818

1919
check = x: x ? "_type" && x._type == "interpolate" && x ? "value";
@@ -453,7 +453,7 @@ in
453453
type = lib.types.addCheck lib.types.int (x: x > 0);
454454
default = 60;
455455
description = ''
456-
How often to poll each repository by default expressed in seconds. This value can be overriden
456+
How often to poll each repository by default expressed in seconds. This value can be overridden
457457
per repository.
458458
'';
459459
};
@@ -462,7 +462,7 @@ in
462462
type = lib.types.nullOr lib.types.int;
463463
default = null;
464464
description = ''
465-
If non-null and non-zero pulls will be randomly spread apart up to the specificied
465+
If non-null and non-zero pulls will be randomly spread apart up to the specified
466466
number of seconds. Can be used to avoid a thundering herd situation.
467467
'';
468468
};
@@ -472,7 +472,7 @@ in
472472
default = null;
473473
description = ''
474474
If non-null the specified SSH key will be used to fetch all configured repositories.
475-
This option is overriden by the per-repository `sshPrivateKeyFile` option.
475+
This option is overridden by the per-repository `sshPrivateKeyFile` option.
476476
'';
477477
};
478478

@@ -481,7 +481,7 @@ in
481481
default = null;
482482
description = ''
483483
If non-null the specified known hosts file will be matched against when connecting to
484-
repositories over SSH. This option is overriden by the per-repository `sshKnownHostsFile`
484+
repositories over SSH. This option is overridden by the per-repository `sshKnownHostsFile`
485485
option.
486486
'';
487487
};
@@ -764,7 +764,6 @@ in
764764
poll_spread = cfg.pullBased.pollSpread;
765765
};
766766
admins = cfg.admins;
767-
workers_file = cfg.workersFile;
768767
build_systems = cfg.buildSystems;
769768
eval_max_memory_size = cfg.evalMaxMemorySize;
770769
eval_worker_count = cfg.evalWorkerCount;
@@ -781,6 +780,7 @@ in
781780
value = "effects-secret__${cleanUpRepoName name}";
782781
}) cfg.effects.perRepoSecretFiles;
783782
branches = cfg.branches;
783+
nix_workers_secret_file = "buildbot-nix-workers";
784784
}
785785
}").read_text()))
786786
)

nixosModules/packages.nix

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,7 @@ in
1818

1919
buildbot = lib.mkOption {
2020
type = lib.types.package;
21-
default = pkgs.buildbot.overrideAttrs (o: {
22-
patches = o.patches ++ [
23-
(pkgs.fetchpatch {
24-
name = "add-Build.skipBuildIf.patch";
25-
url = "https://github.com/buildbot/buildbot/commit/f08eeef96e15c686a4f6ad52368ad08246314751.patch";
26-
hash = "sha256-ACPYXMbjIfw02gsKwmDKIIZkGSxxLWCaW7ceEcgbtIU=";
27-
})
28-
];
29-
});
21+
default = pkgs.callPackage ../packages/buildbot.nix { };
3022
};
3123

3224
buildbot-worker = lib.mkOption {

packages/buildbot-dev.nix

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
writeShellScriptBin,
3+
python,
4+
buildbot,
5+
buildbot-worker,
6+
buildbot-nix,
7+
buildbot-gitea,
8+
buildbot-effects,
9+
buildbot-plugins,
10+
}:
11+
let
12+
pythonEnv = python.withPackages (ps: [
13+
ps.twisted
14+
(ps.toPythonModule buildbot)
15+
(ps.toPythonModule buildbot-worker)
16+
buildbot-nix
17+
buildbot-gitea
18+
buildbot-effects
19+
buildbot-plugins.www
20+
]);
21+
in
22+
writeShellScriptBin "buildbot-dev" ''
23+
set -xeuo pipefail
24+
git_root=$(git rev-parse --show-toplevel)
25+
mkdir -p "$git_root/.buildbot-dev"
26+
cd "$git_root/.buildbot-dev"
27+
"${pythonEnv}/bin/buildbot" create-master .
28+
#if [ ! -f master.cfg ]; then
29+
install -m600 ${./master.cfg.py} master.cfg
30+
#fi
31+
echo > $git_root/.buildbot-dev/twistd.log
32+
tail -f $git_root/.buildbot-dev/twistd.log &
33+
tail_pid=$!
34+
trap 'kill $tail_pid' EXIT
35+
"${pythonEnv}/bin/buildbot" start --nodaemon .
36+
''

packages/buildbot.nix

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{ buildbot, fetchpatch }:
2+
buildbot.overrideAttrs (o: {
3+
patches = o.patches ++ [
4+
(fetchpatch {
5+
name = "add-Build.skipBuildIf.patch";
6+
url = "https://github.com/buildbot/buildbot/commit/f08eeef96e15c686a4f6ad52368ad08246314751.patch";
7+
hash = "sha256-ACPYXMbjIfw02gsKwmDKIIZkGSxxLWCaW7ceEcgbtIU=";
8+
})
9+
];
10+
})

packages/flake-module.nix

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,23 @@
33
{
44
lib,
55
pkgs,
6+
self',
67
...
78
}:
89
{
910
packages =
1011
{
1112
# useful for checking what buildbot version is used.
12-
buildbot = pkgs.buildbot;
13+
buildbot = pkgs.callPackage ./buildbot.nix { };
14+
buildbot-dev = pkgs.python3.pkgs.callPackage ./buildbot-dev.nix {
15+
inherit (self'.packages)
16+
buildbot-gitea
17+
buildbot-effects
18+
buildbot-nix
19+
buildbot
20+
;
21+
inherit (pkgs) buildbot-worker buildbot-plugins;
22+
};
1323
buildbot-nix = pkgs.python3.pkgs.callPackage ./buildbot-nix.nix { };
1424
buildbot-gitea = pkgs.python3.pkgs.callPackage ./buildbot-gitea.nix {
1525
buildbot = pkgs.buildbot;

packages/master.cfg.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from pathlib import Path
2+
from buildbot_nix import (
3+
NixConfigurator,
4+
BuildbotNixConfig,
5+
)
6+
from buildbot.process.factory import BuildFactory
7+
8+
factory = BuildFactory()
9+
10+
STATE_DIR = Path(".")
11+
PORT = 8012
12+
13+
buildbot_nix_config = BuildbotNixConfig(
14+
db_url="sqlite:///state.sqlite",
15+
pull_based=dict(
16+
repositories={
17+
"buildbot-nix": dict(
18+
name="buildbot-nix",
19+
url="https://github.com/nix-community/buildbot-nix",
20+
default_branch="main",
21+
)
22+
},
23+
poll_spread=None,
24+
),
25+
build_systems=["x86_64-linux"],
26+
eval_max_memory_size=4096,
27+
eval_worker_count=4,
28+
local_workers=4,
29+
domain="localhost",
30+
webhook_base_url=f"http://localhost:{PORT}",
31+
url=f"http://localhost:{PORT}",
32+
)
33+
34+
c = BuildmasterConfig = dict(
35+
title="Hello World CI",
36+
titleURL="https://buildbot.github.io/hello-world/",
37+
configurators=[
38+
NixConfigurator(buildbot_nix_config),
39+
],
40+
protocols={"pb": {"port": "tcp:9989:interface=\\:\\:1"}},
41+
www=dict(port=PORT, plugins=dict()),
42+
)

0 commit comments

Comments
 (0)