nixos: systemd: add systemd.user.tmpfiles

This commit is contained in:
schnusch 2022-12-23 21:22:49 +01:00
parent 2054bb5de5
commit 34ad8447c3
3 changed files with 111 additions and 0 deletions

View file

@ -39,6 +39,20 @@ let
"timers.target" "timers.target"
"xdg-desktop-autostart.target" "xdg-desktop-autostart.target"
] ++ config.systemd.additionalUpstreamUserUnits; ] ++ config.systemd.additionalUpstreamUserUnits;
writeTmpfiles = { rules, user ? null }:
let
suffix = if user == null then "" else "-${user}";
in
pkgs.writeTextFile {
name = "nixos-user-tmpfiles.d${suffix}";
destination = "/etc/xdg/user-tmpfiles.d/00-nixos${suffix}.conf";
text = ''
# This file is created automatically and should not be modified.
# Please change the options systemd.user.tmpfiles instead.
${concatStringsSep "\n" rules}
'';
};
in { in {
options = { options = {
systemd.user.extraConfig = mkOption { systemd.user.extraConfig = mkOption {
@ -93,6 +107,42 @@ in {
description = lib.mdDoc "Definition of systemd per-user timer units."; description = lib.mdDoc "Definition of systemd per-user timer units.";
}; };
systemd.user.tmpfiles = {
rules = mkOption {
type = types.listOf types.str;
default = [];
example = [ "D %C - - - 7d" ];
description = lib.mdDoc ''
Global user rules for creation, deletion and cleaning of volatile and
temporary files automatically. See
{manpage}`tmpfiles.d(5)`
for the exact format.
'';
};
users = mkOption {
description = mdDoc ''
Per-user rules for creation, deletion and cleaning of volatile and
temporary files automatically.
'';
type = types.attrsOf (types.submodule {
options = {
rules = mkOption {
type = types.listOf types.str;
default = [];
example = [ "D %C - - - 7d" ];
description = mdDoc ''
Per-user rules for creation, deletion and cleaning of volatile and
temporary files automatically. See
{manpage}`tmpfiles.d(5)`
for the exact format.
'';
};
};
});
};
};
systemd.additionalUpstreamUserUnits = mkOption { systemd.additionalUpstreamUserUnits = mkOption {
default = []; default = [];
type = types.listOf types.str; type = types.listOf types.str;
@ -154,5 +204,30 @@ in {
# Some overrides to upstream units. # Some overrides to upstream units.
systemd.services."user@".restartIfChanged = false; systemd.services."user@".restartIfChanged = false;
systemd.services.systemd-user-sessions.restartIfChanged = false; # Restart kills all active sessions. systemd.services.systemd-user-sessions.restartIfChanged = false; # Restart kills all active sessions.
# enable systemd user tmpfiles
systemd.user.services.systemd-tmpfiles-setup.wantedBy =
optional
(cfg.tmpfiles.rules != [] || any (cfg': cfg'.rules != []) (attrValues cfg.tmpfiles.users))
"basic.target";
# /run/current-system/sw/etc/xdg is in systemd's $XDG_CONFIG_DIRS so we can
# write the tmpfiles.d rules for everyone there
environment.systemPackages =
optional
(cfg.tmpfiles.rules != [])
(writeTmpfiles { inherit (cfg.tmpfiles) rules; });
# /etc/profiles/per-user/$USER/etc/xdg is in systemd's $XDG_CONFIG_DIRS so
# we can write a single user's tmpfiles.d rules there
users.users =
mapAttrs
(user: cfg': {
packages = optional (cfg'.rules != []) (writeTmpfiles {
inherit (cfg') rules;
inherit user;
});
})
cfg.tmpfiles.users;
}; };
} }

View file

@ -642,6 +642,7 @@ in {
systemd-portabled = handleTest ./systemd-portabled.nix {}; systemd-portabled = handleTest ./systemd-portabled.nix {};
systemd-shutdown = handleTest ./systemd-shutdown.nix {}; systemd-shutdown = handleTest ./systemd-shutdown.nix {};
systemd-timesyncd = handleTest ./systemd-timesyncd.nix {}; systemd-timesyncd = handleTest ./systemd-timesyncd.nix {};
systemd-user-tmpfiles-rules = handleTest ./systemd-user-tmpfiles-rules.nix {};
systemd-misc = handleTest ./systemd-misc.nix {}; systemd-misc = handleTest ./systemd-misc.nix {};
tandoor-recipes = handleTest ./tandoor-recipes.nix {}; tandoor-recipes = handleTest ./tandoor-recipes.nix {};
taskserver = handleTest ./taskserver.nix {}; taskserver = handleTest ./taskserver.nix {};

View file

@ -0,0 +1,35 @@
import ./make-test-python.nix ({ lib, ... }: {
name = "systemd-user-tmpfiles-rules";
meta = with lib.maintainers; {
maintainers = [ schnusch ];
};
nodes.machine = { ... }: {
users.users = {
alice.isNormalUser = true;
bob.isNormalUser = true;
};
systemd.user.tmpfiles = {
rules = [
"d %h/user_tmpfiles_created"
];
users.alice.rules = [
"d %h/only_alice"
];
};
};
testScript = { ... }: ''
machine.succeed("loginctl enable-linger alice bob")
machine.wait_until_succeeds("systemctl --user --machine=alice@ is-active systemd-tmpfiles-setup.service")
machine.succeed("[ -d ~alice/user_tmpfiles_created ]")
machine.succeed("[ -d ~alice/only_alice ]")
machine.wait_until_succeeds("systemctl --user --machine=bob@ is-active systemd-tmpfiles-setup.service")
machine.succeed("[ -d ~bob/user_tmpfiles_created ]")
machine.succeed("[ ! -e ~bob/only_alice ]")
'';
})