diff --git a/nixos/modules/system/boot/systemd-unit-options.nix b/nixos/modules/system/boot/systemd-unit-options.nix
index a1faea886f9..cb116e9e92a 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
[Unit] 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
[Service] 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
[Socket] 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
[Timer] 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
[Mount] 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
[Automount] section of the unit. See
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index 5c25dabd0c0..31e795ea2d0 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}
'';
};