- updates buildbot to version 9 release - adds nixos configuration module - fixes buildbot-www package deps - re-hardcode path to tail - builbot configuration via module vars fixes #19759wip/yesman
parent
9eac665cd2
commit
50466c2d4f
@ -0,0 +1,250 @@ |
||||
# NixOS module for Buildbot continous integration server. |
||||
|
||||
{ config, lib, pkgs, ... }: |
||||
|
||||
with lib; |
||||
|
||||
let |
||||
cfg = config.services.buildbot-master; |
||||
escapeStr = s: escape ["'"] s; |
||||
masterCfg = pkgs.writeText "master.cfg" '' |
||||
from buildbot.plugins import * |
||||
factory = util.BuildFactory() |
||||
c = BuildmasterConfig = dict( |
||||
workers = [${concatStringsSep "," cfg.workers}], |
||||
protocols = { 'pb': {'port': ${cfg.bpPort} } }, |
||||
title = '${escapeStr cfg.title}', |
||||
titleURL = '${escapeStr cfg.titleUrl}', |
||||
buildbotURL = '${escapeStr cfg.buildbotUrl}', |
||||
db = dict(db_url='${escapeStr cfg.dbUrl}'), |
||||
www = dict(port=${toString cfg.port}), |
||||
change_source = [ ${concatStringsSep "," cfg.changeSource} ], |
||||
schedulers = [ ${concatStringsSep "," cfg.schedulers} ], |
||||
builders = [ ${concatStringsSep "," cfg.builders} ], |
||||
status = [ ${concatStringsSep "," cfg.status} ], |
||||
) |
||||
for step in [ ${concatStringsSep "," cfg.factorySteps} ]: |
||||
factory.addStep(step) |
||||
|
||||
${cfg.extraConfig} |
||||
''; |
||||
|
||||
configFile = if cfg.masterCfg == null then masterCfg else cfg.masterCfg; |
||||
|
||||
in { |
||||
options = { |
||||
services.buildbot-master = { |
||||
|
||||
factorySteps = mkOption { |
||||
type = types.listOf types.str; |
||||
description = "Factory Steps"; |
||||
default = []; |
||||
example = [ |
||||
"steps.Git(repourl='git://github.com/buildbot/pyflakes.git', mode='incremental')" |
||||
"steps.ShellCommand(command=['trial', 'pyflakes'])" |
||||
]; |
||||
}; |
||||
|
||||
changeSource = mkOption { |
||||
type = types.listOf types.str; |
||||
description = "List of Change Sources."; |
||||
default = []; |
||||
example = [ |
||||
"changes.GitPoller('git://github.com/buildbot/pyflakes.git', workdir='gitpoller-workdir', branch='master', pollinterval=300)" |
||||
]; |
||||
}; |
||||
|
||||
enable = mkOption { |
||||
type = types.bool; |
||||
default = false; |
||||
description = "Whether to enable the Buildbot continuous integration server."; |
||||
}; |
||||
|
||||
extraConfig = mkOption { |
||||
type = types.str; |
||||
description = "Extra configuration to append to master.cfg"; |
||||
default = ""; |
||||
}; |
||||
|
||||
masterCfg = mkOption { |
||||
type = with types; nullOr path; |
||||
description = '' |
||||
Optionally pass path to raw master.cfg file. |
||||
Other options in this configuration will be ignored. |
||||
''; |
||||
default = null; |
||||
example = literalExample '' |
||||
pkgs.writeText "master.cfg" "BuildmasterConfig = c = {}" |
||||
''; |
||||
}; |
||||
|
||||
schedulers = mkOption { |
||||
type = types.listOf types.str; |
||||
description = "List of Schedulers."; |
||||
default = [ |
||||
"schedulers.SingleBranchScheduler(name='all', change_filter=util.ChangeFilter(branch='master'), treeStableTimer=None, builderNames=['runtests'])" |
||||
"schedulers.ForceScheduler(name='force',builderNames=['runtests'])" |
||||
]; |
||||
}; |
||||
|
||||
builders = mkOption { |
||||
type = types.listOf types.str; |
||||
description = "List of Builders."; |
||||
default = [ |
||||
"util.BuilderConfig(name='runtests',workernames=['default-worker'],factory=factory)" |
||||
]; |
||||
}; |
||||
|
||||
workers = mkOption { |
||||
type = types.listOf types.str; |
||||
description = "List of Workers."; |
||||
default = [ |
||||
"worker.Worker('default-worker', 'password')" |
||||
]; |
||||
example = [ "worker.LocalWorker('default-worker')" ]; |
||||
}; |
||||
|
||||
status = mkOption { |
||||
default = []; |
||||
type = types.listOf types.str; |
||||
description = "List of status notification endpoints."; |
||||
}; |
||||
|
||||
user = mkOption { |
||||
default = "buildbot"; |
||||
type = types.str; |
||||
description = "User the buildbot server should execute under."; |
||||
}; |
||||
|
||||
group = mkOption { |
||||
default = "buildbot"; |
||||
type = types.str; |
||||
description = "Primary group of buildbot user."; |
||||
}; |
||||
|
||||
extraGroups = mkOption { |
||||
type = types.listOf types.str; |
||||
default = [ "nixbld" ]; |
||||
description = "List of extra groups that the buildbot user should be a part of."; |
||||
}; |
||||
|
||||
home = mkOption { |
||||
default = "/home/buildbot"; |
||||
type = types.path; |
||||
description = "Buildbot home directory."; |
||||
}; |
||||
|
||||
buildbotDir = mkOption { |
||||
default = "${cfg.home}/master"; |
||||
type = types.path; |
||||
description = "Specifies the Buildbot directory."; |
||||
}; |
||||
|
||||
bpPort = mkOption { |
||||
default = "9989"; |
||||
type = types.string; |
||||
example = "tcp:10000:interface=127.0.0.1"; |
||||
description = "Port where the master will listen to Buildbot Worker."; |
||||
}; |
||||
|
||||
listenAddress = mkOption { |
||||
default = "0.0.0.0"; |
||||
type = types.str; |
||||
description = "Specifies the bind address on which the buildbot HTTP interface listens."; |
||||
}; |
||||
|
||||
buildbotUrl = mkOption { |
||||
default = "http://localhost:8010/"; |
||||
type = types.str; |
||||
description = "Specifies the Buildbot URL."; |
||||
}; |
||||
|
||||
title = mkOption { |
||||
default = "Buildbot"; |
||||
type = types.str; |
||||
description = "Specifies the Buildbot Title."; |
||||
}; |
||||
|
||||
titleUrl = mkOption { |
||||
default = "Buildbot"; |
||||
type = types.str; |
||||
description = "Specifies the Buildbot TitleURL."; |
||||
}; |
||||
|
||||
dbUrl = mkOption { |
||||
default = "sqlite:///state.sqlite"; |
||||
type = types.str; |
||||
description = "Specifies the database connection string."; |
||||
}; |
||||
|
||||
port = mkOption { |
||||
default = 8010; |
||||
type = types.int; |
||||
description = "Specifies port number on which the buildbot HTTP interface listens."; |
||||
}; |
||||
|
||||
package = mkOption { |
||||
type = types.package; |
||||
default = pkgs.buildbot-ui; |
||||
description = '' |
||||
Package to use for buildbot. |
||||
<literal>buildbot-full</literal> is required in order to use local workers. |
||||
''; |
||||
example = pkgs.buildbot-full; |
||||
}; |
||||
|
||||
packages = mkOption { |
||||
default = [ ]; |
||||
example = [ pkgs.git ]; |
||||
type = types.listOf types.package; |
||||
description = "Packages to add to PATH for the buildbot process."; |
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
config = mkIf cfg.enable { |
||||
users.extraGroups = optional (cfg.group == "buildbot") { |
||||
name = "buildbot"; |
||||
}; |
||||
|
||||
users.extraUsers = optional (cfg.user == "buildbot") { |
||||
name = "buildbot"; |
||||
description = "buildbot user"; |
||||
isNormalUser = true; |
||||
createHome = true; |
||||
home = cfg.home; |
||||
group = cfg.group; |
||||
extraGroups = cfg.extraGroups; |
||||
useDefaultShell = true; |
||||
}; |
||||
|
||||
systemd.services.buildbot-master = { |
||||
description = "Buildbot Continuous Integration Server"; |
||||
after = [ "network.target" ]; |
||||
wantedBy = [ "multi-user.target" ]; |
||||
path = cfg.packages; |
||||
|
||||
serviceConfig = { |
||||
Type = "forking"; |
||||
User = cfg.user; |
||||
Group = cfg.group; |
||||
WorkingDirectory = cfg.home; |
||||
ExecStart = "${cfg.package}/bin/buildbot start ${cfg.buildbotDir}"; |
||||
}; |
||||
|
||||
preStart = '' |
||||
mkdir -vp ${cfg.buildbotDir} |
||||
chown -c ${cfg.user}:${cfg.group} ${cfg.buildbotDir} |
||||
ln -sf ${configFile} ${cfg.buildbotDir}/master.cfg |
||||
${cfg.package}/bin/buildbot create-master ${cfg.buildbotDir} |
||||
''; |
||||
|
||||
postStart = '' |
||||
until [[ $(${pkgs.curl}/bin/curl -s --head -w '\n%{http_code}' http://localhost:${toString cfg.port} | tail -n1) =~ ^(200|403)$ ]]; do |
||||
sleep 1 |
||||
done |
||||
''; |
||||
}; |
||||
}; |
||||
|
||||
} |
Loading…
Reference in new issue