Loading nixos/modules/system/boot/systemd/user.nix +14 −5 Original line number Diff line number Diff line Loading @@ -120,6 +120,13 @@ in }; systemd.user.tmpfiles = { enable = (mkEnableOption "systemd user units systemd-tmpfiles-setup.service and systemd-tmpfiles-clean.timer") // { default = true; example = false; }; rules = mkOption { type = types.listOf types.str; default = [ ]; Loading Loading @@ -210,11 +217,15 @@ in // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit v)) cfg.targets // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit v)) cfg.timers; systemd.user.timers = { # enable systemd user tmpfiles systemd-tmpfiles-clean.wantedBy = optional cfg.tmpfiles.enable "timers.target"; } # Generate timer units for all services that have a ‘startAt’ value. systemd.user.timers = mapAttrs (name: service: { // (mapAttrs (name: service: { wantedBy = [ "timers.target" ]; timerConfig.OnCalendar = service.startAt; }) (filterAttrs (name: service: service.startAt != [ ]) cfg.services); }) (filterAttrs (name: service: service.startAt != [ ]) cfg.services)); # Provide the systemd-user PAM service, required to run systemd # user instances. Loading @@ -233,9 +244,7 @@ in 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"; systemd.user.services.systemd-tmpfiles-setup.wantedBy = optional cfg.tmpfiles.enable "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 Loading nixos/tests/systemd-user-tmpfiles-rules.nix +27 −3 Original line number Diff line number Diff line Loading @@ -6,9 +6,8 @@ maintainers = [ schnusch ]; }; nodes.machine = { ... }: { nodes = rec { machine = { users.users = { alice.isNormalUser = true; bob.isNormalUser = true; Loading @@ -21,6 +20,20 @@ users.alice.rules = [ "d %h/only_alice" ]; users.bob.rules = [ "D %h/cleaned_up - - - 0" ]; }; # run every 10 seconds systemd.user.timers.systemd-tmpfiles-clean.timerConfig = { OnStartupSec = "10s"; OnUnitActiveSec = "10s"; }; }; disabled = { imports = [ machine ]; systemd.user.tmpfiles.enable = false; }; }; Loading @@ -36,5 +49,16 @@ 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 ]") machine.succeed("systemctl --user --machine=bob@ is-active systemd-tmpfiles-clean.timer") machine.succeed("runuser -u bob -- touch ~bob/cleaned_up/file") machine.wait_until_fails("[ -e ~bob/cleaned_up/file ]") # disabled user tmpfiles disabled.succeed("loginctl enable-linger alice bob") for user in ("alice", "bob"): for verb in ("is-enabled", "is-active"): for unit in ("systemd-tmpfiles-setup.service", "systemd-tmpfiles-clean.timer"): disabled.fail(f"systemctl --user --machine={user}@ {verb} {unit}") ''; } Loading
nixos/modules/system/boot/systemd/user.nix +14 −5 Original line number Diff line number Diff line Loading @@ -120,6 +120,13 @@ in }; systemd.user.tmpfiles = { enable = (mkEnableOption "systemd user units systemd-tmpfiles-setup.service and systemd-tmpfiles-clean.timer") // { default = true; example = false; }; rules = mkOption { type = types.listOf types.str; default = [ ]; Loading Loading @@ -210,11 +217,15 @@ in // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit v)) cfg.targets // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit v)) cfg.timers; systemd.user.timers = { # enable systemd user tmpfiles systemd-tmpfiles-clean.wantedBy = optional cfg.tmpfiles.enable "timers.target"; } # Generate timer units for all services that have a ‘startAt’ value. systemd.user.timers = mapAttrs (name: service: { // (mapAttrs (name: service: { wantedBy = [ "timers.target" ]; timerConfig.OnCalendar = service.startAt; }) (filterAttrs (name: service: service.startAt != [ ]) cfg.services); }) (filterAttrs (name: service: service.startAt != [ ]) cfg.services)); # Provide the systemd-user PAM service, required to run systemd # user instances. Loading @@ -233,9 +244,7 @@ in 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"; systemd.user.services.systemd-tmpfiles-setup.wantedBy = optional cfg.tmpfiles.enable "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 Loading
nixos/tests/systemd-user-tmpfiles-rules.nix +27 −3 Original line number Diff line number Diff line Loading @@ -6,9 +6,8 @@ maintainers = [ schnusch ]; }; nodes.machine = { ... }: { nodes = rec { machine = { users.users = { alice.isNormalUser = true; bob.isNormalUser = true; Loading @@ -21,6 +20,20 @@ users.alice.rules = [ "d %h/only_alice" ]; users.bob.rules = [ "D %h/cleaned_up - - - 0" ]; }; # run every 10 seconds systemd.user.timers.systemd-tmpfiles-clean.timerConfig = { OnStartupSec = "10s"; OnUnitActiveSec = "10s"; }; }; disabled = { imports = [ machine ]; systemd.user.tmpfiles.enable = false; }; }; Loading @@ -36,5 +49,16 @@ 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 ]") machine.succeed("systemctl --user --machine=bob@ is-active systemd-tmpfiles-clean.timer") machine.succeed("runuser -u bob -- touch ~bob/cleaned_up/file") machine.wait_until_fails("[ -e ~bob/cleaned_up/file ]") # disabled user tmpfiles disabled.succeed("loginctl enable-linger alice bob") for user in ("alice", "bob"): for verb in ("is-enabled", "is-active"): for unit in ("systemd-tmpfiles-setup.service", "systemd-tmpfiles-clean.timer"): disabled.fail(f"systemctl --user --machine={user}@ {verb} {unit}") ''; }