summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2013-11-18 15:45:24 +0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2013-11-18 18:04:16 +0100
commit5620e69b5dfce29f1759ec653d0f26745239f2af (patch)
treeda2020c93637c615cc59b249b57cee22a34a7e76 /nixos
parentf8a034172a42bf1f6b436df2e45677bd972d777f (diff)
downloadnixlib-5620e69b5dfce29f1759ec653d0f26745239f2af.tar
nixlib-5620e69b5dfce29f1759ec653d0f26745239f2af.tar.gz
nixlib-5620e69b5dfce29f1759ec653d0f26745239f2af.tar.bz2
nixlib-5620e69b5dfce29f1759ec653d0f26745239f2af.tar.lz
nixlib-5620e69b5dfce29f1759ec653d0f26745239f2af.tar.xz
nixlib-5620e69b5dfce29f1759ec653d0f26745239f2af.tar.zst
nixlib-5620e69b5dfce29f1759ec653d0f26745239f2af.zip
Apply better type checking to unitConfig/serviceConfig/...
In particular, complain if two modules define the same systemd option.
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/system/boot/systemd-unit-options.nix24
-rw-r--r--nixos/modules/system/boot/systemd.nix78
2 files changed, 54 insertions, 48 deletions
diff --git a/nixos/modules/system/boot/systemd-unit-options.nix b/nixos/modules/system/boot/systemd-unit-options.nix
index a1faea886f98..cb116e9e92a2 100644
--- a/nixos/modules/system/boot/systemd-unit-options.nix
+++ b/nixos/modules/system/boot/systemd-unit-options.nix
@@ -14,6 +14,16 @@ let
     in if errors == [] then true
        else builtins.trace (concatStringsSep "\n" errors) false;
 
+  unitOption = mkOptionType {
+    name = "systemd option";
+    merge = loc: defs:
+      let defs' = getValues defs;
+      in
+        if isList (head defs')
+        then concatLists defs'
+        else mergeOneOption loc defs;
+  };
+
 in rec {
 
   unitOptions = {
@@ -112,7 +122,7 @@ in rec {
     unitConfig = mkOption {
       default = {};
       example = { RequiresMountsFor = "/data"; };
-      type = types.attrs;
+      type = types.attrsOf unitOption;
       description = ''
         Each attribute in this set specifies an option in the
         <literal>[Unit]</literal> section of the unit.  See
@@ -137,7 +147,7 @@ in rec {
 
     environment = mkOption {
       default = {};
-      type = types.attrs;
+      type = types.attrs; # FIXME
       example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; };
       description = "Environment variables passed to the service's processes.";
     };
@@ -159,7 +169,7 @@ in rec {
         { StartLimitInterval = 10;
           RestartSec = 5;
         };
-      type = types.addCheck types.attrs checkService;
+      type = types.addCheck (types.attrsOf unitOption) checkService;
       description = ''
         Each attribute in this set specifies an option in the
         <literal>[Service]</literal> section of the unit.  See
@@ -263,7 +273,7 @@ in rec {
     socketConfig = mkOption {
       default = {};
       example = { ListenStream = "/run/my-socket"; };
-      type = types.attrs;
+      type = types.attrsOf unitOption;
       description = ''
         Each attribute in this set specifies an option in the
         <literal>[Socket]</literal> section of the unit.  See
@@ -280,7 +290,7 @@ in rec {
     timerConfig = mkOption {
       default = {};
       example = { OnCalendar = "Sun 14:00:00"; Unit = "foo.service"; };
-      type = types.attrs;
+      type = types.attrsOf unitOption;
       description = ''
         Each attribute in this set specifies an option in the
         <literal>[Timer]</literal> section of the unit.  See
@@ -328,7 +338,7 @@ in rec {
     mountConfig = mkOption {
       default = {};
       example = { DirectoryMode = "0775"; };
-      type = types.attrs;
+      type = types.attrsOf unitOption;
       description = ''
         Each attribute in this set specifies an option in the
         <literal>[Mount]</literal> section of the unit.  See
@@ -352,7 +362,7 @@ in rec {
     automountConfig = mkOption {
       default = {};
       example = { DirectoryMode = "0775"; };
-      type = types.attrs;
+      type = types.attrsOf unitOption;
       description = ''
         Each attribute in this set specifies an option in the
         <literal>[Automount]</literal> section of the unit.  See
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index 5c25dabd0c0e..31e795ea2d04 100644
--- a/nixos/modules/system/boot/systemd.nix
+++ b/nixos/modules/system/boot/systemd.nix
@@ -160,16 +160,43 @@ let
   };
 
   serviceConfig = { name, config, ... }: {
-    config = {
-      # Default path for systemd services.  Should be quite minimal.
-      path =
-        [ pkgs.coreutils
-          pkgs.findutils
-          pkgs.gnugrep
-          pkgs.gnused
-          systemd
-        ];
-    };
+    config = mkMerge
+      [ { # Default path for systemd services.  Should be quite minimal.
+          path =
+            [ pkgs.coreutils
+              pkgs.findutils
+              pkgs.gnugrep
+              pkgs.gnused
+              systemd
+            ];
+          environment.PATH = config.path;
+          environment.LD_LIBRARY_PATH = "";
+        }
+        (mkIf (config.preStart != "")
+          { serviceConfig.ExecStartPre = makeJobScript "${name}-pre-start" ''
+              #! ${pkgs.stdenv.shell} -e
+              ${config.preStart}
+            '';
+          })
+        (mkIf (config.script != "")
+          { serviceConfig.ExecStart = makeJobScript "${name}-start" ''
+              #! ${pkgs.stdenv.shell} -e
+              ${config.script}
+            '' + " " + config.scriptArgs;
+          })
+        (mkIf (config.postStart != "")
+          { serviceConfig.ExecStartPost = makeJobScript "${name}-post-start" ''
+              #! ${pkgs.stdenv.shell} -e
+              ${config.postStart}
+            '';
+          })
+        (mkIf (config.postStop != "")
+          { serviceConfig.ExecStopPost = makeJobScript "${name}-post-stop" ''
+              #! ${pkgs.stdenv.shell} -e
+              ${config.postStop}
+            '';
+          })
+      ];
   };
 
   mountConfig = { name, config, ... }: {
@@ -223,41 +250,10 @@ let
           ${attrsToSection def.unitConfig}
 
           [Service]
-          Environment=PATH=${def.path}
-          Environment=LD_LIBRARY_PATH=
           ${let env = cfg.globalEnvironment // def.environment;
             in concatMapStrings (n: "Environment=\"${n}=${getAttr n env}\"\n") (attrNames env)}
           ${optionalString (!def.restartIfChanged) "X-RestartIfChanged=false"}
           ${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"}
-
-          ${optionalString (def.preStart != "") ''
-            ExecStartPre=${makeJobScript "${name}-pre-start" ''
-              #! ${pkgs.stdenv.shell} -e
-              ${def.preStart}
-            ''}
-          ''}
-
-          ${optionalString (def.script != "") ''
-            ExecStart=${makeJobScript "${name}-start" ''
-              #! ${pkgs.stdenv.shell} -e
-              ${def.script}
-            ''} ${def.scriptArgs}
-          ''}
-
-          ${optionalString (def.postStart != "") ''
-            ExecStartPost=${makeJobScript "${name}-post-start" ''
-              #! ${pkgs.stdenv.shell} -e
-              ${def.postStart}
-            ''}
-          ''}
-
-          ${optionalString (def.postStop != "") ''
-            ExecStopPost=${makeJobScript "${name}-post-stop" ''
-              #! ${pkgs.stdenv.shell} -e
-              ${def.postStop}
-            ''}
-          ''}
-
           ${attrsToSection def.serviceConfig}
         '';
     };