summaryrefslogtreecommitdiffstats
path: root/krebs/3modules/buildbot/slave.nix
blob: 95b54708192368cefe9dbf9b4c84636cbade6a74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
{ config, pkgs, lib, ... }:

with import <stockholm/lib>;
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 <buildworker@${config.networking.hostName}>";
      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;
}