2021-11-20 17:34:13 +00:00
|
|
|
|
{ lib, systemdUtils }:
|
2012-08-06 15:45:59 +00:00
|
|
|
|
|
2021-11-20 17:34:13 +00:00
|
|
|
|
with systemdUtils.lib;
|
2014-04-14 14:26:48 +00:00
|
|
|
|
with lib;
|
2012-08-06 15:45:59 +00:00
|
|
|
|
|
2013-10-30 14:33:20 +00:00
|
|
|
|
let
|
2014-11-20 09:41:05 +00:00
|
|
|
|
checkService = checkUnitConfig "Service" [
|
|
|
|
|
(assertValueOneOf "Type" [
|
2019-07-15 12:28:26 +00:00
|
|
|
|
"exec" "simple" "forking" "oneshot" "dbus" "notify" "idle"
|
2014-11-20 09:41:05 +00:00
|
|
|
|
])
|
|
|
|
|
(assertValueOneOf "Restart" [
|
2015-01-19 10:41:18 +00:00
|
|
|
|
"no" "on-success" "on-failure" "on-abnormal" "on-abort" "always"
|
2014-11-20 09:41:05 +00:00
|
|
|
|
])
|
|
|
|
|
];
|
|
|
|
|
|
2015-04-19 19:05:12 +00:00
|
|
|
|
in rec {
|
2013-10-30 14:33:20 +00:00
|
|
|
|
|
2013-11-18 14:45:24 +00:00
|
|
|
|
unitOption = mkOptionType {
|
|
|
|
|
name = "systemd option";
|
2016-03-01 19:47:08 +00:00
|
|
|
|
merge = loc: defs:
|
2013-11-18 14:51:21 +00:00
|
|
|
|
let
|
|
|
|
|
defs' = filterOverrides defs;
|
2013-11-18 14:45:24 +00:00
|
|
|
|
in
|
2022-02-08 11:50:06 +00:00
|
|
|
|
if isList (head defs').value
|
|
|
|
|
then concatMap (def:
|
|
|
|
|
if builtins.typeOf def.value == "list"
|
|
|
|
|
then def.value
|
|
|
|
|
else
|
|
|
|
|
throw "The definitions for systemd unit options should be either all lists, representing repeatable options, or all non-lists, but for the option ${showOption loc}, the definitions are a mix of list and non-list ${lib.options.showDefs defs'}"
|
|
|
|
|
) defs'
|
|
|
|
|
|
2019-11-08 15:45:44 +00:00
|
|
|
|
else mergeEqualOption loc defs';
|
2013-11-18 14:45:24 +00:00
|
|
|
|
};
|
|
|
|
|
|
2014-04-17 21:35:05 +00:00
|
|
|
|
sharedOptions = {
|
2012-08-06 15:45:59 +00:00
|
|
|
|
|
2012-10-29 20:01:36 +00:00
|
|
|
|
enable = mkOption {
|
|
|
|
|
default = true;
|
2013-10-28 14:12:11 +00:00
|
|
|
|
type = types.bool;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2012-10-29 20:01:36 +00:00
|
|
|
|
If set to false, this unit will be a symlink to
|
|
|
|
|
/dev/null. This is primarily useful to prevent specific
|
2017-09-16 10:48:16 +00:00
|
|
|
|
template instances
|
2022-08-28 19:18:44 +00:00
|
|
|
|
(e.g. `serial-getty@ttyS0`) from being
|
|
|
|
|
started. Note that `enable=true` does not
|
2017-09-16 10:48:16 +00:00
|
|
|
|
make a unit start by default at boot; if you want that, see
|
2022-08-28 19:18:44 +00:00
|
|
|
|
`wantedBy`.
|
2012-10-29 20:01:36 +00:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2014-04-17 21:35:05 +00:00
|
|
|
|
requiredBy = mkOption {
|
|
|
|
|
default = [];
|
2021-12-27 12:00:00 +00:00
|
|
|
|
type = types.listOf unitNameType;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2017-09-16 10:48:16 +00:00
|
|
|
|
Units that require (i.e. depend on and need to go down with)
|
2022-08-28 19:18:44 +00:00
|
|
|
|
this unit. The discussion under `wantedBy`
|
|
|
|
|
applies here as well: inverse `.requires`
|
2017-09-16 10:48:16 +00:00
|
|
|
|
symlinks are established.
|
|
|
|
|
'';
|
2014-04-17 21:35:05 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
wantedBy = mkOption {
|
|
|
|
|
default = [];
|
2021-12-27 12:00:00 +00:00
|
|
|
|
type = types.listOf unitNameType;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2017-09-16 10:48:16 +00:00
|
|
|
|
Units that want (i.e. depend on) this unit. The standard way
|
|
|
|
|
to make a unit start by default at boot is to set this option
|
2022-08-28 19:18:44 +00:00
|
|
|
|
to `[ "multi-user.target" ]`. That's despite
|
2017-09-16 10:48:16 +00:00
|
|
|
|
the fact that the systemd.unit(5) manpage says this option
|
2022-08-28 19:18:44 +00:00
|
|
|
|
goes in the `[Install]` section that controls
|
|
|
|
|
the behaviour of `systemctl enable`. Since
|
2017-09-16 10:48:16 +00:00
|
|
|
|
such a process is stateful and thus contrary to the design of
|
|
|
|
|
NixOS, setting this option instead causes the equivalent
|
2022-08-28 19:18:44 +00:00
|
|
|
|
inverse `.wants` symlink to be present,
|
2017-09-16 10:48:16 +00:00
|
|
|
|
establishing the same desired relationship in a stateless way.
|
|
|
|
|
'';
|
2014-04-17 21:35:05 +00:00
|
|
|
|
};
|
|
|
|
|
|
2017-02-01 21:51:16 +00:00
|
|
|
|
aliases = mkOption {
|
|
|
|
|
default = [];
|
2021-12-27 12:00:00 +00:00
|
|
|
|
type = types.listOf unitNameType;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc "Aliases of that unit.";
|
2017-02-01 21:51:16 +00:00
|
|
|
|
};
|
|
|
|
|
|
2014-04-17 21:35:05 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
concreteUnitOptions = sharedOptions // {
|
|
|
|
|
|
|
|
|
|
text = mkOption {
|
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
default = null;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc "Text of this systemd unit.";
|
2014-04-17 21:35:05 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
unit = mkOption {
|
|
|
|
|
internal = true;
|
|
|
|
|
description = "The generated unit.";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
commonUnitOptions = {
|
|
|
|
|
options = sharedOptions // {
|
2014-04-17 21:35:05 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
description = mkOption {
|
|
|
|
|
default = "";
|
|
|
|
|
type = types.singleLineStr;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc "Description of this unit used in systemd messages and progress indicators.";
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
2012-08-06 15:45:59 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
documentation = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf types.str;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc "A list of URIs referencing documentation for this unit or its configuration.";
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
2016-04-27 02:56:40 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
requires = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf unitNameType;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Start the specified units when this unit is started, and stop
|
|
|
|
|
this unit when the specified units are stopped or fail.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2012-08-06 15:45:59 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
wants = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf unitNameType;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Start the specified units when this unit is started.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2012-08-06 15:45:59 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
after = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf unitNameType;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
If the specified units are started at the same time as
|
|
|
|
|
this unit, delay this unit until they have started.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2012-08-06 15:45:59 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
before = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf unitNameType;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
If the specified units are started at the same time as
|
|
|
|
|
this unit, delay them until this unit has started.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2012-08-06 15:45:59 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
bindsTo = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf unitNameType;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Like ‘requires’, but in addition, if the specified units
|
|
|
|
|
unexpectedly disappear, this unit will be stopped as well.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2012-10-10 20:50:41 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
partOf = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf unitNameType;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
If the specified units are stopped or restarted, then this
|
|
|
|
|
unit is stopped or restarted as well.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2012-08-15 19:36:54 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
conflicts = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf unitNameType;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
If the specified units are started, then this unit is stopped
|
|
|
|
|
and vice versa.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2013-09-22 19:04:54 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
requisite = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf unitNameType;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Similar to requires. However if the units listed are not started,
|
|
|
|
|
they will not be started and the transaction will fail.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2014-11-19 21:11:30 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
unitConfig = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example = { RequiresMountsFor = "/data"; };
|
|
|
|
|
type = types.attrsOf unitOption;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Each attribute in this set specifies an option in the
|
2022-08-28 19:18:44 +00:00
|
|
|
|
`[Unit]` section of the unit. See
|
|
|
|
|
{manpage}`systemd.unit(5)` for details.
|
2022-04-04 10:48:13 +00:00
|
|
|
|
'';
|
|
|
|
|
};
|
2012-10-01 22:58:11 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
onFailure = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf unitNameType;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
A list of one or more units that are activated when
|
|
|
|
|
this unit enters the "failed" state.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2015-11-16 14:07:10 +00:00
|
|
|
|
|
2022-04-07 11:21:58 +00:00
|
|
|
|
onSuccess = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf unitNameType;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-07 11:21:58 +00:00
|
|
|
|
A list of one or more units that are activated when
|
|
|
|
|
this unit enters the "inactive" state.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
startLimitBurst = mkOption {
|
|
|
|
|
type = types.int;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Configure unit start rate limiting. Units which are started
|
|
|
|
|
more than startLimitBurst times within an interval time
|
|
|
|
|
interval are not permitted to start any more.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2020-09-09 07:31:27 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
startLimitIntervalSec = mkOption {
|
|
|
|
|
type = types.int;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Configure unit start rate limiting. Units which are started
|
|
|
|
|
more than startLimitBurst times within an interval time
|
|
|
|
|
interval are not permitted to start any more.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2018-11-20 17:34:43 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
|
|
|
|
stage2CommonUnitOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
commonUnitOptions
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
options = {
|
|
|
|
|
restartTriggers = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf types.unspecified;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-01 08:44:08 +00:00
|
|
|
|
An arbitrary list of items such as derivations. If any item
|
|
|
|
|
in the list changes between reconfigurations, the service will
|
|
|
|
|
be restarted.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
reloadTriggers = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf unitOption;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-01 08:44:08 +00:00
|
|
|
|
An arbitrary list of items such as derivations. If any item
|
|
|
|
|
in the list changes between reconfigurations, the service will
|
|
|
|
|
be reloaded. If anything but a reload trigger changes in the
|
|
|
|
|
unit file, the unit will be restarted instead.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
};
|
2012-10-01 22:58:11 +00:00
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
stage1CommonUnitOptions = commonUnitOptions;
|
2012-10-01 22:58:11 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
serviceOptions = { name, config, ... }: {
|
|
|
|
|
options = {
|
2012-10-01 22:58:11 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
environment = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
type = with types; attrsOf (nullOr (oneOf [ str path package ]));
|
|
|
|
|
example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; };
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc "Environment variables passed to the service's processes.";
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
2012-08-06 15:45:59 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
path = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = with types; listOf (oneOf [ package str ]);
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
|
|
|
|
Packages added to the service's {env}`PATH`
|
|
|
|
|
environment variable. Both the {file}`bin`
|
|
|
|
|
and {file}`sbin` subdirectories of each
|
2022-04-04 10:48:13 +00:00
|
|
|
|
package are added.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2012-08-06 15:45:59 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
serviceConfig = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example =
|
|
|
|
|
{ RestartSec = 5;
|
|
|
|
|
};
|
|
|
|
|
type = types.addCheck (types.attrsOf unitOption) checkService;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Each attribute in this set specifies an option in the
|
2022-08-28 19:18:44 +00:00
|
|
|
|
`[Service]` section of the unit. See
|
|
|
|
|
{manpage}`systemd.service(5)` for details.
|
2022-04-04 10:48:13 +00:00
|
|
|
|
'';
|
|
|
|
|
};
|
2012-08-06 15:45:59 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
script = mkOption {
|
|
|
|
|
type = types.lines;
|
|
|
|
|
default = "";
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc "Shell commands executed as the service's main process.";
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
scriptArgs = mkOption {
|
|
|
|
|
type = types.str;
|
|
|
|
|
default = "";
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc "Arguments passed to the main process script.";
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
preStart = mkOption {
|
|
|
|
|
type = types.lines;
|
|
|
|
|
default = "";
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Shell commands executed before the service's main process
|
|
|
|
|
is started.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
postStart = mkOption {
|
|
|
|
|
type = types.lines;
|
|
|
|
|
default = "";
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Shell commands executed after the service's main process
|
|
|
|
|
is started.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
reload = mkOption {
|
|
|
|
|
type = types.lines;
|
|
|
|
|
default = "";
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Shell commands executed when the service's main process
|
|
|
|
|
is reloaded.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
preStop = mkOption {
|
|
|
|
|
type = types.lines;
|
|
|
|
|
default = "";
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Shell commands executed to stop the service.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
postStop = mkOption {
|
|
|
|
|
type = types.lines;
|
|
|
|
|
default = "";
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Shell commands executed after the service's main process
|
|
|
|
|
has exited.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
jobScripts = mkOption {
|
|
|
|
|
type = with types; coercedTo path singleton (listOf path);
|
|
|
|
|
internal = true;
|
|
|
|
|
description = "A list of all job script derivations of this unit.";
|
|
|
|
|
default = [];
|
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
2022-04-04 09:04:45 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
config = mkMerge [
|
|
|
|
|
(mkIf (config.preStart != "") rec {
|
|
|
|
|
jobScripts = makeJobScript "${name}-pre-start" config.preStart;
|
|
|
|
|
serviceConfig.ExecStartPre = [ jobScripts ];
|
|
|
|
|
})
|
|
|
|
|
(mkIf (config.script != "") rec {
|
|
|
|
|
jobScripts = makeJobScript "${name}-start" config.script;
|
|
|
|
|
serviceConfig.ExecStart = jobScripts + " " + config.scriptArgs;
|
|
|
|
|
})
|
|
|
|
|
(mkIf (config.postStart != "") rec {
|
|
|
|
|
jobScripts = (makeJobScript "${name}-post-start" config.postStart);
|
|
|
|
|
serviceConfig.ExecStartPost = [ jobScripts ];
|
|
|
|
|
})
|
|
|
|
|
(mkIf (config.reload != "") rec {
|
|
|
|
|
jobScripts = makeJobScript "${name}-reload" config.reload;
|
|
|
|
|
serviceConfig.ExecReload = jobScripts;
|
|
|
|
|
})
|
|
|
|
|
(mkIf (config.preStop != "") rec {
|
|
|
|
|
jobScripts = makeJobScript "${name}-pre-stop" config.preStop;
|
|
|
|
|
serviceConfig.ExecStop = jobScripts;
|
|
|
|
|
})
|
|
|
|
|
(mkIf (config.postStop != "") rec {
|
|
|
|
|
jobScripts = makeJobScript "${name}-post-stop" config.postStop;
|
|
|
|
|
serviceConfig.ExecStopPost = jobScripts;
|
|
|
|
|
})
|
|
|
|
|
];
|
2022-04-04 09:04:45 +00:00
|
|
|
|
|
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
2022-04-04 09:04:45 +00:00
|
|
|
|
stage2ServiceOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage2CommonUnitOptions
|
|
|
|
|
serviceOptions
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
options = {
|
2022-04-01 08:44:08 +00:00
|
|
|
|
restartIfChanged = mkOption {
|
|
|
|
|
type = types.bool;
|
|
|
|
|
default = true;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-01 08:44:08 +00:00
|
|
|
|
Whether the service should be restarted during a NixOS
|
|
|
|
|
configuration switch if its definition has changed.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
reloadIfChanged = mkOption {
|
|
|
|
|
type = types.bool;
|
|
|
|
|
default = false;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-01 08:44:08 +00:00
|
|
|
|
Whether the service should be reloaded during a NixOS
|
|
|
|
|
configuration switch if its definition has changed. If
|
2022-08-28 19:18:44 +00:00
|
|
|
|
enabled, the value of {option}`restartIfChanged` is
|
2022-04-01 08:44:08 +00:00
|
|
|
|
ignored.
|
|
|
|
|
|
|
|
|
|
This option should not be used anymore in favor of
|
2022-08-28 19:18:44 +00:00
|
|
|
|
{option}`reloadTriggers` which allows more granular
|
2022-04-01 08:44:08 +00:00
|
|
|
|
control of when a service is reloaded and when a service
|
|
|
|
|
is restarted.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
stopIfChanged = mkOption {
|
|
|
|
|
type = types.bool;
|
|
|
|
|
default = true;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-01 08:44:08 +00:00
|
|
|
|
If set, a changed unit is restarted by calling
|
2022-08-28 19:18:44 +00:00
|
|
|
|
{command}`systemctl stop` in the old configuration,
|
|
|
|
|
then {command}`systemctl start` in the new one.
|
2022-04-01 08:44:08 +00:00
|
|
|
|
Otherwise, it is restarted in a single step using
|
2022-08-28 19:18:44 +00:00
|
|
|
|
{command}`systemctl restart` in the new configuration.
|
2022-04-01 08:44:08 +00:00
|
|
|
|
The latter is less correct because it runs the
|
2022-08-28 19:18:44 +00:00
|
|
|
|
`ExecStop` commands from the new
|
2022-04-01 08:44:08 +00:00
|
|
|
|
configuration.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
startAt = mkOption {
|
|
|
|
|
type = with types; either str (listOf str);
|
|
|
|
|
default = [];
|
|
|
|
|
example = "Sun 14:00:00";
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-01 08:44:08 +00:00
|
|
|
|
Automatically start this unit at the given date/time, which
|
|
|
|
|
must be in the format described in
|
2022-08-28 19:18:44 +00:00
|
|
|
|
{manpage}`systemd.time(7)`. This is equivalent
|
2022-04-01 08:44:08 +00:00
|
|
|
|
to adding a corresponding timer unit with
|
2022-08-28 19:18:44 +00:00
|
|
|
|
{option}`OnCalendar` set to the value given here.
|
2022-04-01 08:44:08 +00:00
|
|
|
|
'';
|
|
|
|
|
apply = v: if isList v then v else [ v ];
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
2013-10-09 12:28:35 +00:00
|
|
|
|
|
2022-04-01 08:44:08 +00:00
|
|
|
|
stage1ServiceOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage1CommonUnitOptions
|
|
|
|
|
serviceOptions
|
|
|
|
|
];
|
2012-08-06 15:45:59 +00:00
|
|
|
|
};
|
|
|
|
|
|
2012-10-09 19:14:15 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
socketOptions = {
|
|
|
|
|
options = {
|
2012-10-09 19:14:15 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
listenStreams = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf types.str;
|
|
|
|
|
example = [ "0.0.0.0:993" "/run/my-socket" ];
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
|
|
|
|
For each item in this list, a `ListenStream`
|
|
|
|
|
option in the `[Socket]` section will be created.
|
2022-04-04 10:48:13 +00:00
|
|
|
|
'';
|
|
|
|
|
};
|
2013-05-14 14:07:55 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
listenDatagrams = mkOption {
|
|
|
|
|
default = [];
|
|
|
|
|
type = types.listOf types.str;
|
|
|
|
|
example = [ "0.0.0.0:993" "/run/my-socket" ];
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
|
|
|
|
For each item in this list, a `ListenDatagram`
|
|
|
|
|
option in the `[Socket]` section will be created.
|
2022-04-04 10:48:13 +00:00
|
|
|
|
'';
|
|
|
|
|
};
|
2020-08-11 21:46:39 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
socketConfig = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example = { ListenStream = "/run/my-socket"; };
|
|
|
|
|
type = types.attrsOf unitOption;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Each attribute in this set specifies an option in the
|
2022-08-28 19:18:44 +00:00
|
|
|
|
`[Socket]` section of the unit. See
|
|
|
|
|
{manpage}`systemd.socket(5)` for details.
|
2022-04-04 10:48:13 +00:00
|
|
|
|
'';
|
|
|
|
|
};
|
2012-10-09 19:14:15 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
|
|
|
|
stage2SocketOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage2CommonUnitOptions
|
|
|
|
|
socketOptions
|
|
|
|
|
];
|
2012-10-09 19:14:15 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-04-01 08:44:08 +00:00
|
|
|
|
stage1SocketOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage1CommonUnitOptions
|
|
|
|
|
socketOptions
|
|
|
|
|
];
|
|
|
|
|
};
|
2013-03-02 00:03:13 +00:00
|
|
|
|
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
timerOptions = {
|
|
|
|
|
options = {
|
|
|
|
|
|
|
|
|
|
timerConfig = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example = { OnCalendar = "Sun 14:00:00"; Unit = "foo.service"; };
|
|
|
|
|
type = types.attrsOf unitOption;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Each attribute in this set specifies an option in the
|
2022-08-28 19:18:44 +00:00
|
|
|
|
`[Timer]` section of the unit. See
|
|
|
|
|
{manpage}`systemd.timer(5)` and
|
|
|
|
|
{manpage}`systemd.time(7)` for details.
|
2022-04-04 10:48:13 +00:00
|
|
|
|
'';
|
|
|
|
|
};
|
2013-03-02 00:03:13 +00:00
|
|
|
|
|
|
|
|
|
};
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
|
|
|
|
stage2TimerOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage2CommonUnitOptions
|
|
|
|
|
timerOptions
|
|
|
|
|
];
|
2013-03-02 00:03:13 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-04-01 08:44:08 +00:00
|
|
|
|
stage1TimerOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage1CommonUnitOptions
|
|
|
|
|
timerOptions
|
|
|
|
|
];
|
|
|
|
|
};
|
2013-03-02 00:03:13 +00:00
|
|
|
|
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
pathOptions = {
|
|
|
|
|
options = {
|
2014-03-31 10:23:27 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
pathConfig = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example = { PathChanged = "/some/path"; Unit = "changedpath.service"; };
|
|
|
|
|
type = types.attrsOf unitOption;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Each attribute in this set specifies an option in the
|
2022-08-28 19:18:44 +00:00
|
|
|
|
`[Path]` section of the unit. See
|
|
|
|
|
{manpage}`systemd.path(5)` for details.
|
2022-04-04 10:48:13 +00:00
|
|
|
|
'';
|
|
|
|
|
};
|
2014-03-31 10:23:27 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
|
|
|
|
stage2PathOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage2CommonUnitOptions
|
|
|
|
|
pathOptions
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
stage1PathOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage1CommonUnitOptions
|
|
|
|
|
pathOptions
|
|
|
|
|
];
|
2014-03-31 10:23:27 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
mountOptions = {
|
|
|
|
|
options = {
|
2012-12-28 12:29:53 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
what = mkOption {
|
|
|
|
|
example = "/dev/sda1";
|
|
|
|
|
type = types.str;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc "Absolute path of device node, file or other resource. (Mandatory)";
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
2012-12-28 12:29:53 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
where = mkOption {
|
|
|
|
|
example = "/mnt";
|
|
|
|
|
type = types.str;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Absolute path of a directory of the mount point.
|
|
|
|
|
Will be created if it doesn't exist. (Mandatory)
|
|
|
|
|
'';
|
|
|
|
|
};
|
2012-12-28 12:29:53 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
type = mkOption {
|
|
|
|
|
default = "";
|
|
|
|
|
example = "ext4";
|
|
|
|
|
type = types.str;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc "File system type.";
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
2012-12-28 12:29:53 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
options = mkOption {
|
|
|
|
|
default = "";
|
|
|
|
|
example = "noatime";
|
|
|
|
|
type = types.commas;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc "Options used to mount the file system.";
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
mountConfig = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example = { DirectoryMode = "0775"; };
|
|
|
|
|
type = types.attrsOf unitOption;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Each attribute in this set specifies an option in the
|
2022-08-28 19:18:44 +00:00
|
|
|
|
`[Mount]` section of the unit. See
|
|
|
|
|
{manpage}`systemd.mount(5)` for details.
|
2022-04-04 10:48:13 +00:00
|
|
|
|
'';
|
|
|
|
|
};
|
2012-12-28 12:29:53 +00:00
|
|
|
|
|
|
|
|
|
};
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
|
|
|
|
stage2MountOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage2CommonUnitOptions
|
|
|
|
|
mountOptions
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
stage1MountOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage1CommonUnitOptions
|
|
|
|
|
mountOptions
|
|
|
|
|
];
|
2012-12-28 12:29:53 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
automountOptions = {
|
|
|
|
|
options = {
|
2013-09-23 20:56:05 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
where = mkOption {
|
|
|
|
|
example = "/mnt";
|
|
|
|
|
type = types.str;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Absolute path of a directory of the mount point.
|
|
|
|
|
Will be created if it doesn't exist. (Mandatory)
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
automountConfig = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example = { DirectoryMode = "0775"; };
|
|
|
|
|
type = types.attrsOf unitOption;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Each attribute in this set specifies an option in the
|
2022-08-28 19:18:44 +00:00
|
|
|
|
`[Automount]` section of the unit. See
|
|
|
|
|
{manpage}`systemd.automount(5)` for details.
|
2022-04-04 10:48:13 +00:00
|
|
|
|
'';
|
|
|
|
|
};
|
2013-09-23 20:56:05 +00:00
|
|
|
|
|
|
|
|
|
};
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
|
|
|
|
stage2AutomountOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage2CommonUnitOptions
|
|
|
|
|
automountOptions
|
|
|
|
|
];
|
2013-09-23 20:56:05 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-04-01 08:44:08 +00:00
|
|
|
|
stage1AutomountOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage1CommonUnitOptions
|
|
|
|
|
automountOptions
|
|
|
|
|
];
|
|
|
|
|
};
|
2014-04-17 21:35:05 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
sliceOptions = {
|
|
|
|
|
options = {
|
2016-12-20 06:21:52 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
sliceConfig = mkOption {
|
|
|
|
|
default = {};
|
|
|
|
|
example = { MemoryMax = "2G"; };
|
|
|
|
|
type = types.attrsOf unitOption;
|
2022-08-28 19:18:44 +00:00
|
|
|
|
description = lib.mdDoc ''
|
2022-04-04 10:48:13 +00:00
|
|
|
|
Each attribute in this set specifies an option in the
|
2022-08-28 19:18:44 +00:00
|
|
|
|
`[Slice]` section of the unit. See
|
|
|
|
|
{manpage}`systemd.slice(5)` for details.
|
2022-04-04 10:48:13 +00:00
|
|
|
|
'';
|
|
|
|
|
};
|
2016-12-20 06:21:52 +00:00
|
|
|
|
|
2022-04-04 10:48:13 +00:00
|
|
|
|
};
|
|
|
|
|
};
|
2022-04-01 08:44:08 +00:00
|
|
|
|
|
|
|
|
|
stage2SliceOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage2CommonUnitOptions
|
|
|
|
|
sliceOptions
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
stage1SliceOptions = {
|
|
|
|
|
imports = [
|
|
|
|
|
stage1CommonUnitOptions
|
|
|
|
|
sliceOptions
|
|
|
|
|
];
|
2016-12-20 06:21:52 +00:00
|
|
|
|
};
|
|
|
|
|
|
2013-02-15 02:50:41 +00:00
|
|
|
|
}
|