From 0ff2496de4acbc5b7bc009a3ea28dbcd7504ed1a Mon Sep 17 00:00:00 2001
From: lassulus <lass@lassul.us>
Date: Sat, 21 Jan 2017 21:55:59 +0100
Subject: [PATCH] k 3 Reaktor: allow multiple Reaktor configurations

---
 krebs/3modules/Reaktor.nix | 214 +++++++++++++++++++------------------
 1 file changed, 108 insertions(+), 106 deletions(-)

diff --git a/krebs/3modules/Reaktor.nix b/krebs/3modules/Reaktor.nix
index d87003ac2..a70f1ef5d 100644
--- a/krebs/3modules/Reaktor.nix
+++ b/krebs/3modules/Reaktor.nix
@@ -3,99 +3,88 @@
 with import <stockholm/lib>;
 let
 
-  ReaktorConfig = pkgs.writeText "config.py" ''
-      ${if (isString cfg.overrideConfig ) then ''
-      # Overriden Config
-      ${cfg.overrideConfig}
-      '' else ""}
-      ## Extra Config
-      ${concatStringsSep "\n" (map (plug: plug.config) cfg.plugins)}
-      ${cfg.extraConfig}
-    '';
   cfg = config.krebs.Reaktor;
 
+  workdir = "/var/lib/Reaktor";
+
   out = {
     options.krebs.Reaktor = api;
-    config = lib.mkIf cfg.enable imp;
+    config = imp;
   };
 
-  api = {
-    enable = mkOption {
-      default = false;
-      description = ''
-        Start Reaktor at system boot
-      '';
-    };
+  api = mkOption {
+    default = {};
+    type = with types; attrsOf (submodule ({ options = {
 
-    nickname = mkOption {
-      default = config.krebs.build.host.name + "|r";
-      type = types.string;
-      description = ''
-        The nick name of the irc bot.
-        Defaults to {hostname}|r
-      '';
-    };
+      nickname = mkOption {
+        default = config.krebs.build.host.name + "|r";
+        type = types.string;
+        description = ''
+          The nick name of the irc bot.
+          Defaults to {hostname}|r
+        '';
+      };
 
-    overrideConfig = mkOption {
-      default = null;
-      type = types.nullOr types.str;
-      description = ''
-        configuration to be used instead of default ones.
-        Reaktor default cfg can be retrieved via `reaktor get-config`
-      '';
-    };
-    plugins = mkOption {
-      default = [pkgs.ReaktorPlugins.nixos-version];
-    };
-    extraConfig = mkOption {
-      default = "";
-      type = types.string;
-      description = ''
-        configuration appended to the default or overridden configuration
-      '';
-    };
+      overrideConfig = mkOption {
+        default = null;
+        type = types.nullOr types.str;
+        description = ''
+          configuration to be used instead of default ones.
+          Reaktor default cfg can be retrieved via `reaktor get-config`
+        '';
+      };
 
-    workdir = mkOption {
-      default = "/var/lib/Reaktor";
-      type = types.str;
-      description = ''
-        Reaktor working directory
-      '';
-    };
-    extraEnviron = mkOption {
-      default = {};
-      type = types.attrsOf types.str;
-      description = ''
-        Environment to be provided to the service, can be:
-          REAKTOR_HOST
-          REAKTOR_PORT
-          REAKTOR_STATEDIR
+      plugins = mkOption {
+        default = [pkgs.ReaktorPlugins.nixos-version];
+      };
 
-          debug and nickname can be set separately via the Reaktor api
-      '';
-    };
-    channels = mkOption {
-      default = [ "#krebs" ];
-      type = types.listOf types.str;
-      description = ''
-        Channels the Reaktor should connect to at startup.
-      '';
-    };
-    debug = mkOption {
-      default = false;
-      description = ''
-        Reaktor debug output
-      '';
-    };
+      extraConfig = mkOption {
+        default = "";
+        type = types.string;
+        description = ''
+          configuration appended to the default or overridden configuration
+        '';
+      };
+
+      extraEnviron = mkOption {
+        default = {};
+        type = types.attrsOf types.str;
+        description = ''
+          Environment to be provided to the service, can be:
+            REAKTOR_HOST
+            REAKTOR_PORT
+            REAKTOR_STATEDIR
+
+            debug and nickname can be set separately via the Reaktor api
+        '';
+      };
+
+      channels = mkOption {
+        default = [ "#krebs" ];
+        type = types.listOf types.str;
+        description = ''
+          Channels the Reaktor should connect to at startup.
+        '';
+      };
+
+      debug = mkOption {
+        default = false;
+        description = ''
+          Reaktor debug output
+        '';
+      };
+    };}));
   };
 
   imp = {
+    # TODO get user per configured bot
+    # TODO get home from api
     # for reaktor get-config
     users.extraUsers = singleton rec {
       name = "Reaktor";
       uid = genid name;
       description = "Reaktor user";
-      home = cfg.workdir;
+      home = workdir;
       createHome = true;
     };
 
@@ -104,39 +93,52 @@ let
     #  gid = config.ids.gids.Reaktor;
     #};
 
-    systemd.services.Reaktor = {
-      path = with pkgs; [
-        utillinux #flock for tell_on-join
-        git # for nag
-        python # for caps
-        ];
-      description = "Reaktor IRC Bot";
-      after = [ "network.target" ];
-      wantedBy = [ "multi-user.target" ];
-      environment = {
-        GIT_SSL_CAINFO = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
-        REAKTOR_NICKNAME = cfg.nickname;
-        REAKTOR_DEBUG = (if cfg.debug  then "True" else "False");
-        REAKTOR_CHANNELS = lib.concatStringsSep "," cfg.channels;
-        state_dir = cfg.workdir;
-
-        } // cfg.extraEnviron;
-      serviceConfig= {
-        ExecStartPre = pkgs.writeScript "Reaktor-init" ''
-          #! /bin/sh
-          ${if (isString cfg.overrideConfig) then
-            ''cp ${ReaktorConfig} /tmp/config.py''
-          else
-            ''(${pkgs.Reaktor}/bin/reaktor get-config;cat "${ReaktorConfig}" ) > /tmp/config.py''
-          }
+    systemd.services = mapAttrs' (name: botcfg:
+      let
+        ReaktorConfig = pkgs.writeText "config.py" ''
+          ${if (isString botcfg.overrideConfig ) then ''
+          # Overriden Config
+          ${botcfg.overrideConfig}
+          '' else ""}
+          ## Extra Config
+          ${concatStringsSep "\n" (map (plug: plug.config) botcfg.plugins)}
+          ${botcfg.extraConfig}
         '';
-        ExecStart = "${pkgs.Reaktor}/bin/reaktor run /tmp/config.py";
-        PrivateTmp = "true";
-        User = "Reaktor";
-        Restart = "always";
-        RestartSec= "30" ;
+      in nameValuePair "Reaktor-${name}" {
+        path = with pkgs; [
+          utillinux #flock for tell_on-join
+          git # for nag
+          python # for caps
+          ];
+        description = "Reaktor IRC Bot";
+        after = [ "network.target" ];
+        wantedBy = [ "multi-user.target" ];
+        environment = {
+          GIT_SSL_CAINFO = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
+          REAKTOR_NICKNAME = botcfg.nickname;
+          REAKTOR_DEBUG = (if botcfg.debug  then "True" else "False");
+          REAKTOR_CHANNELS = lib.concatStringsSep "," botcfg.channels;
+          state_dir = workdir;
+
+        } // botcfg.extraEnviron;
+        serviceConfig= {
+          ExecStartPre = pkgs.writeScript "Reaktor-init" ''
+            #! /bin/sh
+            ${if (isString botcfg.overrideConfig) then
+              ''cp ${ReaktorConfig} /tmp/reaktor-${name}-config.py''
+            else
+              ''(${pkgs.Reaktor}/bin/reaktor get-config;cat "${ReaktorConfig}" ) > /tmp/reaktor-${name}-config.py''
+            }
+          '';
+          ExecStart = "${pkgs.Reaktor}/bin/reaktor run /tmp/reaktor-${name}-config.py";
+          PrivateTmp = "true";
+          User = "Reaktor";
+          Restart = "always";
+          RestartSec= "30" ;
         };
-    };
+      }
+    ) cfg;
+
   };
 
 in