about summary refs log tree commit diff
path: root/nixos/lib/systemd-lib.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/lib/systemd-lib.nix')
-rw-r--r--nixos/lib/systemd-lib.nix84
1 files changed, 34 insertions, 50 deletions
diff --git a/nixos/lib/systemd-lib.nix b/nixos/lib/systemd-lib.nix
index 37900b0b16f6..16ec47df3a46 100644
--- a/nixos/lib/systemd-lib.nix
+++ b/nixos/lib/systemd-lib.nix
@@ -122,10 +122,15 @@ in rec {
         (if isList value then value else [value]))
         as));
 
-  generateUnits = generateUnits' true;
-
-  generateUnits' = allowCollisions: type: units: upstreamUnits: upstreamWants:
-    pkgs.runCommand "${type}-units"
+  generateUnits = { allowCollisions ? true, type, units, upstreamUnits, upstreamWants, packages ? cfg.packages, package ? cfg.package }:
+    let
+      typeDir = ({
+        system = "system";
+        initrd = "system";
+        user = "user";
+        nspawn = "nspawn";
+      }).${type};
+    in pkgs.runCommand "${type}-units"
       { preferLocalBuild = true;
         allowSubstitutes = false;
       } ''
@@ -133,7 +138,7 @@ in rec {
 
       # Copy the upstream systemd units we're interested in.
       for i in ${toString upstreamUnits}; do
-        fn=${cfg.package}/example/systemd/${type}/$i
+        fn=${package}/example/systemd/${typeDir}/$i
         if ! [ -e $fn ]; then echo "missing $fn"; false; fi
         if [ -L $fn ]; then
           target="$(readlink "$fn")"
@@ -150,7 +155,7 @@ in rec {
       # Copy .wants links, but only those that point to units that
       # we're interested in.
       for i in ${toString upstreamWants}; do
-        fn=${cfg.package}/example/systemd/${type}/$i
+        fn=${package}/example/systemd/${typeDir}/$i
         if ! [ -e $fn ]; then echo "missing $fn"; false; fi
         x=$out/$(basename $fn)
         mkdir $x
@@ -162,14 +167,14 @@ in rec {
       done
 
       # Symlink all units provided listed in systemd.packages.
-      packages="${toString cfg.packages}"
+      packages="${toString packages}"
 
       # Filter duplicate directories
       declare -A unique_packages
       for k in $packages ; do unique_packages[$k]=1 ; done
 
       for i in ''${!unique_packages[@]}; do
-        for fn in $i/etc/systemd/${type}/* $i/lib/systemd/${type}/*; do
+        for fn in $i/etc/systemd/${typeDir}/* $i/lib/systemd/${typeDir}/*; do
           if ! [[ "$fn" =~ .wants$ ]]; then
             if [[ -d "$fn" ]]; then
               targetDir="$out/$(basename "$fn")"
@@ -270,9 +275,9 @@ in rec {
           { Conflicts = toString config.conflicts; }
         // optionalAttrs (config.requisite != [])
           { Requisite = toString config.requisite; }
-        // optionalAttrs (config.restartTriggers != [])
+        // optionalAttrs (config ? restartTriggers && config.restartTriggers != [])
           { X-Restart-Triggers = toString config.restartTriggers; }
-        // optionalAttrs (config.reloadTriggers != [])
+        // optionalAttrs (config ? reloadTriggers && config.reloadTriggers != [])
           { X-Reload-Triggers = toString config.reloadTriggers; }
         // optionalAttrs (config.description != "") {
           Description = config.description; }
@@ -288,45 +293,24 @@ in rec {
     };
   };
 
-  serviceConfig = { name, config, ... }: {
-    config = mkMerge
-      [ { # Default path for systemd services.  Should be quite minimal.
-          path = mkAfter
-            [ pkgs.coreutils
-              pkgs.findutils
-              pkgs.gnugrep
-              pkgs.gnused
-              systemd
-            ];
-          environment.PATH = "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}";
-        }
-        (mkIf (config.preStart != "")
-          { serviceConfig.ExecStartPre =
-              [ (makeJobScript "${name}-pre-start" config.preStart) ];
-          })
-        (mkIf (config.script != "")
-          { serviceConfig.ExecStart =
-              makeJobScript "${name}-start" config.script + " " + config.scriptArgs;
-          })
-        (mkIf (config.postStart != "")
-          { serviceConfig.ExecStartPost =
-              [ (makeJobScript "${name}-post-start" config.postStart) ];
-          })
-        (mkIf (config.reload != "")
-          { serviceConfig.ExecReload =
-              makeJobScript "${name}-reload" config.reload;
-          })
-        (mkIf (config.preStop != "")
-          { serviceConfig.ExecStop =
-              makeJobScript "${name}-pre-stop" config.preStop;
-          })
-        (mkIf (config.postStop != "")
-          { serviceConfig.ExecStopPost =
-              makeJobScript "${name}-post-stop" config.postStop;
-          })
-      ];
+  serviceConfig = { config, ... }: {
+    config.environment.PATH = mkIf (config.path != []) "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}";
   };
 
+  stage2ServiceConfig = {
+    imports = [ serviceConfig ];
+    # Default path for systemd services. Should be quite minimal.
+    config.path = mkAfter [
+      pkgs.coreutils
+      pkgs.findutils
+      pkgs.gnugrep
+      pkgs.gnused
+      systemd
+    ];
+  };
+
+  stage1ServiceConfig = serviceConfig;
+
   mountConfig = { config, ... }: {
     config = {
       mountConfig =
@@ -374,12 +358,12 @@ in rec {
               # systemd max line length is now 1MiB
               # https://github.com/systemd/systemd/commit/e6dde451a51dc5aaa7f4d98d39b8fe735f73d2af
               in if stringLength s >= 1048576 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${name}.service’ is too long." else s) (attrNames env)}
-          ${if def.reloadIfChanged then ''
+          ${if def ? reloadIfChanged && def.reloadIfChanged then ''
             X-ReloadIfChanged=true
-          '' else if !def.restartIfChanged then ''
+          '' else if (def ? restartIfChanged && !def.restartIfChanged) then ''
             X-RestartIfChanged=false
           '' else ""}
-          ${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"}
+          ${optionalString (def ? stopIfChanged && !def.stopIfChanged) "X-StopIfChanged=false"}
           ${attrsToSection def.serviceConfig}
         '';
     };