2015-12-15 17:43:40 +00:00
|
|
|
{ config, pkgs, lib, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
let
|
|
|
|
buildbot = pkgs.buildbot;
|
|
|
|
buildbot-master-config = pkgs.writeText "buildbot-master.cfg" ''
|
|
|
|
# -*- python -*-
|
|
|
|
from buildbot.plugins import *
|
2015-12-16 16:58:29 +00:00
|
|
|
import re
|
2015-12-15 17:43:40 +00:00
|
|
|
|
|
|
|
c = BuildmasterConfig = {}
|
|
|
|
|
|
|
|
c['slaves'] = []
|
|
|
|
# TODO: template potential buildslaves
|
|
|
|
# TODO: set password?
|
2015-12-15 21:25:46 +00:00
|
|
|
slavenames= [ 'testslave' ]
|
|
|
|
for i in slavenames:
|
2015-12-15 17:43:40 +00:00
|
|
|
c['slaves'].append(buildslave.BuildSlave(i, "krebspass"))
|
|
|
|
|
|
|
|
c['protocols'] = {'pb': {'port': 9989}}
|
|
|
|
|
|
|
|
####### Build Inputs
|
|
|
|
stockholm_repo = 'http://cgit.gum/stockholm'
|
|
|
|
c['change_source'] = []
|
|
|
|
c['change_source'].append(changes.GitPoller(
|
|
|
|
stockholm_repo,
|
|
|
|
workdir='stockholm-poller', branch='master',
|
|
|
|
project='stockholm',
|
2015-12-16 16:48:49 +00:00
|
|
|
pollinterval=120))
|
2015-12-15 17:43:40 +00:00
|
|
|
|
|
|
|
####### Build Scheduler
|
|
|
|
# TODO: configure scheduler
|
|
|
|
c['schedulers'] = []
|
2015-12-16 16:48:49 +00:00
|
|
|
|
|
|
|
# test the master real quick
|
|
|
|
fast = schedulers.SingleBranchScheduler(
|
|
|
|
change_filter=util.ChangeFilter(branch="master"),
|
|
|
|
name="fast-master-test",
|
|
|
|
builderNames=["fast-tests"])
|
|
|
|
|
|
|
|
force = schedulers.ForceScheduler(
|
2015-12-15 17:43:40 +00:00
|
|
|
name="force",
|
2015-12-16 16:48:49 +00:00
|
|
|
builderNames=["full-tests"])
|
|
|
|
|
|
|
|
# files everyone depends on or are part of the share branch
|
|
|
|
def shared_files(change):
|
|
|
|
r =re.compile("^((krebs|share)/.*|Makefile|default.nix)")
|
|
|
|
for file in change.files:
|
|
|
|
if r.match(file):
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
full = schedulers.SingleBranchScheduler(
|
|
|
|
change_filter=util.ChangeFilter(branch="master"),
|
|
|
|
fileIsImportant=shared_files,
|
|
|
|
name="full-master-test",
|
|
|
|
builderNames=["full-tests"])
|
|
|
|
c['schedulers'] = [ fast, force, full ]
|
2015-12-15 17:43:40 +00:00
|
|
|
###### The actual build
|
2015-12-16 16:48:49 +00:00
|
|
|
# couple of fast steps:
|
2015-12-16 16:11:42 +00:00
|
|
|
f = util.BuildFactory()
|
2015-12-16 16:48:49 +00:00
|
|
|
## fetch repo
|
|
|
|
grab_repo = steps.Git(repourl=stockholm_repo, mode='incremental')
|
|
|
|
f.addStep(grab_repo)
|
2015-12-15 17:43:40 +00:00
|
|
|
|
2015-12-16 16:11:42 +00:00
|
|
|
# the dependencies which are used by the test script
|
2015-12-15 17:43:40 +00:00
|
|
|
deps = [ "gnumake", "jq" ]
|
2015-12-16 16:11:42 +00:00
|
|
|
nixshell = ["nix-shell", "-p" ] + deps + [ "--run" ]
|
2015-12-16 16:48:49 +00:00
|
|
|
def addShell(f,**kwargs):
|
2015-12-16 16:11:42 +00:00
|
|
|
f.addStep(steps.ShellCommand(**kwargs))
|
|
|
|
|
2015-12-16 16:48:49 +00:00
|
|
|
addShell(f,name="centos7-eval",env={"LOGNAME": "shared",
|
2015-12-16 16:11:42 +00:00
|
|
|
"get" : "krebs.deploy",
|
|
|
|
"filter" : "json"
|
|
|
|
},
|
|
|
|
command=nixshell + ["make -s eval system=test-centos7"])
|
2015-12-16 16:48:49 +00:00
|
|
|
|
|
|
|
addShell(f,name="wolf-eval",env={"LOGNAME": "shared",
|
2015-12-16 16:11:42 +00:00
|
|
|
"get" : "krebs.deploy",
|
|
|
|
"filter" : "json"
|
|
|
|
},
|
|
|
|
command=nixshell + ["make -s eval system=wolf"])
|
2015-12-15 17:43:40 +00:00
|
|
|
|
|
|
|
c['builders'] = []
|
|
|
|
c['builders'].append(
|
2015-12-16 16:48:49 +00:00
|
|
|
util.BuilderConfig(name="fast-tests",
|
|
|
|
slavenames=slavenames,
|
|
|
|
factory=f))
|
|
|
|
|
|
|
|
# TODO slow build
|
|
|
|
c['builders'].append(
|
|
|
|
util.BuilderConfig(name="full-tests",
|
2015-12-15 21:25:46 +00:00
|
|
|
slavenames=slavenames,
|
2015-12-16 16:11:42 +00:00
|
|
|
factory=f))
|
2015-12-15 17:43:40 +00:00
|
|
|
|
|
|
|
####### Status of Builds
|
|
|
|
c['status'] = []
|
|
|
|
|
|
|
|
from buildbot.status import html
|
|
|
|
from buildbot.status.web import authz, auth
|
|
|
|
# TODO: configure if http is wanted
|
|
|
|
authz_cfg=authz.Authz(
|
|
|
|
# TODO: configure user/pw
|
|
|
|
auth=auth.BasicAuth([("krebs","bob")]),
|
|
|
|
gracefulShutdown = False,
|
|
|
|
forceBuild = 'auth',
|
|
|
|
forceAllBuilds = 'auth',
|
|
|
|
pingBuilder = False,
|
|
|
|
stopBuild = False,
|
|
|
|
stopAllBuilds = False,
|
|
|
|
cancelPendingBuild = False,
|
|
|
|
)
|
|
|
|
# TODO: configure nginx
|
|
|
|
c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
|
|
|
|
|
|
|
|
from buildbot.status import words
|
2015-12-16 13:29:46 +00:00
|
|
|
${optionalString (cfg.irc.enable) ''
|
|
|
|
irc = words.IRC("${cfg.irc.server}", "krebsbuild",
|
|
|
|
# TODO: multiple channels
|
|
|
|
channels=["${cfg.irc.channel}"],
|
|
|
|
notify_events={
|
2015-12-16 16:58:29 +00:00
|
|
|
#'success': 1,
|
|
|
|
#'failure': 1,
|
2015-12-16 13:29:46 +00:00
|
|
|
'exception': 1,
|
|
|
|
'successToFailure': 1,
|
|
|
|
'failureToSuccess': 1,
|
|
|
|
}${optionalString cfg.irc.allowForce ",allowForce=True"})
|
|
|
|
c['status'].append(irc)
|
|
|
|
''}
|
2015-12-15 17:43:40 +00:00
|
|
|
|
|
|
|
####### PROJECT IDENTITY
|
|
|
|
c['title'] = "Stockholm"
|
|
|
|
c['titleURL'] = "http://krebsco.de"
|
|
|
|
|
2015-12-16 16:48:49 +00:00
|
|
|
#c['buildbotURL'] = "http://buildbot.krebsco.de/"
|
|
|
|
# TODO: configure url
|
|
|
|
c['buildbotURL'] = "http://vbob:8010/"
|
2015-12-15 17:43:40 +00:00
|
|
|
|
|
|
|
####### DB URL
|
|
|
|
c['db'] = {
|
|
|
|
'db_url' : "sqlite:///state.sqlite",
|
|
|
|
}
|
|
|
|
${cfg.extraConfig}
|
|
|
|
'';
|
|
|
|
|
|
|
|
cfg = config.makefu.buildbot.master;
|
|
|
|
|
|
|
|
api = {
|
|
|
|
enable = mkEnableOption "Buildbot Master";
|
|
|
|
workDir = mkOption {
|
|
|
|
default = "/var/lib/buildbot/master";
|
|
|
|
type = types.str;
|
|
|
|
description = ''
|
|
|
|
Path to build bot master directory.
|
|
|
|
Will be created on startup.
|
|
|
|
'';
|
|
|
|
};
|
2015-12-16 13:29:46 +00:00
|
|
|
irc = mkOption {
|
|
|
|
default = {};
|
|
|
|
type = types.submodule ({ config, ... }: {
|
|
|
|
options = {
|
|
|
|
enable = mkEnableOption "Buildbot Master IRC Status";
|
|
|
|
channel = mkOption {
|
|
|
|
default = "nix-buildbot-meetup";
|
|
|
|
type = types.str;
|
|
|
|
description = ''
|
|
|
|
irc channel the bot should connect to
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
allowForce = mkOption {
|
|
|
|
default = false;
|
|
|
|
type = types.bool;
|
|
|
|
description = ''
|
|
|
|
Determines if builds can be forced via IRC
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
nick = mkOption {
|
|
|
|
default = "nix-buildbot";
|
|
|
|
type = types.str;
|
|
|
|
description = ''
|
|
|
|
nickname for IRC
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
server = mkOption {
|
|
|
|
default = "irc.freenode.net";
|
|
|
|
type = types.str;
|
|
|
|
description = ''
|
|
|
|
Buildbot Status IRC Server to connect to
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
});
|
|
|
|
};
|
2015-12-16 16:48:49 +00:00
|
|
|
|
2015-12-15 17:43:40 +00:00
|
|
|
extraConfig = mkOption {
|
|
|
|
default = "";
|
|
|
|
type = types.lines;
|
|
|
|
description = ''
|
|
|
|
extra config appended to the generated master.cfg
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
imp = {
|
|
|
|
|
|
|
|
users.extraUsers.buildbotMaster = {
|
2015-12-26 04:55:13 +00:00
|
|
|
uid = genid "buildbotMaster";
|
2015-12-15 17:43:40 +00:00
|
|
|
description = "Buildbot Master";
|
|
|
|
home = cfg.workDir;
|
|
|
|
createHome = false;
|
|
|
|
};
|
|
|
|
|
|
|
|
users.extraGroups.buildbotMaster = {
|
|
|
|
gid = 672626386;
|
|
|
|
};
|
|
|
|
|
|
|
|
systemd.services.buildbotMaster = {
|
|
|
|
description = "Buildbot Master";
|
|
|
|
after = [ "network.target" ];
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
2015-12-16 16:11:42 +00:00
|
|
|
path = [ pkgs.git ];
|
2015-12-15 21:25:46 +00:00
|
|
|
serviceConfig = let
|
|
|
|
workdir="${lib.shell.escape cfg.workDir}";
|
2015-12-16 16:11:42 +00:00
|
|
|
# TODO: check if git is the only dep
|
2015-12-15 21:25:46 +00:00
|
|
|
in {
|
2015-12-15 17:43:40 +00:00
|
|
|
PermissionsStartOnly = true;
|
2015-12-15 21:25:46 +00:00
|
|
|
Type = "forking";
|
|
|
|
PIDFile = "${workdir}/twistd.pid";
|
2015-12-15 17:43:40 +00:00
|
|
|
# TODO: maybe also prepare buildbot.tac?
|
|
|
|
ExecStartPre = pkgs.writeScript "buildbot-master-init" ''
|
|
|
|
#!/bin/sh
|
|
|
|
set -efux
|
2015-12-15 21:25:46 +00:00
|
|
|
if [ ! -e ${workdir} ];then
|
|
|
|
mkdir -p ${workdir}
|
|
|
|
${buildbot}/bin/buildbot create-master -r -l 10 -f ${workdir}
|
2015-12-15 17:43:40 +00:00
|
|
|
fi
|
|
|
|
# always override the master.cfg
|
2015-12-15 21:25:46 +00:00
|
|
|
cp ${buildbot-master-config} ${workdir}/master.cfg
|
2015-12-15 17:43:40 +00:00
|
|
|
# sanity
|
2015-12-15 21:25:46 +00:00
|
|
|
${buildbot}/bin/buildbot checkconfig ${workdir}
|
|
|
|
|
2015-12-16 13:29:46 +00:00
|
|
|
# TODO: maybe upgrade? not sure about this
|
|
|
|
# normally we should write buildbot.tac by our own
|
2015-12-15 21:25:46 +00:00
|
|
|
# ${buildbot}/bin/buildbot upgrade-master ${workdir}
|
|
|
|
|
2015-12-16 13:29:46 +00:00
|
|
|
chmod 700 -R ${workdir}
|
2015-12-15 21:25:46 +00:00
|
|
|
chown buildbotMaster:buildbotMaster -R ${workdir}
|
2015-12-15 17:43:40 +00:00
|
|
|
'';
|
2015-12-15 21:25:46 +00:00
|
|
|
ExecStart = "${buildbot}/bin/buildbot start ${workdir}";
|
|
|
|
ExecStop = "${buildbot}/bin/buildbot stop ${workdir}";
|
|
|
|
ExecReload = "${buildbot}/bin/buildbot reconfig ${workdir}";
|
2015-12-15 17:43:40 +00:00
|
|
|
PrivateTmp = "true";
|
|
|
|
User = "buildbotMaster";
|
|
|
|
Restart = "always";
|
|
|
|
RestartSec = "10";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
in
|
|
|
|
{
|
|
|
|
options.makefu.buildbot.master = api;
|
|
|
|
config = mkIf cfg.enable imp;
|
|
|
|
}
|