Make unitConfig/serviceConfig attribute sets

So instead of:

  boot.systemd.services."foo".serviceConfig =
    ''
      StartLimitInterval=10
      CPUShare=500
    '';

you can say:

  boot.systemd.services."foo".serviceConfig.StartLimitInterval = 10;
  boot.systemd.services."foo".serviceConfig.CPUShare = 500;

This way all unit options are available and users can set/override
options in configuration.nix.
This commit is contained in:
Eelco Dolstra 2012-10-01 16:27:42 -04:00
parent 440b793a5b
commit 891be375b5
9 changed files with 100 additions and 105 deletions

View File

@ -194,15 +194,14 @@ in
''; '';
serviceConfig = serviceConfig =
'' { # Shut down Postgres using SIGINT ("Fast Shutdown mode"). See
# Shut down Postgres using SIGINT ("Fast Shutdown mode"). See
# http://www.postgresql.org/docs/current/static/server-shutdown.html # http://www.postgresql.org/docs/current/static/server-shutdown.html
KillSignal=SIGINT KillSignal = "SIGINT";
# Give Postgres a decent amount of time to clean up after # Give Postgres a decent amount of time to clean up after
# receiving systemd's SIGINT. # receiving systemd's SIGINT.
TimeoutSec=60 TimeoutSec = 60;
''; };
}; };
}; };

View File

@ -106,8 +106,8 @@ in
# FIXME: restarting syslog seems to break journal logging. # FIXME: restarting syslog seems to break journal logging.
boot.systemd.services.syslog = boot.systemd.services.syslog =
{ description = "Syslog daemon"; { description = "Syslog Daemon";
requires = [ "syslog.socket" ]; requires = [ "syslog.socket" ];
wantedBy = [ "multi-user.target" "syslog.target" ]; wantedBy = [ "multi-user.target" "syslog.target" ];
@ -115,11 +115,10 @@ in
environment.TZ = config.time.timeZone; environment.TZ = config.time.timeZone;
serviceConfig = serviceConfig =
'' { ExecStart = "${pkgs.sysklogd}/sbin/syslogd ${toString cfg.extraParams} -f ${syslogConf} -n";
ExecStart=${pkgs.sysklogd}/sbin/syslogd ${toString cfg.extraParams} -f ${syslogConf} -n
# Prevent syslogd output looping back through journald. # Prevent syslogd output looping back through journald.
StandardOutput=null StandardOutput = "null";
''; };
}; };
}; };

View File

@ -258,7 +258,7 @@ in
ListenStream=/nix/var/nix/daemon-socket/socket ListenStream=/nix/var/nix/daemon-socket/socket
''; '';
}; };
boot.systemd.services."nix-daemon" = boot.systemd.services."nix-daemon" =
{ description = "Nix Daemon"; { description = "Nix Daemon";
@ -268,16 +268,14 @@ in
environment = cfg.envVars; environment = cfg.envVars;
serviceConfig = serviceConfig =
'' { ExecStart = "${nix}/bin/nix-worker --daemon";
ExecStart=${nix}/bin/nix-worker --daemon KillMode = "process";
KillMode=process Nice = cfg.daemonNiceLevel;
PIDFile=/run/sshd.pid IOSchedulingPriority = cfg.daemonIONiceLevel;
Nice=${toString cfg.daemonNiceLevel} LimitNOFILE = 4096;
IOSchedulingPriority=${toString cfg.daemonIONiceLevel} };
LimitNOFILE=4096
'';
}; };
nix.envVars = nix.envVars =
{ NIX_CONF_DIR = "/etc/nix"; { NIX_CONF_DIR = "/etc/nix";

View File

@ -91,7 +91,7 @@ in
config = mkIf config.networking.useDHCP { config = mkIf config.networking.useDHCP {
jobs.dhcpcd = boot.systemd.services.dhcpcd =
{ description = "DHCP Client"; { description = "DHCP Client";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
@ -99,14 +99,12 @@ in
path = [ dhcpcd pkgs.nettools pkgs.openresolv ]; path = [ dhcpcd pkgs.nettools pkgs.openresolv ];
daemonType = "fork";
exec = "dhcpcd --config ${dhcpcdConf}";
serviceConfig = serviceConfig =
'' { Type = "forking";
ExecReload=${dhcpcd}/sbin/dhcpcd --rebind PIDFile = "/run/dhcpcd.pid";
''; ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --config ${dhcpcdConf}";
ExecReload = "${dhcpcd}/sbin/dhcpcd --rebind";
};
}; };
environment.systemPackages = [ dhcpcd ]; environment.systemPackages = [ dhcpcd ];

View File

@ -321,11 +321,8 @@ in
script = mkAuthkeyScript; script = mkAuthkeyScript;
serviceConfig = serviceConfig.Type = "oneshot";
'' serviceConfig.RemainAfterExit = true;
Type=oneshot
RemainAfterExit=true
'';
}; };
boot.systemd.services.sshd = boot.systemd.services.sshd =
@ -349,15 +346,14 @@ in
''; '';
serviceConfig = serviceConfig =
'' { ExecStart =
ExecStart=\ "${pkgs.openssh}/sbin/sshd -D -h ${cfg.hostKeyPath} " +
${pkgs.openssh}/sbin/sshd -D -h ${cfg.hostKeyPath} \ "-f ${pkgs.writeText "sshd_config" cfg.extraConfig}";
-f ${pkgs.writeText "sshd_config" cfg.extraConfig} Restart = "always";
Restart=always Type = "simple";
Type=simple KillMode = "process";
KillMode=process PIDFile = "/run/sshd.pid";
PIDFile=/run/sshd.pid };
'';
}; };
networking.firewall.allowedTCPPorts = cfg.ports; networking.firewall.allowedTCPPorts = cfg.ports;

View File

@ -53,15 +53,16 @@ in
''; '';
serviceConfig = serviceConfig =
'' { ExecStart = "@${pkgs.glibc}/sbin/nscd nscd -f ${./nscd.conf}";
ExecStart=@${pkgs.glibc}/sbin/nscd nscd -f ${./nscd.conf} Type = "forking";
Type=forking PIDFile = "/run/nscd/nscd.pid";
PIDFile=/run/nscd/nscd.pid Restart = "always";
Restart=always ExecReload =
ExecReload=${pkgs.glibc}/sbin/nscd --invalidate passwd [ "${pkgs.glibc}/sbin/nscd --invalidate passwd"
ExecReload=${pkgs.glibc}/sbin/nscd --invalidate group "${pkgs.glibc}/sbin/nscd --invalidate group"
ExecReload=${pkgs.glibc}/sbin/nscd --invalidate hosts "${pkgs.glibc}/sbin/nscd --invalidate hosts"
''; ];
};
}; };
}; };

View File

@ -81,21 +81,28 @@ with pkgs.lib;
}; };
unitConfig = mkOption { unitConfig = mkOption {
default = ""; default = {};
type = types.string; example = { RequiresMountsFor = "/data"; };
type = types.attrs;
description = '' description = ''
Contents of the <literal>[Unit]</literal> section of the unit. Each attribute in this set specifies an option in the
See <citerefentry><refentrytitle>systemd.unit</refentrytitle> <literal>[Unit]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.unit</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details. <manvolnum>5</manvolnum></citerefentry> for details.
''; '';
}; };
serviceConfig = mkOption { serviceConfig = mkOption {
default = ""; default = {};
type = types.string; example =
{ StartLimitInterval = 10;
RestartSec = 5;
};
type = types.attrs;
description = '' description = ''
Contents of the <literal>[Service]</literal> section of the unit. Each attribute in this set specifies an option in the
See <citerefentry><refentrytitle>systemd.service</refentrytitle> <literal>[Service]</literal> section of the unit. See
<citerefentry><refentrytitle>systemd.service</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details. <manvolnum>5</manvolnum></citerefentry> for details.
''; '';
}; };

View File

@ -177,24 +177,38 @@ let
pkgs.gnused pkgs.gnused
systemd systemd
]; ];
unitConfig =
{ Requires = concatStringsSep " " config.requires;
Wants = concatStringsSep " " config.wants;
After = concatStringsSep " " config.after;
Before = concatStringsSep " " config.before;
PartOf = concatStringsSep " " config.partOf;
} // optionalAttrs (config.description != "")
{ Description = config.description;
};
}; };
}; };
toOption = x:
if x == true then "true"
else if x == false then "false"
else toString x;
attrsToSection = as:
concatStrings (concatLists (mapAttrsToList (name: value:
map (x: ''
${name}=${toOption x}
'')
(if isList value then value else [value]))
as));
serviceToUnit = name: def: serviceToUnit = name: def:
{ inherit (def) wantedBy; { inherit (def) wantedBy;
text = text =
'' ''
[Unit] [Unit]
${optionalString (def.description != "") '' ${attrsToSection def.unitConfig}
Description=${def.description}
''}
Requires=${concatStringsSep " " def.requires}
Wants=${concatStringsSep " " def.wants}
After=${concatStringsSep " " def.after}
Before=${concatStringsSep " " def.before}
PartOf=${concatStringsSep " " def.partOf}
${def.unitConfig}
[Service] [Service]
Environment=PATH=${def.path} Environment=PATH=${def.path}
@ -215,7 +229,7 @@ let
''} ''}
''} ''}
${def.serviceConfig} ${attrsToSection def.serviceConfig}
''; '';
}; };

View File

@ -54,7 +54,7 @@ let
''; '';
in { in {
inherit (job) description requires wants before partOf environment path restartIfChanged; inherit (job) description requires wants before partOf environment path restartIfChanged unitConfig;
after = after =
(if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else (if job.startOn == "stopped udevtrigger" then [ "systemd-udev-settle.service" ] else
@ -72,40 +72,23 @@ let
[ "multi-user.target" ]) ++ job.wantedBy; [ "multi-user.target" ]) ++ job.wantedBy;
serviceConfig = serviceConfig =
'' job.serviceConfig
${job.serviceConfig} // optionalAttrs (job.preStart != "" && (job.script != "" || job.exec != ""))
{ ExecStartPre = preStartScript; }
${optionalString (job.preStart != "" && (job.script != "" || job.exec != "")) '' // optionalAttrs (job.script != "" || job.exec != "")
ExecStartPre=${preStartScript} { ExecStart = startScript; }
''} // optionalAttrs (job.postStart != "")
{ ExecStartPost = postStartScript; }
${optionalString (job.preStart != "" && job.script == "" && job.exec == "") '' // optionalAttrs (job.preStop != "")
ExecStart=${preStartScript} { ExecStop = preStopScript; }
''} // optionalAttrs (job.postStop != "")
{ ExecStopPost = postStopScript; }
${optionalString (job.script != "" || job.exec != "") '' // (if job.script == "" && job.exec == "" then { Type = "oneshot"; RemainAfterExit = true; } else
ExecStart=${startScript} if job.daemonType == "fork" then { Type = "forking"; GuessMainPID = true; } else
''} if job.daemonType == "none" then { } else
throw "invalid daemon type `${job.daemonType}'")
${optionalString (job.postStart != "") '' // optionalAttrs (!job.task && job.respawn)
ExecStartPost=${postStartScript} { Restart = "always"; };
''}
${optionalString (job.preStop != "") ''
ExecStop=${preStopScript}
''}
${optionalString (job.postStop != "") ''
ExecStopPost=${postStopScript}
''}
${if job.script == "" && job.exec == "" then "Type=oneshot\nRemainAfterExit=true" else
if job.daemonType == "fork" then "Type=forking\nGuessMainPID=true" else
if job.daemonType == "none" then "" else
throw "invalid daemon type `${job.daemonType}'"}
${optionalString (!job.task && job.respawn) "Restart=always"}
'';
}; };