Skip to content

Commit f71a8e7

Browse files
committedMar 21, 2025
amend! assert previous behaviour
nixos/systemd-user: enable systemd-tmpfiles-clean.timer Set systemd.user.timers.systemd-tmpfiles-clean.wantedBy when any user tmpfiles rules are set so NixOS knows to enable the unit.
1 parent a77a951 commit f71a8e7

File tree

2 files changed

+36
-61
lines changed

2 files changed

+36
-61
lines changed
 

‎nixos/modules/system/boot/systemd/user.nix

+14-8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ with lib;
1212
let
1313
cfg = config.systemd.user;
1414

15+
hasTmpfiles =
16+
cfg.tmpfiles.rules != [ ] || any (cfg': cfg'.rules != [ ]) (attrValues cfg.tmpfiles.users);
17+
1518
systemd = config.systemd.package;
1619

1720
inherit (systemdUtils.lib)
@@ -209,11 +212,16 @@ in
209212
// mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit v)) cfg.targets
210213
// mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit v)) cfg.timers;
211214

212-
# Generate timer units for all services that have a ‘startAt’ value.
213-
systemd.user.timers = mapAttrs (name: service: {
214-
wantedBy = [ "timers.target" ];
215-
timerConfig.OnCalendar = service.startAt;
216-
}) (filterAttrs (name: service: service.startAt != [ ]) cfg.services);
215+
systemd.user.timers =
216+
{
217+
# enable systemd user tmpfiles
218+
systemd-tmpfiles-clean.wantedBy = optional hasTmpfiles "timers.target";
219+
}
220+
# Generate timer units for all services that have a ‘startAt’ value.
221+
// (mapAttrs (name: service: {
222+
wantedBy = [ "timers.target" ];
223+
timerConfig.OnCalendar = service.startAt;
224+
}) (filterAttrs (name: service: service.startAt != [ ]) cfg.services));
217225

218226
# Provide the systemd-user PAM service, required to run systemd
219227
# user instances.
@@ -232,9 +240,7 @@ in
232240
systemd.services.systemd-user-sessions.restartIfChanged = false; # Restart kills all active sessions.
233241

234242
# enable systemd user tmpfiles
235-
systemd.user.services.systemd-tmpfiles-setup.wantedBy = optional (
236-
cfg.tmpfiles.rules != [ ] || any (cfg': cfg'.rules != [ ]) (attrValues cfg.tmpfiles.users)
237-
) "basic.target";
243+
systemd.user.services.systemd-tmpfiles-setup.wantedBy = optional hasTmpfiles "basic.target";
238244

239245
# /run/current-system/sw/etc/xdg is in systemd's $XDG_CONFIG_DIRS so we can
240246
# write the tmpfiles.d rules for everyone there

‎nixos/tests/systemd-user-tmpfiles-rules.nix

+22-53
Original file line numberDiff line numberDiff line change
@@ -7,62 +7,36 @@ import ./make-test-python.nix (
77
maintainers = [ schnusch ];
88
};
99

10-
nodes = {
11-
machine =
12-
{ ... }:
13-
{
14-
users.users = {
15-
alice.isNormalUser = true;
16-
bob.isNormalUser = true;
17-
};
18-
19-
systemd.user.tmpfiles = {
20-
rules = [
21-
"d %h/user_tmpfiles_created"
22-
];
23-
users.alice.rules = [
24-
"d %h/only_alice"
25-
];
26-
users.bob.rules = [
27-
"D %h/cleaned_up - - - 0"
28-
];
29-
};
30-
31-
# run every 10 seconds
32-
systemd.user.timers.systemd-tmpfiles-clean = {
33-
wantedBy = [ "timers.target" ];
34-
timerConfig = {
35-
OnStartupSec = "10s";
36-
OnUnitActiveSec = "10s";
37-
};
38-
};
10+
nodes.machine =
11+
{ ... }:
12+
{
13+
users.users = {
14+
alice.isNormalUser = true;
15+
bob.isNormalUser = true;
3916
};
4017

41-
default =
42-
{ ... }:
43-
{
44-
users.users = {
45-
alice.isNormalUser = true;
46-
};
18+
systemd.user.tmpfiles = {
19+
rules = [
20+
"d %h/user_tmpfiles_created"
21+
];
22+
users.alice.rules = [
23+
"d %h/only_alice"
24+
];
25+
users.bob.rules = [
26+
"D %h/cleaned_up - - - 0"
27+
];
28+
};
4729

48-
systemd.user.tmpfiles = {
49-
rules = [
50-
"d %h/user_tmpfiles_created"
51-
];
52-
};
30+
# run every 10 seconds
31+
systemd.user.timers.systemd-tmpfiles-clean.timerConfig = {
32+
OnStartupSec = "10s";
33+
OnUnitActiveSec = "10s";
5334
};
54-
};
35+
};
5536

5637
testScript =
5738
{ ... }:
5839
''
59-
# Test if `systemd-tmpfiles-clean.timer` is not enabled if we do not change
60-
# anything below `systemd.user.timers.systemd-tmpfiles-clean`.
61-
default.succeed("loginctl enable-linger alice")
62-
default.wait_until_succeeds("systemctl --user --machine=alice@ is-active systemd-tmpfiles-setup.service")
63-
default.fail("systemctl --user --machine=alice@ is-active systemd-tmpfiles-clean.timer")
64-
65-
# test user-tmpfiles.d
6640
machine.succeed("loginctl enable-linger alice bob")
6741
6842
machine.wait_until_succeeds("systemctl --user --machine=alice@ is-active systemd-tmpfiles-setup.service")
@@ -74,11 +48,6 @@ import ./make-test-python.nix (
7448
machine.succeed("[ ! -e ~bob/only_alice ]")
7549
7650
machine.succeed("systemctl --user --machine=bob@ is-active systemd-tmpfiles-clean.timer")
77-
machine.succeed(
78-
# we cannot combine `--machine=bob@` and `cat`
79-
# runuser -l does not set $XDG_RUNTIME_DIR
80-
'runuser -u bob -- env XDG_RUNTIME_DIR="/run/user/$(id -u bob)" systemctl --user cat systemd-tmpfiles-clean.timer >&2'
81-
)
8251
machine.succeed("runuser -u bob -- touch ~bob/cleaned_up/file")
8352
machine.wait_until_fails("[ -e ~bob/cleaned_up/file ]")
8453
'';

0 commit comments

Comments
 (0)
Failed to load comments.