systemd: add settings option (#4276)

The `systemd.user.extraConfig` provides a way to generate a
`systemd-user.conf(5)` file for the user.

This is the home-manager equivalent of NixOS’s option of the same
name, with the difference that NixOS’s option generates a `user.conf`
file that is shared between all users.
This commit is contained in:
Olli Helenius 2023-11-07 16:55:17 +02:00 committed by GitHub
parent 76e7c05f7d
commit 6a8444467c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 97 additions and 0 deletions

View File

@ -6,10 +6,16 @@ let
inherit (lib) getAttr hm isBool literalExpression mkIf mkMerge mkOption types;
settingsFormat = pkgs.formats.ini { listsAsDuplicateKeys = true; };
# From <nixpkgs/nixos/modules/system/boot/systemd-lib.nix>
mkPathSafeName =
lib.replaceStrings [ "@" ":" "\\" "[" "]" ] [ "-" "-" "-" "" "" ];
removeIfEmpty = attrs: names:
lib.filterAttrs (name: value: !(builtins.elem name names) || value != "")
attrs;
toSystemdIni = lib.generators.toINI {
listsAsDuplicateKeys = true;
mkKeyValue = key: value:
@ -87,6 +93,11 @@ let
+ "\n";
};
settings = mkIf (cfg.settings != { }) {
"systemd/user.conf".source =
settingsFormat.generate "user.conf" cfg.settings;
};
in {
meta.maintainers = [ lib.maintainers.rycee ];
@ -209,6 +220,64 @@ in {
{manpage}`environment.d(5)`.
'';
};
settings = mkOption {
apply = sections:
sections // {
# Setting one of these to an empty value would reset any
# previous settings, so well remove them instead if they
# are not explicitly set.
Manager = removeIfEmpty sections.Manager [
"ManagerEnvironment"
"DefaultEnvironment"
];
};
type = types.submodule {
freeformType = settingsFormat.type;
options = let
inherit (lib) concatStringsSep escapeShellArg mapAttrsToList;
environmentOption = args:
mkOption {
type = with types;
attrsOf (nullOr (oneOf [ str path package ]));
default = { };
example = literalExpression ''
{
PATH = "%u/bin:%u/.cargo/bin";
}
'';
apply = value:
concatStringsSep " "
(mapAttrsToList (n: v: "${n}=${escapeShellArg v}") value);
} // args;
in {
Manager = {
DefaultEnvironment = environmentOption {
description = ''
Configures environment variables passed to all executed processes.
'';
};
ManagerEnvironment = environmentOption {
description = ''
Sets environment variables just for the manager process itself.
'';
};
};
};
};
default = { };
example = literalExpression ''
{
Manager.DefaultCPUAccounting = true;
}
'';
description = ''
Extra config options for user session service manager. See {manpage}`systemd-user.conf(5)` for
available options.
'';
};
};
};
@ -227,6 +296,8 @@ in {
++ (buildServices "automount" cfg.automounts)))
sessionVariables
settings
];
# Run systemd service reload if user is logged in. If we're

View File

@ -2,6 +2,7 @@
systemd-services = ./services.nix;
systemd-services-disabled-for-root = ./services-disabled-for-root.nix;
systemd-session-variables = ./session-variables.nix;
systemd-user-config = ./user-config.nix;
systemd-slices = ./slices.nix;
systemd-timers = ./timers.nix;
}

View File

@ -0,0 +1,25 @@
{ pkgs, ... }:
{
systemd.user.settings.Manager = {
LogLevel = "debug";
DefaultCPUAccounting = true;
DefaultEnvironment = {
TEST = "abc";
PATH = "/bin:/sbin:/some where";
};
};
nmt.script = ''
userConf=home-files/.config/systemd/user.conf
assertFileExists $userConf
assertFileContent $userConf ${
pkgs.writeText "expected" ''
[Manager]
DefaultCPUAccounting=true
DefaultEnvironment=PATH='/bin:/sbin:/some where' TEST='abc'
LogLevel=debug
''
}
'';
}