stockholm/krebs/3modules/ci.nix

203 lines
6.3 KiB
Nix
Raw Normal View History

2018-09-09 18:01:51 +00:00
{ config, lib, pkgs, ... }:
with import <stockholm/lib>;
let
cfg = config.krebs.ci;
out = {
options.krebs.ci = api;
config = lib.mkIf cfg.enable imp;
};
api = {
enable = mkEnableOption "Enable krebs ci service";
repos = mkOption {
type = types.attrsOf (types.submodule ({ config, ...}: {
options = {
urls = mkOption {
type = types.listOf types.str;
default = [ "git@localhost:${config._module.args.name}" ];
};
};
}));
};
};
hostname = config.networking.hostName;
getJobs = pkgs.writeDash "get_jobs" ''
set -efu
2019-09-25 18:40:22 +00:00
${pkgs.nix}/bin/nix-build --no-out-link --quiet --show-trace -Q ./ci.nix >&2
2018-11-27 20:06:20 +00:00
json="$(${pkgs.nix}/bin/nix-instantiate --quiet -Q --eval --strict --json ./ci.nix)"
echo "$json" | ${pkgs.jq}/bin/jq -r 'to_entries[] | [.key, .value] | @tsv' \
2018-11-26 23:58:07 +00:00
| while read -r host builder; do
gcroot=${shell.escape profileRoot}/$host-builder
${pkgs.nix}/bin/nix-env -p "$gcroot" --set "$builder"
done
2018-11-27 20:06:20 +00:00
echo "$json"
2018-09-09 18:01:51 +00:00
'';
2018-11-13 20:38:28 +00:00
profileRoot = "/nix/var/nix/profiles/ci";
2018-09-09 18:01:51 +00:00
imp = {
krebs.buildbot.master = {
slaves = {
testslave = "lasspass";
};
change_source = mapAttrs' (name: repo:
nameValuePair name (concatMapStrings (url: ''
cs.append(
changes.GitPoller(
"${url}",
workdir='${name}-${elemAt(splitString "." url) 1}', branches=True,
project='${name}',
pollinterval=10
)
)
'') repo.urls)
) cfg.repos;
scheduler = mapAttrs' (name: repo:
nameValuePair name ''
sched.append(
schedulers.SingleBranchScheduler(
2018-09-13 12:41:58 +00:00
change_filter=util.ChangeFilter(
branch_re=".*",
project='${name}',
),
2018-09-09 18:01:51 +00:00
treeStableTimer=60,
2018-09-13 12:41:58 +00:00
name="${name}-all-branches",
2018-09-09 18:01:51 +00:00
builderNames=[
"${name}",
]
)
)
sched.append(
schedulers.ForceScheduler(
name="${name}",
builderNames=[
"${name}",
]
)
)
''
) cfg.repos;
builder_pre = ''
from buildbot import interfaces
from buildbot.steps.shell import ShellCommand
class StepToStartMoreSteps(ShellCommand):
def __init__(self, **kwargs):
ShellCommand.__init__(self, **kwargs)
def addBuildSteps(self, steps_factories):
for sf in steps_factories:
step = interfaces.IBuildStepFactory(sf).buildStep()
step.setBuild(self.build)
step.setBuildSlave(self.build.slavebuilder.slave)
step_status = self.build.build_status.addStepWithName(step.name)
step.setStepStatus(step_status)
self.build.steps.append(step)
def start(self):
props = self.build.getProperties()
new_steps = json.loads(props.getProperty('steps_json'))
for new_step in new_steps:
self.addBuildSteps([steps.ShellCommand(
name=str(new_step),
command=[
2018-11-13 20:38:28 +00:00
"${pkgs.writeDash "build-stepper.sh" ''
set -xefu
2018-11-13 20:38:28 +00:00
profile=${shell.escape profileRoot}/$build_name
result=$("$build_script")
if [ -n "$result" ]; then
${pkgs.nix}/bin/nix-env -p "$profile" --set "$result"
fi
2018-11-13 20:38:28 +00:00
''}"
2018-09-09 18:01:51 +00:00
],
2018-09-14 09:41:12 +00:00
env={
2018-11-13 20:38:28 +00:00
"build_name": new_step,
"build_script": new_steps[new_step],
2018-09-14 09:41:12 +00:00
"NIX_REMOTE": "daemon",
"NIX_PATH": "secrets=/var/src/stockholm/null:/var/src",
},
2018-09-09 18:01:51 +00:00
timeout=90001,
workdir='build', # TODO figure out why we need this?
)])
ShellCommand.start(self)
'';
builder = mapAttrs' (name: repo:
nameValuePair name ''
f_${name} = util.BuildFactory()
f_${name}.addStep(steps.Git(
repourl=util.Property('repository', '${head repo.urls}'),
2019-11-29 13:11:18 +00:00
method='clobber',
2018-09-09 18:01:51 +00:00
mode='full',
submodules=True,
))
f_${name}.addStep(steps.SetPropertyFromCommand(
env={
"NIX_REMOTE": "daemon",
"NIX_PATH": "secrets=/var/src/stockholm/null:/var/src",
},
name="get_steps",
command=["${getJobs}"],
2018-09-14 11:57:58 +00:00
extract_fn=lambda rc, stdout, stderr: { 'steps_json': stdout },
2018-09-09 18:01:51 +00:00
))
f_${name}.addStep(StepToStartMoreSteps(command=["echo"])) # TODO remove dummy command from here
bu.append(
util.BuilderConfig(
name="${name}",
slavenames=slavenames,
factory=f_${name}
)
)
''
) cfg.repos;
enable = true;
web.enable = true;
irc = {
enable = true;
nick = "build|${hostname}";
server = "irc.r";
2018-09-12 13:21:45 +00:00
channels = [ "xxx" "noise" ];
2018-09-09 18:01:51 +00:00
allowForce = true;
};
extraConfig = ''
c['buildbotURL'] = "http://build.${hostname}.r/"
'';
};
krebs.buildbot.slave = {
enable = true;
masterhost = "localhost";
username = "testslave";
password = "lasspass";
packages = with pkgs; [ gnumake jq nix populate gnutar lzma gzip ];
};
2018-11-13 20:38:28 +00:00
system.activationScripts.buildbots-nix-profile = ''
${pkgs.coreutils}/bin/mkdir -p ${shell.escape profileRoot}
${pkgs.coreutils}/bin/chmod 0770 ${shell.escape profileRoot}
${pkgs.coreutils}/bin/chgrp buildbots ${shell.escape profileRoot}
'';
users = {
groups.buildbots.gid = genid "buildbots";
users = {
buildbotMaster.extraGroups = [ "buildbots" ];
buildbotSlave.extraGroups = [ "buildbots" ];
};
};
2018-09-09 18:01:51 +00:00
};
in out