]> git.immae.eu Git - perso/Immae/Config/Nix/NUR.git/commitdiff
Start moving php configuration to a dedicated module
authorIsmaël Bouya <ismael.bouya@normalesup.org>
Sat, 1 Jun 2019 10:46:35 +0000 (12:46 +0200)
committerIsmaël Bouya <ismael.bouya@normalesup.org>
Fri, 24 Apr 2020 22:04:23 +0000 (00:04 +0200)
modules/default.nix
modules/websites/php-application.nix [new file with mode: 0644]

index e36f1a06e10b43ed06a0b2007a794029a484b9a1..dd34870235f99c58ffa6dd8dba818ab346cc340d 100644 (file)
@@ -10,5 +10,6 @@
   mediagoblin = ./webapps/mediagoblin.nix;
   peertube = ./webapps/peertube.nix;
 
+  php-application = ./websites/php-application.nix;
   websites = ./websites;
 } // (if builtins.pathExists ./private then import ./private else {})
diff --git a/modules/websites/php-application.nix b/modules/websites/php-application.nix
new file mode 100644 (file)
index 0000000..7bbae50
--- /dev/null
@@ -0,0 +1,152 @@
+{ lib, config, ... }:
+with lib;
+let
+  cfg = config.services.phpApplication;
+  cfgByEnv = lists.groupBy (x: x.websiteEnv) (builtins.attrValues cfg);
+in
+{
+  options = {
+    services.phpApplication = with types; mkOption {
+      default = {};
+      description = ''
+        php applications to define
+        '';
+      type = attrsOf (submodule {
+        options = {
+          varDir = mkOption {
+            type = nullOr path;
+            description = ''
+              Path to application’s vardir.
+              '';
+          };
+          mode = mkOption {
+            type = str;
+            default = "0700";
+            description = ''
+              Mode to apply to the vardir
+              '';
+          };
+          phpSession = mkOption {
+            type = bool;
+            default = true;
+            description = "Handle phpsession files separately in vardir";
+          };
+          websiteEnv = mkOption {
+            type = str;
+            description = ''
+              website instance name to use
+              '';
+          };
+          httpdUser = mkOption {
+            type = str;
+            default = config.services.httpd.user;
+            description = ''
+              httpd user to run the prestart scripts as.
+              '';
+          };
+          httpdGroup = mkOption {
+            type = str;
+            default = config.services.httpd.group;
+            description = ''
+              httpd group to run the prestart scripts as.
+              '';
+          };
+          app = mkOption {
+            type = path;
+            description = ''
+              Path to application root
+              '';
+          };
+          webappName = mkOption {
+            type = nullOr str;
+            description = ''
+              Alias name for the app, to be used in services.websites.webappDirs
+              '';
+          };
+          webRoot = mkOption {
+            type = nullOr path;
+            description = ''
+              Path to the web root path of the application. May differ from the application itself (usually a subdirectory)
+              '';
+          };
+          preStartActions = mkOption {
+            type = listOf str;
+            default = [];
+            description = ''
+              List of actions to run as apache user at preStart when
+              whatchFiles or app dir changed.
+              '';
+          };
+          serviceDeps = mkOption {
+            type = listOf str;
+            default = [];
+            description = ''
+              List of systemd services this application depends on
+              '';
+          };
+          watchFiles = mkOption {
+            type = listOf path;
+            default = [];
+            description = ''
+              Path to other files to watch to trigger preStart scripts
+              '';
+          };
+        };
+      });
+    };
+  };
+
+  config = {
+    services.websites = attrsets.mapAttrs' (name: cfgs: attrsets.nameValuePair
+      name {
+        modules = [ "proxy_fcgi" ];
+        watchPaths = builtins.concatLists (map (c: c.watchFiles) cfgs);
+      }
+    ) cfgByEnv;
+
+    services.websitesWebappDirs = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
+      icfg.webappName icfg.webRoot
+    ) (attrsets.filterAttrs (n: v: !isNull v.webappName && !isNull v.webRoot) cfg);
+
+    systemd.services = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
+      "phpfpm-${name}" {
+        after = lib.mkAfter icfg.serviceDeps;
+        wants = icfg.serviceDeps;
+        preStart = lib.mkAfter (optionalString (!isNull icfg.varDir) ''
+          watchFilesChanged() {
+            ${optionalString (builtins.length icfg.watchFiles == 0) "return 0"}
+            [ ! -f "${icfg.varDir}"/watchedFiles ] \
+              || ! sha512sum -c --status ${icfg.varDir}/watchedFiles
+          }
+          appDirChanged() {
+            [ ! -f "${icfg.varDir}/currentWebappDir" -o \
+              "${icfg.app}" != "$(cat ${icfg.varDir}/currentWebappDir 2>/dev/null)" ]
+          }
+          updateWatchFiles() {
+            ${optionalString (builtins.length icfg.watchFiles == 0) "return 0"}
+            sha512sum ${builtins.concatStringsSep " " icfg.watchFiles} > ${icfg.varDir}/watchedFiles
+          }
+
+          if watchFilesChanged || appDirChanged; then
+            pushd ${icfg.app} > /dev/null
+            ${builtins.concatStringsSep "\n  " (map (c: "/run/wrappers/bin/sudo -u ${icfg.httpdUser} ${c}") icfg.preStartActions) }
+            popd > /dev/null
+            echo -n "${icfg.app}" > ${icfg.varDir}/currentWebappDir
+            updateWatchFiles
+          fi
+        '');
+      }
+    ) cfg;
+
+    system.activationScripts = attrsets.mapAttrs' (name: icfg: attrsets.nameValuePair
+      name {
+        deps = [];
+        text = optionalString (!isNull icfg.varDir) ''
+          install -m ${icfg.mode} -o ${icfg.httpdUser} -g ${icfg.httpdGroup} -d ${icfg.varDir}
+          '' + optionalString (icfg.phpSession) ''
+          install -m 0700 -o ${icfg.httpdUser} -g ${icfg.httpdGroup} -d ${icfg.varDir}/phpSessions
+          '';
+      }
+    ) cfg;
+  };
+}