2012-08-06 17:45:59 +02:00
|
|
|
|
{ config, pkgs }:
|
|
|
|
|
|
|
|
|
|
with pkgs.lib;
|
|
|
|
|
|
2013-10-30 15:33:20 +01:00
|
|
|
|
let
|
|
|
|
|
|
|
|
|
|
checkService = v:
|
|
|
|
|
let assertValueOneOf = name: values: attr:
|
|
|
|
|
let val = getAttr name attr;
|
|
|
|
|
in optional ( hasAttr name attr && !elem val values) "Systemd service field `${name}' cannot have value `${val}'.";
|
|
|
|
|
checkType = assertValueOneOf "Type" ["simple" "forking" "oneshot" "dbus" "notify" "idle"];
|
|
|
|
|
checkRestart = assertValueOneOf "Restart" ["no" "on-success" "on-failure" "on-abort" "always"];
|
|
|
|
|
errors = concatMap (c: c v) [checkType checkRestart];
|
|
|
|
|
in if errors == [] then true
|
|
|
|
|
else builtins.trace (concatStringsSep "\n" errors) false;
|
|
|
|
|
|
2013-11-18 15:45:24 +01:00
|
|
|
|
unitOption = mkOptionType {
|
|
|
|
|
name = "systemd option";
|
|
|
|
|
merge = loc: defs:
|
2013-11-18 15:51:21 +01:00
|
|
|
|
let
|
|
|
|
|
defs' = filterOverrides defs;
|
|
|
|
|
defs'' = getValues defs';
|
2013-11-18 15:45:24 +01:00
|
|
|
|
in
|
2013-11-18 15:51:21 +01:00
|
|
|
|
if isList (head defs'')
|
|
|
|
|
then concatLists defs''
|
|
|
|
|
else mergeOneOption loc defs';
|
2013-11-18 15:45:24 +01:00
|
|
|
|
};
|
|
|
|
|
|
2013-10-30 15:33:20 +01:00
|
|
|
|
in rec {
|
2012-08-06 17:45:59 +02:00
|
|
|
|
|
2012-10-02 00:58:11 +02:00
|
|
|
|
unitOptions = {
|
2012-08-06 17:45:59 +02:00
|
|
|
|
|
2012-10-29 21:01:36 +01:00
|
|
|
|
enable = mkOption {
|
|
|
|
|
default = true;
|
2013-10-28 15:12:11 +01:00
|
|
|
|
type = types.bool;
|
2012-10-29 21:01:36 +01:00
|
|
|
|
description = ''
|
|
|
|
|
If set to false, this unit will be a symlink to
|
|
|
|
|
/dev/null. This is primarily useful to prevent specific
|
|
|
|
|
template instances (e.g. <literal>serial-getty@ttyS0</literal>)
|
|
|
|
|
from being started.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2014-03-12 18:20:57 +01:00
|
|
|
|
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.";
|
|
|
|
|
};
|
|
|
|
|
|
2012-08-06 17:45:59 +02:00
|
|
|
|
description = mkOption {
|
|
|
|
|
default = "";
|
2013-10-30 11:02:04 +01:00
|
|
|
|
type = types.str;
|
2012-08-06 17:45:59 +02:00
|
|
|
|
description = "Description of this unit used in systemd messages and progress indicators.";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
requires = mkOption {
|
|
|
|
|
default = [];
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.listOf types.str;
|
2012-08-06 17:45:59 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Start the specified units when this unit is started, and stop
|
|
|
|
|
this unit when the specified units are stopped or fail.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
wants = mkOption {
|
|
|
|
|
default = [];
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.listOf types.str;
|
2012-08-06 17:45:59 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Start the specified units when this unit is started.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
after = mkOption {
|
|
|
|
|
default = [];
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.listOf types.str;
|
2012-08-06 17:45:59 +02:00
|
|
|
|
description = ''
|
|
|
|
|
If the specified units are started at the same time as
|
|
|
|
|
this unit, delay this unit until they have started.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
before = mkOption {
|
|
|
|
|
default = [];
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.listOf types.str;
|
2012-08-06 17:45:59 +02:00
|
|
|
|
description = ''
|
|
|
|
|
If the specified units are started at the same time as
|
|
|
|
|
this unit, delay them until this unit has started.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2012-10-10 22:50:41 +02:00
|
|
|
|
bindsTo = mkOption {
|
|
|
|
|
default = [];
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.listOf types.str;
|
2012-10-10 22:50:41 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Like ‘requires’, but in addition, if the specified units
|
|
|
|
|
unexpectedly disappear, this unit will be stopped as well.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2012-08-15 21:36:54 +02:00
|
|
|
|
partOf = mkOption {
|
|
|
|
|
default = [];
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.listOf types.str;
|
2012-08-15 21:36:54 +02:00
|
|
|
|
description = ''
|
|
|
|
|
If the specified units are stopped or restarted, then this
|
|
|
|
|
unit is stopped or restarted as well.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2013-09-22 21:04:54 +02:00
|
|
|
|
conflicts = mkOption {
|
|
|
|
|
default = [];
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.listOf types.str;
|
2013-09-22 21:04:54 +02:00
|
|
|
|
description = ''
|
|
|
|
|
If the specified units are started, then this unit is stopped
|
|
|
|
|
and vice versa.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2013-04-19 22:28:00 +02:00
|
|
|
|
requiredBy = mkOption {
|
|
|
|
|
default = [];
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.listOf types.str;
|
2013-04-19 22:28:00 +02:00
|
|
|
|
description = "Units that require (i.e. depend on and need to go down with) this unit.";
|
|
|
|
|
};
|
|
|
|
|
|
2012-08-06 17:45:59 +02:00
|
|
|
|
wantedBy = mkOption {
|
|
|
|
|
default = [];
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.listOf types.str;
|
2012-08-06 17:45:59 +02:00
|
|
|
|
description = "Units that want (i.e. depend on) this unit.";
|
|
|
|
|
};
|
|
|
|
|
|
2012-10-02 00:58:11 +02:00
|
|
|
|
unitConfig = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example = { RequiresMountsFor = "/data"; };
|
2013-11-18 15:45:24 +01:00
|
|
|
|
type = types.attrsOf unitOption;
|
2012-10-02 00:58:11 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Each attribute in this set specifies an option in the
|
|
|
|
|
<literal>[Unit]</literal> section of the unit. See
|
|
|
|
|
<citerefentry><refentrytitle>systemd.unit</refentrytitle>
|
|
|
|
|
<manvolnum>5</manvolnum></citerefentry> for details.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2012-10-11 23:54:43 +02:00
|
|
|
|
restartTriggers = mkOption {
|
|
|
|
|
default = [];
|
2014-03-12 18:35:50 +01:00
|
|
|
|
type = types.listOf types.unspecified;
|
2012-10-11 23:54:43 +02:00
|
|
|
|
description = ''
|
|
|
|
|
An arbitrary list of items such as derivations. If any item
|
|
|
|
|
in the list changes between reconfigurations, the service will
|
|
|
|
|
be restarted.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2012-10-02 00:58:11 +02:00
|
|
|
|
};
|
|
|
|
|
|
2012-10-09 21:14:15 +02:00
|
|
|
|
|
2012-10-02 00:58:11 +02:00
|
|
|
|
serviceOptions = unitOptions // {
|
|
|
|
|
|
2012-08-06 17:45:59 +02:00
|
|
|
|
environment = mkOption {
|
|
|
|
|
default = {};
|
2013-11-18 15:45:24 +01:00
|
|
|
|
type = types.attrs; # FIXME
|
2012-08-06 17:45:59 +02:00
|
|
|
|
example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; };
|
2013-08-10 23:07:13 +02:00
|
|
|
|
description = "Environment variables passed to the service's processes.";
|
2012-08-06 17:45:59 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
path = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
apply = ps: "${makeSearchPath "bin" ps}:${makeSearchPath "sbin" ps}";
|
|
|
|
|
description = ''
|
|
|
|
|
Packages added to the service's <envar>PATH</envar>
|
|
|
|
|
environment variable. Both the <filename>bin</filename>
|
|
|
|
|
and <filename>sbin</filename> subdirectories of each
|
|
|
|
|
package are added.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
serviceConfig = mkOption {
|
2012-10-01 22:27:42 +02:00
|
|
|
|
default = {};
|
|
|
|
|
example =
|
|
|
|
|
{ StartLimitInterval = 10;
|
|
|
|
|
RestartSec = 5;
|
|
|
|
|
};
|
2013-11-18 15:45:24 +01:00
|
|
|
|
type = types.addCheck (types.attrsOf unitOption) checkService;
|
2012-08-06 17:45:59 +02:00
|
|
|
|
description = ''
|
2012-10-01 22:27:42 +02:00
|
|
|
|
Each attribute in this set specifies an option in the
|
|
|
|
|
<literal>[Service]</literal> section of the unit. See
|
|
|
|
|
<citerefentry><refentrytitle>systemd.service</refentrytitle>
|
2012-08-06 17:45:59 +02:00
|
|
|
|
<manvolnum>5</manvolnum></citerefentry> for details.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
script = mkOption {
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.lines;
|
2012-08-06 17:45:59 +02:00
|
|
|
|
default = "";
|
|
|
|
|
description = "Shell commands executed as the service's main process.";
|
|
|
|
|
};
|
|
|
|
|
|
2013-02-15 03:50:41 +01:00
|
|
|
|
scriptArgs = mkOption {
|
2013-10-30 11:02:04 +01:00
|
|
|
|
type = types.str;
|
2013-02-15 03:50:41 +01:00
|
|
|
|
default = "";
|
|
|
|
|
description = "Arguments passed to the main process script.";
|
|
|
|
|
};
|
|
|
|
|
|
2012-08-06 17:45:59 +02:00
|
|
|
|
preStart = mkOption {
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.lines;
|
2012-08-06 17:45:59 +02:00
|
|
|
|
default = "";
|
|
|
|
|
description = ''
|
|
|
|
|
Shell commands executed before the service's main process
|
|
|
|
|
is started.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2012-10-01 22:45:49 +02:00
|
|
|
|
postStart = mkOption {
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.lines;
|
2012-10-01 22:45:49 +02:00
|
|
|
|
default = "";
|
|
|
|
|
description = ''
|
|
|
|
|
Shell commands executed after the service's main process
|
|
|
|
|
is started.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2013-11-26 18:24:55 +01:00
|
|
|
|
preStop = mkOption {
|
|
|
|
|
type = types.lines;
|
|
|
|
|
default = "";
|
|
|
|
|
description = ''
|
|
|
|
|
Shell commands executed to stop the service.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2012-10-10 23:55:13 +02:00
|
|
|
|
postStop = mkOption {
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.lines;
|
2012-10-10 23:55:13 +02:00
|
|
|
|
default = "";
|
|
|
|
|
description = ''
|
|
|
|
|
Shell commands executed after the service's main process
|
|
|
|
|
has exited.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2012-08-17 19:14:42 +02:00
|
|
|
|
restartIfChanged = mkOption {
|
|
|
|
|
type = types.bool;
|
|
|
|
|
default = true;
|
|
|
|
|
description = ''
|
|
|
|
|
Whether the service should be restarted during a NixOS
|
|
|
|
|
configuration switch if its definition has changed.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2013-01-05 01:05:25 +01:00
|
|
|
|
stopIfChanged = mkOption {
|
|
|
|
|
type = types.bool;
|
|
|
|
|
default = true;
|
|
|
|
|
description = ''
|
|
|
|
|
If set, a changed unit is restarted by calling
|
|
|
|
|
<command>systemctl stop</command> in the old configuration,
|
|
|
|
|
then <command>systemctl start</command> in the new one.
|
|
|
|
|
Otherwise, it is restarted in a single step using
|
|
|
|
|
<command>systemctl restart</command> in the new configuration.
|
|
|
|
|
The latter is less correct because it runs the
|
|
|
|
|
<literal>ExecStop</literal> commands from the new
|
|
|
|
|
configuration.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2013-10-09 14:28:35 +02:00
|
|
|
|
startAt = mkOption {
|
2013-10-30 11:02:04 +01:00
|
|
|
|
type = types.str;
|
2013-10-09 14:28:35 +02:00
|
|
|
|
default = "";
|
|
|
|
|
example = "Sun 14:00:00";
|
|
|
|
|
description = ''
|
|
|
|
|
Automatically start this unit at the given date/time, which
|
|
|
|
|
must be in the format described in
|
|
|
|
|
<citerefentry><refentrytitle>systemd.time</refentrytitle>
|
|
|
|
|
<manvolnum>5</manvolnum></citerefentry>. This is equivalent
|
|
|
|
|
to adding a corresponding timer unit with
|
|
|
|
|
<option>OnCalendar</option> set to the value given here.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2012-08-06 17:45:59 +02:00
|
|
|
|
};
|
|
|
|
|
|
2012-10-09 21:14:15 +02:00
|
|
|
|
|
|
|
|
|
socketOptions = unitOptions // {
|
|
|
|
|
|
2013-05-14 16:07:55 +02:00
|
|
|
|
listenStreams = mkOption {
|
|
|
|
|
default = [];
|
2013-11-18 15:48:37 +01:00
|
|
|
|
type = types.listOf types.str;
|
2013-05-14 16:07:55 +02:00
|
|
|
|
example = [ "0.0.0.0:993" "/run/my-socket" ];
|
|
|
|
|
description = ''
|
|
|
|
|
For each item in this list, a <literal>ListenStream</literal>
|
|
|
|
|
option in the <literal>[Socket]</literal> section will be created.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2012-10-09 21:14:15 +02:00
|
|
|
|
socketConfig = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example = { ListenStream = "/run/my-socket"; };
|
2013-11-18 15:45:24 +01:00
|
|
|
|
type = types.attrsOf unitOption;
|
2012-10-09 21:14:15 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Each attribute in this set specifies an option in the
|
|
|
|
|
<literal>[Socket]</literal> section of the unit. See
|
|
|
|
|
<citerefentry><refentrytitle>systemd.socket</refentrytitle>
|
|
|
|
|
<manvolnum>5</manvolnum></citerefentry> for details.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
2013-03-02 01:03:13 +01:00
|
|
|
|
|
|
|
|
|
timerOptions = unitOptions // {
|
|
|
|
|
|
|
|
|
|
timerConfig = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example = { OnCalendar = "Sun 14:00:00"; Unit = "foo.service"; };
|
2013-11-18 15:45:24 +01:00
|
|
|
|
type = types.attrsOf unitOption;
|
2013-03-02 01:03:13 +01:00
|
|
|
|
description = ''
|
|
|
|
|
Each attribute in this set specifies an option in the
|
|
|
|
|
<literal>[Timer]</literal> section of the unit. See
|
|
|
|
|
<citerefentry><refentrytitle>systemd.timer</refentrytitle>
|
|
|
|
|
<manvolnum>5</manvolnum></citerefentry> and
|
|
|
|
|
<citerefentry><refentrytitle>systemd.time</refentrytitle>
|
|
|
|
|
<manvolnum>5</manvolnum></citerefentry> for details.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2012-12-28 13:29:53 +01:00
|
|
|
|
mountOptions = unitOptions // {
|
|
|
|
|
|
|
|
|
|
what = mkOption {
|
|
|
|
|
example = "/dev/sda1";
|
2013-10-30 11:02:04 +01:00
|
|
|
|
type = types.str;
|
2012-12-28 13:29:53 +01:00
|
|
|
|
description = "Absolute path of device node, file or other resource. (Mandatory)";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
where = mkOption {
|
|
|
|
|
example = "/mnt";
|
2013-10-30 11:02:04 +01:00
|
|
|
|
type = types.str;
|
2012-12-28 13:29:53 +01:00
|
|
|
|
description = ''
|
|
|
|
|
Absolute path of a directory of the mount point.
|
|
|
|
|
Will be created if it doesn't exist. (Mandatory)
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type = mkOption {
|
|
|
|
|
default = "";
|
|
|
|
|
example = "ext4";
|
2013-10-30 11:02:04 +01:00
|
|
|
|
type = types.str;
|
2012-12-28 13:29:53 +01:00
|
|
|
|
description = "File system type.";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
options = mkOption {
|
|
|
|
|
default = "";
|
|
|
|
|
example = "noatime";
|
2013-10-28 16:14:15 +01:00
|
|
|
|
type = types.commas;
|
2012-12-28 13:29:53 +01:00
|
|
|
|
description = "Options used to mount the file system.";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
mountConfig = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example = { DirectoryMode = "0775"; };
|
2013-11-18 15:45:24 +01:00
|
|
|
|
type = types.attrsOf unitOption;
|
2012-12-28 13:29:53 +01:00
|
|
|
|
description = ''
|
|
|
|
|
Each attribute in this set specifies an option in the
|
|
|
|
|
<literal>[Mount]</literal> section of the unit. See
|
|
|
|
|
<citerefentry><refentrytitle>systemd.mount</refentrytitle>
|
|
|
|
|
<manvolnum>5</manvolnum></citerefentry> for details.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2013-09-23 22:56:05 +02:00
|
|
|
|
automountOptions = unitOptions // {
|
|
|
|
|
|
|
|
|
|
where = mkOption {
|
|
|
|
|
example = "/mnt";
|
2013-10-30 11:02:04 +01:00
|
|
|
|
type = types.str;
|
2013-09-23 22:56:05 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Absolute path of a directory of the mount point.
|
|
|
|
|
Will be created if it doesn't exist. (Mandatory)
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
automountConfig = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example = { DirectoryMode = "0775"; };
|
2013-11-18 15:45:24 +01:00
|
|
|
|
type = types.attrsOf unitOption;
|
2013-09-23 22:56:05 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Each attribute in this set specifies an option in the
|
|
|
|
|
<literal>[Automount]</literal> section of the unit. See
|
|
|
|
|
<citerefentry><refentrytitle>systemd.automount</refentrytitle>
|
|
|
|
|
<manvolnum>5</manvolnum></citerefentry> for details.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2013-02-15 03:50:41 +01:00
|
|
|
|
}
|