]> git.immae.eu Git - perso/Immae/Config/Nix.git/commitdiff
Add a filesWatcher service to restart them when secrets change
authorIsmaël Bouya <ismael.bouya@normalesup.org>
Fri, 31 May 2019 22:01:46 +0000 (00:01 +0200)
committerIsmaël Bouya <ismael.bouya@normalesup.org>
Fri, 31 May 2019 22:01:46 +0000 (00:01 +0200)
25 files changed:
modules/default.nix
modules/filesWatcher.nix [new file with mode: 0644]
modules/private/buildbot/default.nix
modules/private/databases/openldap/default.nix
modules/private/ftp.nix
modules/private/mpd.nix
modules/private/tasks/default.nix
modules/private/websites/aten/integration.nix
modules/private/websites/aten/production.nix
modules/private/websites/chloe/integration.nix
modules/private/websites/chloe/production.nix
modules/private/websites/connexionswing/integration.nix
modules/private/websites/connexionswing/production.nix
modules/private/websites/default.nix
modules/private/websites/florian/app.nix
modules/private/websites/ludivinecassal/integration.nix
modules/private/websites/ludivinecassal/production.nix
modules/private/websites/tools/diaspora/default.nix
modules/private/websites/tools/ether/default.nix
modules/private/websites/tools/mastodon/default.nix
modules/private/websites/tools/mgoblin/default.nix
modules/private/websites/tools/peertube/default.nix
modules/private/websites/tools/tools/default.nix
modules/secrets.nix
modules/websites/default.nix

index acb0bb5161d18e3dc95db394ba54c1a7cb820da1..e36f1a06e10b43ed06a0b2007a794029a484b9a1 100644 (file)
@@ -1,6 +1,7 @@
 {
   myids = ./myids.nix;
   secrets = ./secrets.nix;
+  filesWatcher = ./filesWatcher.nix;
 
   webstats = ./webapps/webstats;
   diaspora = ./webapps/diaspora.nix;
diff --git a/modules/filesWatcher.nix b/modules/filesWatcher.nix
new file mode 100644 (file)
index 0000000..4444027
--- /dev/null
@@ -0,0 +1,61 @@
+{ lib, config, pkgs, ... }:
+with lib;
+let
+  cfg = config.services.filesWatcher;
+in
+{
+  options = {
+    services.filesWatcher = with types; mkOption {
+      default = {};
+      description = ''
+        Files to watch and trigger service reload or restart of service
+        when changed.
+        '';
+        type = attrsOf (submodule {
+          options = {
+            restart = mkEnableOption "Restart service rather than reloading it";
+            paths = mkOption {
+              type = listOf str;
+              description = ''
+                Paths to watch that should trigger a reload of the
+                service
+                '';
+            };
+            waitTime = mkOption {
+              type = int;
+              default = 5;
+              description = ''
+                Time to wait before reloading/restarting the service.
+                Set 0 to not wait.
+                '';
+            };
+          };
+      });
+    };
+  };
+
+  config.systemd.services = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
+    "${name}Watcher" {
+      description = "${name} reloader";
+      after = [ "network.target" ];
+      script = let
+        action = if icfg.restart then "restart" else "reload";
+      in ''
+        # Service may be stopped during file modification (e.g. activationScripts)
+        if ${pkgs.systemd}/bin/systemctl --quiet is-active ${name}.service; then
+          ${pkgs.coreutils}/bin/sleep ${toString icfg.waitTime}
+          ${pkgs.systemd}/bin/systemctl ${action} ${name}.service
+        fi
+        '';
+      serviceConfig = {
+        Type = "oneshot";
+      };
+    }
+  ) cfg;
+  config.systemd.paths = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
+    "${name}Watcher" {
+      wantedBy = [ "multi-user.target" ];
+      pathConfig.PathChanged = icfg.paths;
+    }
+  ) cfg;
+}
index fa6a6f20f3c4a17d3c6c2cc2bb59a4e2149c6fde..d023a835e83afc5f989496fc45b2e1dd0fe25e7a 100644 (file)
@@ -37,6 +37,10 @@ in
       extraGroups = [ "keys" ];
     };
 
+    services.websites.tools.watchPaths = lib.attrsets.mapAttrsToList
+      (k: project: "/var/secrets/buildbot/${project.name}/webhook-httpd-include")
+      myconfig.env.buildbot.projects;
+
     services.websites.tools.vhostConfs.git.extraConfig = lib.attrsets.mapAttrsToList (k: project: ''
         RedirectMatch permanent "^/buildbot/${project.name}$" "/buildbot/${project.name}/"
         RewriteEngine On
@@ -106,6 +110,14 @@ in
       }
     ];
 
+    services.filesWatcher = lib.attrsets.mapAttrs' (k: project: lib.attrsets.nameValuePair "buildbot-${project.name}" {
+      restart = true;
+      paths = [
+        "/var/secrets/buildbot/ldap"
+        "/var/secrets/buildbot/ssh_key"
+      ] ++ lib.attrsets.mapAttrsToList (k: v: "/var/secrets/buildbot/${project.name}/${k}") project.secrets;
+    }) myconfig.env.buildbot.projects;
+
     systemd.services = lib.attrsets.mapAttrs' (k: project: lib.attrsets.nameValuePair "buildbot-${project.name}" {
       description = "Buildbot Continuous Integration Server ${project.name}.";
       after = [ "network-online.target" ];
index e048d565200f532eaddfa6c4ab8eb7ce3112254e..f09113a0889969d252a93aa52dbb8c78b1041e0e 100644 (file)
@@ -144,6 +144,11 @@ in
       '';
     };
 
+    services.filesWatcher.openldap = {
+      restart = true;
+      paths = [ "${config.secrets.location}/ldap/" ];
+    };
+
     services.openldap = {
       enable = true;
       dataDir = cfg.dataDir;
index ada5f416bed9ca0d82a68c72883986d48491fe57..59cae595bfe1c359aa6e6e7ef36a3c4a142a1937 100644 (file)
@@ -72,6 +72,11 @@ in
         '';
     }];
 
+    services.filesWatcher.pure-ftpd = {
+      restart = true;
+      paths = [ "/var/secrets/pure-ftpd-ldap" ];
+    };
+
     systemd.services.pure-ftpd = let
       configFile = pkgs.writeText "pure-ftpd.conf" ''
         PassivePortRange             40000 50000
index 9903bdf0d2ba1dea3701057c740f75a7644610a3..17454d72aa9c1bdef74c8351b49b5a1eb6e1863b 100644 (file)
     networking.firewall.allowedTCPPorts = [ 6600 ];
     users.users.mpd.extraGroups = [ "wwwrun" "keys" ];
     systemd.services.mpd.serviceConfig.RuntimeDirectory = "mpd";
+    services.filesWatcher.mpd = {
+      restart = true;
+      paths = [ "/var/secrets/mpd-config" ];
+    };
+
     services.mpd = {
       enable = true;
       network.listenAddress = "any";
index 30f49ee933e11b6f49e458c87f69a5d5d53c135c..83a1b616b13934f567a6d509a5d4f76ac617a6db 100644 (file)
@@ -101,6 +101,7 @@ in {
           SetEnv TASKD_LDAP_FILTER   "${env.ldap.search}"
         '';
     }];
+    services.websites.tools.watchPaths = [ "/var/secrets/webapps/tools-taskwarrior-web" ];
     services.websites.tools.modules = [ "proxy_fcgi" "sed" ];
     services.websites.tools.vhostConfs.task = {
       certName    = "eldiron";
index 748e388554ac65abbb86be8bcce6923131a1b07c..384b32454e191d01eda6706d493cb54ae37759b9 100644 (file)
@@ -27,6 +27,9 @@ in {
       root        = aten.apache.root;
       extraConfig = [ aten.apache.vhostConf ];
     };
+    services.websites.integration.watchPaths = [
+      "/var/secrets/webapps/${aten.app.environment}-aten"
+    ];
   };
 }
 
index 7a4adb5a2f865fc191315baed7613d234648fc6b..1a55e8a46cdc0ac178b4f656df9ea689a48c676e 100644 (file)
@@ -29,6 +29,8 @@ in {
       root         = aten.apache.root;
       extraConfig  = [ aten.apache.vhostConf ];
     };
+    services.websites.production.watchPaths = [
+      "/var/secrets/webapps/${aten.app.environment}-aten"
+    ];
   };
 }
-
index c42a428250c6542d9a486f0d9aa4989b5859645f..25ec4db3a3d95e86cac1408b516134a7b69fa058 100644 (file)
@@ -32,5 +32,8 @@ in {
       root        = chloe.apache.root;
       extraConfig = [ chloe.apache.vhostConf ];
     };
+    services.websites.integration.watchPaths = [
+      "/var/secrets/webapps/${chloe.app.environment}-chloe"
+    ];
   };
 }
index 0bf2d8fd3891a4e09d71bf8ce2bc3a66d0107508..6e0c34d7d8cb6789361ca10dcf65c78106380871 100644 (file)
@@ -34,5 +34,8 @@ in {
       root         = chloe.apache.root;
       extraConfig  = [ chloe.apache.vhostConf ];
     };
+    services.websites.production.watchPaths = [
+      "/var/secrets/webapps/${chloe.app.environment}-chloe"
+    ];
   };
 }
index 1d8488a9eb08cc231ea7d38a8e27a94b2e47d51b..7d77ac77f06e53b6c23f2a2a726e101541910dc2 100644 (file)
@@ -31,6 +31,10 @@ in {
       root        = connexionswing.apache.root;
       extraConfig = [ connexionswing.apache.vhostConf ];
     };
+    services.filesWatcher.phpfpm-connexionswing_dev = {
+      restart = true;
+      paths = [ "/var/secrets/webapps/${connexionswing.app.environment}-connexionswing" ];
+    };
   };
 }
 
index 555f129f2f85116c1debfd866da19c770d70556e..f4cb377236bdd2b3e5731b182d77f46db6422962 100644 (file)
@@ -33,6 +33,10 @@ in {
       root         = connexionswing.apache.root;
       extraConfig  = [ connexionswing.apache.vhostConf ];
     };
+    services.filesWatcher.phpfpm-connexionswing_prod = {
+      restart = true;
+      paths = [ "/var/secrets/webapps/${connexionswing.app.environment}-connexionswing" ];
+    };
   };
 }
 
index 8b02977c98ff8111e300ae446463be7cead4b37b..c3d941c2f5014b3867e12e54fe806aaff6883f90 100644 (file)
@@ -138,6 +138,10 @@ in
         '';
     };
 
+    services.filesWatcher.httpdProd.paths = [ "/var/secrets/apache-ldap" ];
+    services.filesWatcher.httpdInte.paths = [ "/var/secrets/apache-ldap" ];
+    services.filesWatcher.httpdTools.paths = [ "/var/secrets/apache-ldap" ];
+
     services.websites.production = {
       enable = true;
       adminAddr = "httpd@immae.eu";
index 3a6d1522103c269cabc55c00651d57fa6e7fd389..55fb3cb232d03fec08ca67659d3e4729089eb1e4 100644 (file)
@@ -32,5 +32,9 @@ in {
         adminer.apache.vhostConf
       ];
     };
+    services.filesWatcher.phpfpm-tellesflorian_dev = {
+      restart = true;
+      paths = [ "/var/secrets/webapps/${tellesflorian.app.environment}-tellesflorian" ];
+    };
   };
 }
index ed0dc9feaaefa6d7ca5ef86f3102863355e9034a..f0ef3a66a2796aba67c7485b2835a9cfe0fa4260 100644 (file)
@@ -28,5 +28,9 @@ in {
       root        = ludivinecassal.apache.root;
       extraConfig = [ ludivinecassal.apache.vhostConf ];
     };
+    services.filesWatcher.phpfpm-ludivinecassal_dev = {
+      restart = true;
+      paths = [ "/var/secrets/webapps/${ludivinecassal.app.environment}-ludivinecassal" ];
+    };
   };
 }
index 3df5613fce6c0da062ff4183cac1e5f5f1515760..6a22d98474a51943f6d1b41903bc4f7eee699a08 100644 (file)
@@ -29,5 +29,9 @@ in {
       root         = ludivinecassal.apache.root;
       extraConfig  = [ ludivinecassal.apache.vhostConf ];
     };
+    services.filesWatcher.phpfpm-ludivinecassal_prod = {
+      restart = true;
+      paths = [ "/var/secrets/webapps/${ludivinecassal.app.environment}-ludivinecassal" ];
+    };
   };
 }
index efa1fabbdb6e793d43f1cb65c5831a49e7047b67..6742a8108d437ad56c176b7efca1d6749f0d9afe 100644 (file)
@@ -145,6 +145,11 @@ in {
       configDir = "/var/secrets/webapps/diaspora";
     };
 
+    services.filesWatcher.diaspora = {
+      restart = true;
+      paths = [ dcfg.configDir ];
+    };
+
     services.websites.tools.modules = [
       "headers" "proxy" "proxy_http"
     ];
index ebcbf6187af8173078e71c23fb8d128d05be4fc9..3e68d54e5ee2fbe3d4834f08fec4fa3a4ef019d3 100644 (file)
@@ -133,6 +133,11 @@ in {
 
     systemd.services.etherpad-lite.serviceConfig.SupplementaryGroups = "keys";
 
+    services.filesWatcher.etherpad-lite = {
+      restart = true;
+      paths = [ ecfg.sessionKeyFile ecfg.apiKeyFile ecfg.configFile ];
+    };
+
     services.websites.tools.modules = [
       "headers" "proxy" "proxy_http" "proxy_wstunnel"
     ];
index d742a33a38a4a29c3dbd9db0292d3f7a163dc002..1a4b387c769a3cd55cf568afd7181dbbc4de1186 100644 (file)
@@ -63,6 +63,19 @@ in {
       socketsPrefix = "live_immae";
       dataDir = "/var/lib/mastodon_immae";
     };
+    services.filesWatcher.mastodon-streaming = {
+      restart = true;
+      paths = [ mcfg.configFile ];
+    };
+    services.filesWatcher.mastodon-web = {
+      restart = true;
+      paths = [ mcfg.configFile ];
+    };
+    services.filesWatcher.mastodon-sidekiq = {
+      restart = true;
+      paths = [ mcfg.configFile ];
+    };
+
 
     services.websites.tools.modules = [
       "headers" "proxy" "proxy_wstunnel" "proxy_http"
index 5da81f68163bc6831c1a5c04f5f1713243bcd95d..1d398db24ebecf20e6b39ee483af6ecb18cc5929 100644 (file)
@@ -78,6 +78,14 @@ in {
       plugins    = builtins.attrValues pkgs.webapps.mediagoblin-plugins;
       configFile = "/var/secrets/webapps/tools-mediagoblin";
     };
+    services.filesWatcher.mediagoblin-web = {
+      restart = true;
+      paths = [ mcfg.configFile ];
+    };
+    services.filesWatcher.mediagoblin-celeryd = {
+      restart = true;
+      paths = [ mcfg.configFile ];
+    };
 
     services.websites.tools.modules = [
       "proxy" "proxy_http"
index dee1b81db79968a7750a0bca62a6f6bd01fb0dfb..dd2853039a33db38beda72d1461cdbdd8e8ebed9 100644 (file)
@@ -153,6 +153,11 @@ in {
     services.websites.tools.modules = [
       "headers" "proxy" "proxy_http" "proxy_wstunnel"
     ];
+    services.filesWatcher.peertube = {
+      restart = true;
+      paths = [ pcfg.configFile ];
+    };
+
     services.websites.tools.vhostConfs.peertube = {
       certName    = "eldiron";
       addToCerts  = true;
index 94a2be164d7fe15d2aef7aaf7d431e5cd5ddafdc..d75def47fdebcf2cf94d57e139fda2f44388a755 100644 (file)
@@ -212,6 +212,11 @@ in {
       };
     };
 
+    services.filesWatcher.ympd = {
+      restart = true;
+      paths = [ "/var/secrets/mpd" ];
+    };
+
     services.phpfpm.pools.roundcubemail = {
       listen = roundcubemail.phpFpm.socket;
       extraConfig = roundcubemail.phpFpm.pool;
@@ -297,6 +302,13 @@ in {
       "${kanboard.apache.webappName}" = kanboard.webRoot;
     };
 
+    services.websites.tools.watchPaths = [
+      "/var/secrets/webapps/tools-wallabag"
+    ];
+    services.filesWatcher.phpfpm-wallabag = {
+      restart = true;
+      paths = [ "/var/secrets/webapps/tools-wallabag" ];
+    };
   };
 }
 
index b282e56e207d17f12b2ef46bfc6da5321d909eb7..808b15c5bdeb886347a8f9c34f69891495e0999f 100644 (file)
         if [ -f /run/keys/secrets.tar ]; then
           if [ ! -f ${location}/currentSecrets ] || ! sha512sum -c --status "${location}/currentSecrets"; then
             echo "rebuilding secrets"
-            rm -rf ${location}
-            install -m0750 -o root -g keys -d ${location}
-            ${pkgs.gnutar}/bin/tar --strip-components 1 -C ${location} -xf /run/keys/secrets.tar
-            sha512sum /run/keys/secrets.tar > ${location}/currentSecrets
-            find ${location} -type d -exec chown root:keys {} \; -exec chmod o-rx {} \;
+            TMP=$(${pkgs.coreutils}/bin/mktemp -d)
+            if [ -n "$TMP" ]; then
+              install -m0750 -o root -g keys -d $TMP
+              ${pkgs.gnutar}/bin/tar --strip-components 1 -C $TMP -xf /run/keys/secrets.tar
+              sha512sum /run/keys/secrets.tar > $TMP/currentSecrets
+              find $TMP -type d -exec chown root:keys {} \; -exec chmod o-rx {} \;
+              ${pkgs.rsync}/bin/rsync -O -c -av --delete $TMP/ ${location}
+              rm -rf $TMP
+            fi
           fi
         fi
         '';
index e57f505a86fae43fc3b523c5f9210db6b82a7895..4b21efb75eb386e97a42068313080d132e29cf05 100644 (file)
@@ -91,6 +91,13 @@ in
             };
           });
         };
+        watchPaths = mkOption {
+          type = listOf string;
+          default = [];
+          description = ''
+            Paths to watch that should trigger a reload of httpd
+            '';
+        };
       };
     });
   };
@@ -159,6 +166,13 @@ in
     })
   ) cfg;
 
+  config.services.filesWatcher = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
+    "httpd${icfg.httpdName}" {
+      paths = icfg.watchPaths;
+      waitTime = 5;
+    }
+  ) cfg;
+
   config.security.acme.certs = let
     typesToManage = attrsets.filterAttrs (k: v: v.enable) cfg;
     flatVhosts = lists.flatten (attrsets.mapAttrsToList (k: v: