about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--modules/default.nix1
-rw-r--r--modules/laminar.nix124
2 files changed, 125 insertions, 0 deletions
diff --git a/modules/default.nix b/modules/default.nix
index ff6c7c0..1901177 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -2,4 +2,5 @@
   # Add your NixOS modules here
   #
   # my-module = ./my-module;
+  laminar = ./laminar.nix;
 }
diff --git a/modules/laminar.nix b/modules/laminar.nix
new file mode 100644
index 0000000..c0024bb
--- /dev/null
+++ b/modules/laminar.nix
@@ -0,0 +1,124 @@
+{ config
+, lib
+, pkgs
+, ...
+}:
+let
+  cfg = config.services.laminar;
+
+  inherit (lib) mkEnableOption mkPackageOption mkOption mkIf optionalAttrs 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.";
+    };
+
+    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" ];
+      serviceConfig = {
+        User = cfg.user;
+        Group = cfg.group;
+        ExecStart = "${cfg.package}/bin/laminard -v";
+        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"
+        ];
+      };
+    };
+
+    users.users = optionalAttrs (cfg.user == "laminar") {
+      laminar = {
+        inherit (cfg) group;
+        home = cfg.homeDir;
+        createHome = true;
+        isSystemUser = true;
+      };
+    };
+
+    users.groups = optionalAttrs (cfg.group == "laminar") {
+      laminar = { };
+    };
+  };
+}