about summary refs log tree commit diff stats
path: root/modules/laminar.nix
blob: 02944f3755dfb2bfa77c9ae04d4baf1bfaf07259 (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
{ config
, lib
, pkgs
, ...
}:
let
  cfg = config.services.laminar;

  inherit (lib)
    literalExpression
    optionalAttrs
    mkEnableOption
    mkPackageOption
    mkOption
    mkIf
    types;
in
{
  options.services.laminar = {
    enable = mkEnableOption "Lightweight and modular Continuous Integration service for Linux.";

    user = mkOption {
      type = types.str;
      default = "laminar";
      description = "User account under which laminar runs.";
    };

    group = mkOption {
      type = types.str;
      default = "laminar";
      description = "User account under which laminar runs.";
    };

    package = mkPackageOption pkgs "laminar" { };

    homeDir = mkOption {
      type = types.path;
      default = "/var/lib/laminar";
      description = "Home directory for laminar user.";
    };

    path = mkOption {
      type = types.listOf types.package;
      default = with pkgs; [
        bash
        stdenv
        git
        nix
        config.programs.ssh.package
      ];
      defaultText = literalExpression "[ pkgs.stdenv pkgs.git pkgs.nix config.programs.ssh.package ]";
      description = "Packages added to service PATH environment variable.";
    };

    settings = mkOption {
      default = { };

      description = ''
        Configuration for laminar.

        See https://laminar.ohwg.net/docs.html#Service-configuration-file
      '';

      type = types.submodule {
        options = {
          bindHTTP = mkOption {
            type = types.str;
            default = "*:8080";
            description = "The interface/port or unix socket on which laminard should listen for incoming connections to the web frontend.";
          };
          bindRPC = mkOption {
            type = types.str;
            default = "unix-abstract:laminar";
            description = "The interface/port or unix socket on which laminard should listen for incoming commands such as build triggers.";
          };
          title = mkOption {
            type = types.str;
            default = "";
            description = "The page title to show in the web frontend.";
          };
          keepRundirs = mkOption {
            type = types.int;
            default = 0;
            description = "Set to an integer defining how many rundirs to keep per job. The lowest-numbered ones will be deleted.";
          };
          baseURL = mkOption {
            type = types.str;
            default = "/";
            description = "Base url for the frontend.";
          };
          archiveURL = mkOption {
            type = with types; nullOr str;
            default = null;
            example = "http://localhost:8080";
            description = "If set, the web frontend served by laminard will use this URL to form links to artefacts archived jobs.";
          };
        };
      };
    };
  };

  config = mkIf cfg.enable {
    systemd.services.laminar = {
      description = "Laminar continuous integration service";
      wantedBy = [ "multi-user.target" ];
      after = [ "network.target" ];
      inherit (cfg) path;
      environment = {
        XDG_RUNTIME_DIR = "%t/laminar";
      };
      serviceConfig = {
        User = cfg.user;
        Group = cfg.group;
        ExecStart = "${cfg.package}/bin/laminard -v";
        RuntimeDirectory = "laminar";
        EnvironmentFile = pkgs.writeText "laminar.conf" ''
          LAMINAR_HOME=${cfg.homeDir}
          LAMINAR_BIND_HTTP=${cfg.settings.bindHTTP}
          LAMINAR_BIND_RPC=${cfg.settings.bindRPC}
          LAMINAR_TITLE=${cfg.settings.title}
          LAMINAR_KEEP_RUNDIRS=${toString cfg.settings.keepRundirs}
          LAMINAR_BASE_URL=${cfg.settings.baseURL}
          ${lib.optionalString (cfg.settings.archiveURL != null)
            "LAMINAR_ARCHIVE_URL=${cfg.settings.archiveURL}"
          }
        '';
      };
      unitConfig = {
        Documentation = [
          "man:laminard(8)"
          "https://laminar.ohwg.net/docs.html"
        ];
      };
    };

    environment.systemPackages = [
      pkgs.laminar
    ];

    users.users = optionalAttrs (cfg.user == "laminar") {
      laminar = {
        inherit (cfg) group;
        home = cfg.homeDir;
        createHome = true;
        isSystemUser = true;
      };
    };

    users.groups = optionalAttrs (cfg.group == "laminar") {
      laminar = { };
    };
  };
}