summary refs log tree commit diff
path: root/nixos/modules/services/continuous-integration/gitlab-runner.nix
blob: ce0583dad54d3883d8658f15ae3bc0bc30fa1b6d (plain) (blame)
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
{ config, lib, pkgs, ... }:

with lib;

let
  cfg = config.services.gitlab-runner;
  configFile =
    if (cfg.configFile == null) then
      (pkgs.runCommand "config.toml" {
        buildInputs = [ pkgs.remarshal ];
      } ''
        remarshal -if json -of toml \
          < ${pkgs.writeText "config.json" (builtins.toJSON cfg.configOptions)} \
          > $out
      '')
    else
      cfg.configFile;
  hasDocker = config.virtualisation.docker.enable;
in
{
  options.services.gitlab-runner = {
    enable = mkEnableOption "Gitlab Runner";

    configFile = mkOption {
      default = null;
      description = ''
        Configuration file for gitlab-runner.
        Use this option in favor of configOptions to avoid placing CI tokens in the nix store.

        <option>configFile</option> takes precedence over <option>configOptions</option>.

        Warning: Not using <option>configFile</option> will potentially result in secrets
        leaking into the WORLD-READABLE nix store.
      '';
      type = types.nullOr types.path;
    };

    configOptions = mkOption {
      description = ''
        Configuration for gitlab-runner
        <option>configFile</option> will take precedence over this option.

        Warning: all Configuration, especially CI token, will be stored in a
        WORLD-READABLE file in the Nix Store.

        If you want to protect your CI token use <option>configFile</option> instead.
      '';
      type = types.attrs;
      example = {
        concurrent = 2;
        runners = [{
          name = "docker-nix-1.11";
          url = "https://CI/";
          token = "TOKEN";
          executor = "docker";
          builds_dir = "";
          docker = {
            host = "";
            image = "nixos/nix:1.11";
            privileged = true;
            disable_cache = true;
            cache_dir = "";
          };
        }];
      };
    };

    gracefulTermination = mkOption {
      default = false;
      type = types.bool;
      description = ''
        Finish all remaining jobs before stopping, restarting or reconfiguring.
        If not set gitlab-runner will stop immediatly without waiting for jobs to finish,
        which will lead to failed builds.
      '';
    };

    gracefulTimeout = mkOption {
      default = "infinity";
      type = types.str;
      example = "5min 20s";
      description = ''Time to wait until a graceful shutdown is turned into a forceful one.'';
    };

    workDir = mkOption {
      default = "/var/lib/gitlab-runner";
      type = types.path;
      description = "The working directory used";
    };

    package = mkOption {
      description = "Gitlab Runner package to use";
      default = pkgs.gitlab-runner;
      defaultText = "pkgs.gitlab-runner";
      type = types.package;
      example = literalExample "pkgs.gitlab-runner_1_11";
    };

  };

  config = mkIf cfg.enable {
    systemd.services.gitlab-runner = {
      description = "Gitlab Runner";
      after = [ "network.target" ]
        ++ optional hasDocker "docker.service";
      requires = optional hasDocker "docker.service";
      wantedBy = [ "multi-user.target" ];
      serviceConfig = {
        ExecStart = ''${cfg.package.bin}/bin/gitlab-runner run \
          --working-directory ${cfg.workDir} \
          --config ${configFile} \
          --service gitlab-runner \
          --user gitlab-runner \
        '';

      } //  optionalAttrs (cfg.gracefulTermination) {
        TimeoutStopSec = "${cfg.gracefulTimeout}";
        KillSignal = "SIGQUIT";
        KillMode = "process";
      };
    };

    # Make the gitlab-runner command availabe so users can query the runner
    environment.systemPackages = [ cfg.package ];

    users.extraUsers.gitlab-runner = {
      group = "gitlab-runner";
      extraGroups = optional hasDocker "docker";
      uid = config.ids.uids.gitlab-runner;
      home = cfg.workDir;
      createHome = true;
    };

    users.extraGroups.gitlab-runner.gid = config.ids.gids.gitlab-runner;
  };
}