{ config, pkgs, lib, ... }: with import ; let default-packages = [ pkgs.git pkgs.bash ]; buildbot = pkgs.stdenv.lib.overrideDerivation pkgs.buildbot-worker (old:{ patches = [ ./buildbot-worker.patch ]; propagatedBuildInputs = old.propagatedBuildInputs ++ [ pkgs.coreutils ]; }); cfg = config.krebs.buildbot.worker; api = { enable = mkEnableOption "Buildbot worker"; workDir = mkOption { default = "/var/lib/buildbot/worker"; type = types.str; description = '' Path to build bot worker directory. Will be created on startup. ''; }; masterhost = mkOption { default = "localhost"; type = types.str; description = '' Hostname/IP of the buildbot master ''; }; username = mkOption { type = types.str; description = '' workername used to authenticate with master ''; }; password = mkOption { type = types.str; description = '' worker password used to authenticate with master ''; }; contact = mkOption { default = "nix worker "; type = types.str; description = '' contact to be announced by buildworker ''; }; description = mkOption { default = "Nix Generated Buildworker"; type = types.str; description = '' description for hostto be announced by buildworker ''; }; packages = mkOption { default = [ pkgs.git ]; type = with types; listOf package; description = '' packages which should be in path for buildworker ''; }; extraEnviron = mkOption { default = {}; example = { NIX_PATH = "nixpkgs=/path/to/my/nixpkgs"; }; type = types.attrsOf types.str; description = '' extra environment variables to be provided to the buildworker service if you need nixpkgs, e.g. for running nix-shell you can set NIX_PATH here. ''; }; extraConfig = mkOption { default = ""; type = types.lines; example = '' port = 443 keepalive = 600 ''; description = '' extra config evaluated before calling Buildworker init in .tac file ''; }; }; imp = { users.extraUsers.buildbotworker = { uid = genid "buildbotworker"; description = "Buildbot worker"; home = cfg.workDir; createHome = false; }; users.extraGroups.buildbotworker = { gid = genid "buildbotworker"; }; systemd.services."buildbotworker-${cfg.username}-${cfg.masterhost}" = { description = "Buildbot worker for ${cfg.username}@${cfg.masterhost}"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; path = default-packages ++ cfg.packages; environment = { SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; NIX_REMOTE="daemon"; } // cfg.extraEnviron; serviceConfig = let workdir = shell.escape cfg.workDir; contact = shell.escape cfg.contact; description = shell.escape cfg.description; masterhost = shell.escape cfg.masterhost; username = shell.escape cfg.username; password = shell.escape cfg.password; in { PermissionsStartOnly = true; Type = "forking"; PIDFile = "${workdir}/twistd.pid"; ExecStartPre = pkgs.writeDash "buildbot-slave-init" '' set -efux mkdir -p ${workdir}/info # TODO: cleanup .tac file? ${buildbot}/bin/buildbot-worker create-worker ${workdir} ${masterhost} ${username} ${password} echo ${contact} > ${workdir}/info/admin echo ${description} > ${workdir}/info/host chown buildbotworker:buildbotworker -R ${workdir} chmod 700 -R ${workdir} ''; ExecStart = "${buildbot}/bin/buildbot-worker start ${workdir}"; ExecStop = "${buildbot}/bin/buildbot-worker stop ${workdir}"; PrivateTmp = "true"; User = "buildbotworker"; Restart = "always"; RestartSec = "10"; }; }; }; in { options.krebs.buildbot.worker = api; config = lib.mkIf cfg.enable imp; }