]> git.immae.eu Git - perso/Immae/Config/Nix/NUR.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, 24 Apr 2020 22:04:23 +0000 (00:04 +0200)
modules/default.nix
modules/filesWatcher.nix [new file with mode: 0644]
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 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: