From da53312f5c4ba1c8f4c54028b250596295798bd8 Mon Sep 17 00:00:00 2001
From: Matthias Beyer <mail@beyermatthias.de>
Date: Thu, 7 May 2015 17:49:01 +0200
Subject: [PATCH] Add services file for taskwarrior server service

---
 nixos/modules/services/misc/taskserver.nix | 208 +++++++++++++++++++++
 1 file changed, 208 insertions(+)
 create mode 100644 nixos/modules/services/misc/taskserver.nix

diff --git a/nixos/modules/services/misc/taskserver.nix b/nixos/modules/services/misc/taskserver.nix
new file mode 100644
index 000000000000..d4948e39f9ea
--- /dev/null
+++ b/nixos/modules/services/misc/taskserver.nix
@@ -0,0 +1,208 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.taskserver;
+in {
+
+  options = {
+    services.taskserver = {
+
+      enable = mkEnableOption "Taskwarrior server.";
+
+      user = mkOption {
+        default = "taskd";
+        description = "User for taskserver.";
+      };
+
+      dataDir = mkOption {
+        default = "/var/lib/taskserver/data/";
+        description = "Data directory for taskserver.";
+        type = types.path;
+      };
+
+      caCert = mkOption {
+        description = "Fully qualified path to the CA certificate. Optional.";
+        type = types.path;
+      };
+
+      ciphers = mkOption {
+        default = "NORMAL";
+        description = ''
+          List of GnuTLS ciphers to use. See your
+          GnuTLS documentation for full details.
+        '';
+        type = types.string;
+      };
+
+      confirmation = mkOption {
+        default = true;
+        description = ''
+          Determines whether certain commands are confirmed.
+        '';
+        type = types.bool;
+      };
+
+      debug = mkOption {
+        default = false;
+        description = ''
+          Logs debugging information.
+        '';
+        type = types.bool;
+      };
+
+      extensions = mkOption {
+        description = ''
+          Fully qualified path of the Taskserver extension scripts.  Currently
+          there are none.
+        '';
+        type = types.path;
+      };
+
+      ipLog = mkOption {
+        default = true;
+        description = ''
+          Logs the IP addresses of incoming requests.
+        '';
+        type = types.bool;
+      };
+
+      log = mkOption {
+        default = "/tmp/taskd.log";
+        description = ''
+          Fully-qualified path name to the Taskserver log file.
+        '';
+        type = types.string;
+      };
+
+      pidFile = mkOption {
+        default = "/tmp/taskd.pid";
+        description = ''
+          Fully-qualified path name to the Taskserver PID file. This is used
+          by the 'taskdctl' script to start/stop the daemon.
+        '';
+        type = types.string;
+      };
+
+      queueSize = mkOption {
+        default = 10;
+        description = ''
+          Size of the connection backlog.  See 'man listen'.
+        '';
+        type = types.int;
+      };
+
+      requestLimit = mkOption {
+        default = 1048576;
+        description = ''
+          Size limit of incoming requests, in bytes.
+        '';
+        type = types.int;
+      };
+
+      client = {
+
+        allow = mkOption {
+          default = [ "[Tt]ask [2-9]+" ];
+          description = ''
+             A comma-separated list of regular expressions that are matched
+             against the reported client id (such as "task 2.3.0").  The values
+             'all' or 'none' have special meaning. Overidden by any
+             'client.deny' entry.
+          '';
+          type = types.listOf types.str;
+        };
+
+        cert = mkOption {
+          description = ''
+             Fully qualified path of the client cert.  This is used by the
+             'client' command.
+          '';
+          type = types.path;
+        };
+
+        deny = mkOption {
+          default = [ "[Tt]ask [2-9]+" ];
+          description = ''
+            A comma-separated list of regular expressions that are matched
+            against the reported client id (such as "task 2.3.0"). The values
+            'all' or 'none' have special meaning.  Any 'client.deny' entry
+            overrides any 'client.allow' entry.
+          '';
+          type = types.listOf types.str;
+        };
+
+      };
+
+      server = {
+        host = mkOption {
+          default = "localhost";
+          description = ''
+            The address (IPv4, IPv6 or DNS) of the Taskserver.
+          '';
+          type = types.string;
+        };
+
+        port = mkOption {
+          default = 53589;
+          description = ''
+            Portnumber of the Taskserver.
+          '';
+          type = types.int;
+        };
+
+        cert = mkOption {
+          description = "Fully qualified path to the server certificate";
+          type = types.path;
+        };
+
+        crl = mkOption {
+          description = ''
+            Fully qualified path to the server certificate
+            revocation list.
+          '';
+          type = types.path;
+        };
+
+        key = mkOption {
+          description = ''
+            Fully qualified path to the server key.
+
+            Note that sending the HUP signal to the Taskserver
+            causes a configuration file reload before the next
+            request is handled.
+          '';
+          type = types.path;
+        };
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+
+    environment.systemPackages = [ pkgs.taskserver ];
+
+    systemd.services.taskserver = {
+      description = "taskserver Service.";
+      path = [ pkgs.taskserver ];
+
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network.target" ];
+
+      preStart = ''
+        mkdir -p ${cfg.dataDir}
+      '';
+
+      environment = {
+        TASKDDATA = "${cfg.dataDir}";
+      };
+
+      serviceConfig = {
+        ExecStart = "${pkgs.taskserver}/bin/taskdctl start";
+        ExecStop  = "${pkgs.taskserver}/bin/taskdctl stop";
+        User = cfg.user;
+      };
+    };
+  };
+}