about summary refs log tree commit diff
path: root/nixos/modules/services/continuous-integration
diff options
context:
space:
mode:
authorFernando J Pando <fernando.pando@stelligent.com>2016-10-21 17:04:48 -0400
committerJörg Thalheim <joerg@higgsboson.tk>2016-12-13 10:52:56 +0100
commit50466c2d4feca9eee52815eebb30ab6c62dc4deb (patch)
tree2a69ab72ee9121c61fabfe923128adaef680d962 /nixos/modules/services/continuous-integration
parent9eac665cd2d219194c9f5a5f9ec46822dd168d3b (diff)
downloadnixlib-50466c2d4feca9eee52815eebb30ab6c62dc4deb.tar
nixlib-50466c2d4feca9eee52815eebb30ab6c62dc4deb.tar.gz
nixlib-50466c2d4feca9eee52815eebb30ab6c62dc4deb.tar.bz2
nixlib-50466c2d4feca9eee52815eebb30ab6c62dc4deb.tar.lz
nixlib-50466c2d4feca9eee52815eebb30ab6c62dc4deb.tar.xz
nixlib-50466c2d4feca9eee52815eebb30ab6c62dc4deb.tar.zst
nixlib-50466c2d4feca9eee52815eebb30ab6c62dc4deb.zip
buildbot: 0.9.0rc4 -> 0.9.0.post1
- 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 #19759
Diffstat (limited to 'nixos/modules/services/continuous-integration')
-rw-r--r--nixos/modules/services/continuous-integration/buildbot/master.nix250
1 files changed, 250 insertions, 0 deletions
diff --git a/nixos/modules/services/continuous-integration/buildbot/master.nix b/nixos/modules/services/continuous-integration/buildbot/master.nix
new file mode 100644
index 000000000000..a40be4f546ea
--- /dev/null
+++ b/nixos/modules/services/continuous-integration/buildbot/master.nix
@@ -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
+      '';
+    };
+  };
+
+}