feat: binary cache
Signed-off-by: Raito Bezarius <raito@lix.systems>
This commit is contained in:
parent
e9b3b38bbf
commit
6118daa0a4
|
@ -26,6 +26,7 @@ from buildbot.process.buildstep import CANCELLED
|
||||||
from buildbot.process.buildstep import EXCEPTION
|
from buildbot.process.buildstep import EXCEPTION
|
||||||
from buildbot.process.buildstep import SUCCESS
|
from buildbot.process.buildstep import SUCCESS
|
||||||
from buildbot.process.results import worst_status
|
from buildbot.process.results import worst_status
|
||||||
|
from buildbot_nix.binary_cache import LocalSigner
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from buildbot.process.log import Log
|
from buildbot.process.log import Log
|
||||||
|
@ -34,6 +35,8 @@ from twisted.internet import defer, threads
|
||||||
from twisted.logger import Logger
|
from twisted.logger import Logger
|
||||||
from twisted.python.failure import Failure
|
from twisted.python.failure import Failure
|
||||||
|
|
||||||
|
from .binary_cache import S3BinaryCacheConfig
|
||||||
|
|
||||||
from .github_projects import (
|
from .github_projects import (
|
||||||
slugify_project_name,
|
slugify_project_name,
|
||||||
)
|
)
|
||||||
|
@ -498,6 +501,8 @@ def nix_build_config(
|
||||||
project: GerritProject,
|
project: GerritProject,
|
||||||
worker_names: list[str],
|
worker_names: list[str],
|
||||||
outputs_path: Path | None = None,
|
outputs_path: Path | None = None,
|
||||||
|
signing_keyfile: str | None = None,
|
||||||
|
binary_cache_config: S3BinaryCacheConfig | None = None
|
||||||
) -> util.BuilderConfig:
|
) -> util.BuilderConfig:
|
||||||
"""Builds one nix flake attribute."""
|
"""Builds one nix flake attribute."""
|
||||||
factory = util.BuildFactory()
|
factory = util.BuildFactory()
|
||||||
|
@ -528,6 +533,39 @@ def nix_build_config(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if signing_keyfile is not None:
|
||||||
|
factory.addStep(
|
||||||
|
steps.ShellCommand(
|
||||||
|
name="Sign the store path",
|
||||||
|
command=[
|
||||||
|
"nix",
|
||||||
|
"store",
|
||||||
|
"sign",
|
||||||
|
"--keyfile",
|
||||||
|
signing_keyfile,
|
||||||
|
util.Interpolate(
|
||||||
|
"%(prop:drv_path)s^*"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if binary_cache_config is not None:
|
||||||
|
factory.addStep(
|
||||||
|
steps.ShellCommand(
|
||||||
|
name="Upload the store path to the cache",
|
||||||
|
command=[
|
||||||
|
"nix",
|
||||||
|
"copy",
|
||||||
|
"--to",
|
||||||
|
f"s3://{binary_cache_config.bucket}?profile={binary_cache_config.profile}®ion={binary_cache_config.region}&endpoint={binary_cache_config.endpoint}",
|
||||||
|
util.Property(
|
||||||
|
"out_path"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
factory.addStep(
|
factory.addStep(
|
||||||
steps.ShellCommand(
|
steps.ShellCommand(
|
||||||
name="Register gcroot",
|
name="Register gcroot",
|
||||||
|
@ -586,6 +624,8 @@ def config_for_project(
|
||||||
nix_eval_max_memory_size: int,
|
nix_eval_max_memory_size: int,
|
||||||
eval_lock: util.MasterLock,
|
eval_lock: util.MasterLock,
|
||||||
outputs_path: Path | None = None,
|
outputs_path: Path | None = None,
|
||||||
|
signing_keyfile: str | None = None,
|
||||||
|
binary_cache_config: S3BinaryCacheConfig | None = None
|
||||||
) -> Project:
|
) -> Project:
|
||||||
config["projects"].append(Project(project.name))
|
config["projects"].append(Project(project.name))
|
||||||
config["schedulers"].extend(
|
config["schedulers"].extend(
|
||||||
|
@ -642,6 +682,8 @@ def config_for_project(
|
||||||
project,
|
project,
|
||||||
worker_names,
|
worker_names,
|
||||||
outputs_path=outputs_path,
|
outputs_path=outputs_path,
|
||||||
|
signing_keyfile=signing_keyfile,
|
||||||
|
binary_cache_config=binary_cache_config
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -742,6 +784,8 @@ class GerritNixConfigurator(ConfiguratorBase):
|
||||||
nix_eval_worker_count: int | None,
|
nix_eval_worker_count: int | None,
|
||||||
nix_eval_max_memory_size: int,
|
nix_eval_max_memory_size: int,
|
||||||
nix_workers_secret_name: str = "buildbot-nix-workers", # noqa: S107
|
nix_workers_secret_name: str = "buildbot-nix-workers", # noqa: S107
|
||||||
|
signing_keyfile: str | None = None,
|
||||||
|
binary_cache_config: dict[str, str] | None = None,
|
||||||
outputs_path: str | None = None,
|
outputs_path: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@ -754,6 +798,11 @@ class GerritNixConfigurator(ConfiguratorBase):
|
||||||
self.nix_supported_systems = nix_supported_systems
|
self.nix_supported_systems = nix_supported_systems
|
||||||
self.gerrit_change_source = GerritChangeSource(gerrit_server, gerrit_user, gerritport=gerrit_port, identity_file=gerrit_sshkey_path)
|
self.gerrit_change_source = GerritChangeSource(gerrit_server, gerrit_user, gerritport=gerrit_port, identity_file=gerrit_sshkey_path)
|
||||||
self.url = url
|
self.url = url
|
||||||
|
if binary_cache_config is not None:
|
||||||
|
self.binary_cache_config = S3BinaryCacheConfig(**binary_cache_config)
|
||||||
|
else:
|
||||||
|
self.binary_cache_config = None
|
||||||
|
self.signing_keyfile = signing_keyfile
|
||||||
if outputs_path is None:
|
if outputs_path is None:
|
||||||
self.outputs_path = None
|
self.outputs_path = None
|
||||||
else:
|
else:
|
||||||
|
@ -786,6 +835,8 @@ class GerritNixConfigurator(ConfiguratorBase):
|
||||||
self.nix_eval_max_memory_size,
|
self.nix_eval_max_memory_size,
|
||||||
eval_lock,
|
eval_lock,
|
||||||
self.outputs_path,
|
self.outputs_path,
|
||||||
|
signing_keyfile=self.signing_keyfile,
|
||||||
|
binary_cache_config=self.binary_cache_config
|
||||||
)
|
)
|
||||||
|
|
||||||
config["change_source"] = self.gerrit_change_source
|
config["change_source"] = self.gerrit_change_source
|
||||||
|
|
12
buildbot_nix/binary_cache.py
Normal file
12
buildbot_nix/binary_cache.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class S3BinaryCacheConfig:
|
||||||
|
region: str
|
||||||
|
bucket: str
|
||||||
|
endpoint: str
|
||||||
|
profile: str
|
||||||
|
|
||||||
|
class LocalSigner:
|
||||||
|
def __init__(self, keyfile: str):
|
||||||
|
self.keyfile = keyfile
|
|
@ -57,6 +57,34 @@ in
|
||||||
default = null;
|
default = null;
|
||||||
example = "/var/www/buildbot/nix-outputs";
|
example = "/var/www/buildbot/nix-outputs";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
binaryCache = {
|
||||||
|
enable = lib.mkEnableOption " binary cache upload to a S3 bucket";
|
||||||
|
profileCredentialsFile = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.path;
|
||||||
|
description = "A path to the various AWS profile credentials related to the S3 bucket containing a profile named `default`";
|
||||||
|
default = null;
|
||||||
|
example = "/run/agenix.d/aws-profile";
|
||||||
|
};
|
||||||
|
bucket = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
description = "Bucket where to store the data";
|
||||||
|
default = null;
|
||||||
|
example = "lix-cache";
|
||||||
|
};
|
||||||
|
endpoint = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
description = "Endpoint for the S3 server";
|
||||||
|
default = null;
|
||||||
|
example = "s3.lix.systems";
|
||||||
|
};
|
||||||
|
region = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
description = "Region for the S3 bucket";
|
||||||
|
default = null;
|
||||||
|
example = "garage";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
@ -97,6 +125,10 @@ in
|
||||||
nix_eval_worker_count=${if cfg.evalWorkerCount == null then "None" else builtins.toString cfg.evalWorkerCount},
|
nix_eval_worker_count=${if cfg.evalWorkerCount == null then "None" else builtins.toString cfg.evalWorkerCount},
|
||||||
nix_supported_systems=${builtins.toJSON cfg.buildSystems},
|
nix_supported_systems=${builtins.toJSON cfg.buildSystems},
|
||||||
outputs_path=${if cfg.outputsPath == null then "None" else builtins.toJSON cfg.outputsPath},
|
outputs_path=${if cfg.outputsPath == null then "None" else builtins.toJSON cfg.outputsPath},
|
||||||
|
binary_cache_config=${if (!cfg.binaryCache.enable) then "None" else builtins.toJSON {
|
||||||
|
inherit (cfg.binaryCache) bucket region endpoint;
|
||||||
|
profile = "default";
|
||||||
|
}}
|
||||||
)
|
)
|
||||||
''
|
''
|
||||||
];
|
];
|
||||||
|
@ -117,6 +149,20 @@ in
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# TODO(raito): we assume worker runs on coordinator. please clean up this later.
|
||||||
|
systemd.services.buildbot-worker.serviceConfig.Environment =
|
||||||
|
let
|
||||||
|
awsConfigFile = pkgs.writeText "config.ini" ''
|
||||||
|
[default]
|
||||||
|
region = ${cfg.binaryCache.region}
|
||||||
|
endpoint_url = ${cfg.binaryCache.endpoint}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
[
|
||||||
|
"AWS_CONFIG_FILE=${awsConfigFile}"
|
||||||
|
"AWS_SHARED_CREDENTIALS_FILE=${cfg.binaryCache.profileCredentialsFile}"
|
||||||
|
];
|
||||||
|
|
||||||
systemd.services.buildbot-master = {
|
systemd.services.buildbot-master = {
|
||||||
after = [ "postgresql.service" ];
|
after = [ "postgresql.service" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
|
Loading…
Reference in a new issue