Merge pull request #207468 from schnusch/systemd-user-tmpfiles-rules

nixos: systemd: add systemd.user.tmpfiles.rules, systemd.user.tmpfiles.users.<name>.rules

Changed files
+111
nixos
modules
system
boot
systemd
tests
+75
nixos/modules/system/boot/systemd/user.nix
···
"timers.target"
"xdg-desktop-autostart.target"
] ++ 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 {
options = {
systemd.user.extraConfig = mkOption {
···
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 {
default = [];
type = types.listOf types.str;
···
# Some overrides to upstream units.
systemd.services."user@".restartIfChanged = false;
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;
};
}
+1
nixos/tests/all-tests.nix
···
systemd-portabled = handleTest ./systemd-portabled.nix {};
systemd-shutdown = handleTest ./systemd-shutdown.nix {};
systemd-timesyncd = handleTest ./systemd-timesyncd.nix {};
+
systemd-user-tmpfiles-rules = handleTest ./systemd-user-tmpfiles-rules.nix {};
systemd-misc = handleTest ./systemd-misc.nix {};
systemd-userdbd = handleTest ./systemd-userdbd.nix {};
systemd-homed = handleTest ./systemd-homed.nix {};
+35
nixos/tests/systemd-user-tmpfiles-rules.nix
···
+
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 ]")
+
'';
+
})