systemd: make the unit option type more robust
This should allow more sensible merging behavior. In particular, with this change it is possible to use, for example, `mkForce` for greater control of merging. Fixes #543
This commit is contained in:
parent
d49b514aa6
commit
12cb82af91
|
@ -1019,6 +1019,36 @@ in
|
||||||
A new module is available: 'services.xcape'.
|
A new module is available: 'services.xcape'.
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
time = "2019-04-11T22:50:10+00:00";
|
||||||
|
condition = hostPlatform.isLinux;
|
||||||
|
message = ''
|
||||||
|
The type used for the systemd unit options under
|
||||||
|
|
||||||
|
systemd.user.services, systemd.user.sockets, etc.
|
||||||
|
|
||||||
|
has been changed to offer more robust merging of configurations.
|
||||||
|
|
||||||
|
If you don't override values within systemd units then you are not
|
||||||
|
affected by this change. Unfortunately, if you do override unit values
|
||||||
|
you may encounter errors due to this change.
|
||||||
|
|
||||||
|
In particular, if you get an error saying that a "unique option" is
|
||||||
|
"defined multiple times" then you need to use 'lib.mkForce'. For
|
||||||
|
example,
|
||||||
|
|
||||||
|
systemd.user.services.foo.Service.ExecStart = "/foo/bar";
|
||||||
|
|
||||||
|
becomes
|
||||||
|
|
||||||
|
systemd.user.services.foo.Service.ExecStart = lib.mkForce "/foo/bar";
|
||||||
|
|
||||||
|
We had to make this change because the old merging was causing too
|
||||||
|
many confusing situations for people. Apologies for potentially
|
||||||
|
breaking your configuration!
|
||||||
|
'';
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,9 +58,14 @@ let
|
||||||
|
|
||||||
servicesStartTimeoutMs = builtins.toString cfg.servicesStartTimeoutMs;
|
servicesStartTimeoutMs = builtins.toString cfg.servicesStartTimeoutMs;
|
||||||
|
|
||||||
attrsRecursivelyMerged = types.attrs // {
|
unitType = unitKind: with types;
|
||||||
merge = loc: foldl' (res: def: recursiveUpdate res def.value) {};
|
let
|
||||||
};
|
primitive = either bool (either int str);
|
||||||
|
in
|
||||||
|
attrsOf (attrsOf (attrsOf (either primitive (listOf primitive))))
|
||||||
|
// {
|
||||||
|
description = "systemd ${unitKind} unit configuration";
|
||||||
|
};
|
||||||
|
|
||||||
unitDescription = type: ''
|
unitDescription = type: ''
|
||||||
Definition of systemd per-user ${type} units. Attributes are
|
Definition of systemd per-user ${type} units. Attributes are
|
||||||
|
@ -78,6 +83,7 @@ let
|
||||||
{
|
{
|
||||||
Unit = {
|
Unit = {
|
||||||
Description = "Example description";
|
Description = "Example description";
|
||||||
|
Documentation = [ "man:example(1)" "man:example(5)" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
${type} = {
|
${type} = {
|
||||||
|
@ -113,35 +119,35 @@ in
|
||||||
|
|
||||||
services = mkOption {
|
services = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
type = attrsRecursivelyMerged;
|
type = unitType "service";
|
||||||
description = unitDescription "service";
|
description = unitDescription "service";
|
||||||
example = unitExample "Service";
|
example = unitExample "Service";
|
||||||
};
|
};
|
||||||
|
|
||||||
sockets = mkOption {
|
sockets = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
type = attrsRecursivelyMerged;
|
type = unitType "socket";
|
||||||
description = unitDescription "socket";
|
description = unitDescription "socket";
|
||||||
example = unitExample "Socket";
|
example = unitExample "Socket";
|
||||||
};
|
};
|
||||||
|
|
||||||
targets = mkOption {
|
targets = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
type = attrsRecursivelyMerged;
|
type = unitType "target";
|
||||||
description = unitDescription "target";
|
description = unitDescription "target";
|
||||||
example = unitExample "Target";
|
example = unitExample "Target";
|
||||||
};
|
};
|
||||||
|
|
||||||
timers = mkOption {
|
timers = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
type = attrsRecursivelyMerged;
|
type = unitType "timer";
|
||||||
description = unitDescription "timer";
|
description = unitDescription "timer";
|
||||||
example = unitExample "Timer";
|
example = unitExample "Timer";
|
||||||
};
|
};
|
||||||
|
|
||||||
paths = mkOption {
|
paths = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
type = attrsRecursivelyMerged;
|
type = unitType "path";
|
||||||
description = unitDescription "path";
|
description = unitDescription "path";
|
||||||
example = unitExample "Path";
|
example = unitExample "Path";
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue