systemd: Allow customisation of upstream units

You can now say:

  systemd.services.foo.baseUnit = "${pkgs.foo}/.../foo.service";

This will cause NixOS' generated foo.service file to include
foo.service from the foo package.  You can then apply local
customization in the usual way:

  systemd.services.foo.serviceConfig.MemoryLimit = "512M";

Note however that overriding options in the original unit may not
work.  For instance, you cannot override ExecStart.

It's also possible to customize instances of template units:

  systemd.services."getty@tty4" =
    { baseUnit = "/etc/systemd/system/getty@.service";
      serviceConfig.MemoryLimit = "512M";
    };

This replaces the unit options linkTarget (which didn't allow
customisation) and extraConfig (which did allow customisation, but in
a non-standard way).
This commit is contained in:
Eelco Dolstra 2014-03-12 18:20:57 +01:00
parent 3358906395
commit 691c0cd72e
2 changed files with 22 additions and 45 deletions

View file

@ -41,6 +41,12 @@ in rec {
'';
};
baseUnit = mkOption {
type = types.nullOr types.path;
default = null;
description = "Path to an upstream unit file on which the NixOS unit configuration will be based.";
};
description = mkOption {
default = "";
type = types.str;

View file

@ -12,18 +12,12 @@ let
makeUnit = name: unit:
pkgs.runCommand "unit" { preferLocalBuild = true; inherit (unit) text; }
((if !unit.enable then ''
(if !unit.enable then ''
mkdir -p $out
ln -s /dev/null $out/${name}
'' else if unit.linkTarget != null then ''
mkdir -p $out
ln -s ${unit.linkTarget} $out/${name}
'' else if unit.text != null then ''
'' else ''
mkdir -p $out
echo -n "$text" > $out/${name}
'' else "") + optionalString (unit.extraConfig != {}) ''
mkdir -p $out/${name}.d
${concatStringsSep "\n" (mapAttrsToList (n: v: "echo -n \"${v}\" > $out/${name}.d/${n}") unit.extraConfig)}
'');
upstreamUnits =
@ -158,7 +152,7 @@ let
BindsTo = concatStringsSep " " config.bindsTo;
PartOf = concatStringsSep " " config.partOf;
Conflicts = concatStringsSep " " config.conflicts;
"X-Restart-Triggers" = toString config.restartTriggers;
X-Restart-Triggers = toString config.restartTriggers;
} // optionalAttrs (config.description != "") {
Description = config.description;
};
@ -244,6 +238,14 @@ let
(if isList value then value else [value]))
as));
commonUnitText = def:
optionalString (def.baseUnit != null) ''
.include ${def.baseUnit}
'' + ''
[Unit]
${attrsToSection def.unitConfig}
'';
targetToUnit = name: def:
{ inherit (def) wantedBy requiredBy enable;
text =
@ -255,11 +257,8 @@ let
serviceToUnit = name: def:
{ inherit (def) wantedBy requiredBy enable;
text =
text = commonUnitText def +
''
[Unit]
${attrsToSection def.unitConfig}
[Service]
${let env = cfg.globalEnvironment // def.environment;
in concatMapStrings (n: "Environment=\"${n}=${getAttr n env}\"\n") (attrNames env)}
@ -271,11 +270,8 @@ let
socketToUnit = name: def:
{ inherit (def) wantedBy requiredBy enable;
text =
text = commonUnitText def +
''
[Unit]
${attrsToSection def.unitConfig}
[Socket]
${attrsToSection def.socketConfig}
${concatStringsSep "\n" (map (s: "ListenStream=${s}") def.listenStreams)}
@ -284,11 +280,8 @@ let
timerToUnit = name: def:
{ inherit (def) wantedBy requiredBy enable;
text =
text = commonUnitText def +
''
[Unit]
${attrsToSection def.unitConfig}
[Timer]
${attrsToSection def.timerConfig}
'';
@ -296,11 +289,8 @@ let
mountToUnit = name: def:
{ inherit (def) wantedBy requiredBy enable;
text =
text = commonUnitText def +
''
[Unit]
${attrsToSection def.unitConfig}
[Mount]
${attrsToSection def.mountConfig}
'';
@ -308,11 +298,8 @@ let
automountToUnit = name: def:
{ inherit (def) wantedBy requiredBy enable;
text =
text = commonUnitText def +
''
[Unit]
${attrsToSection def.unitConfig}
[Automount]
${attrsToSection def.automountConfig}
'';
@ -423,22 +410,6 @@ in
internal = true;
description = "The generated unit.";
};
linkTarget = mkOption {
default = null;
description = "The file to symlink this target to.";
type = types.nullOr types.path;
};
extraConfig = mkOption {
default = {};
example = { "foo@1.conf" = "X-RestartIfChanged=false"; };
type = types.attrsOf types.lines;
description = ''
Extra files to be appended to the configuration for the unit.
This can be used to override configuration for a unit provided
by systemd or another package, or to override only a single instance
of a template unit.
'';
};
};
config = {
unit = makeUnit name config;