lol

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

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

authored by

Florian Klink and committed by
GitHub
24b41896 11d29ac9

+111
+75
nixos/modules/system/boot/systemd/user.nix
··· 39 39 "timers.target" 40 40 "xdg-desktop-autostart.target" 41 41 ] ++ config.systemd.additionalUpstreamUserUnits; 42 + 43 + writeTmpfiles = { rules, user ? null }: 44 + let 45 + suffix = if user == null then "" else "-${user}"; 46 + in 47 + pkgs.writeTextFile { 48 + name = "nixos-user-tmpfiles.d${suffix}"; 49 + destination = "/etc/xdg/user-tmpfiles.d/00-nixos${suffix}.conf"; 50 + text = '' 51 + # This file is created automatically and should not be modified. 52 + # Please change the options ‘systemd.user.tmpfiles’ instead. 53 + ${concatStringsSep "\n" rules} 54 + ''; 55 + }; 42 56 in { 43 57 options = { 44 58 systemd.user.extraConfig = mkOption { ··· 93 107 description = lib.mdDoc "Definition of systemd per-user timer units."; 94 108 }; 95 109 110 + systemd.user.tmpfiles = { 111 + rules = mkOption { 112 + type = types.listOf types.str; 113 + default = []; 114 + example = [ "D %C - - - 7d" ]; 115 + description = lib.mdDoc '' 116 + Global user rules for creation, deletion and cleaning of volatile and 117 + temporary files automatically. See 118 + {manpage}`tmpfiles.d(5)` 119 + for the exact format. 120 + ''; 121 + }; 122 + 123 + users = mkOption { 124 + description = mdDoc '' 125 + Per-user rules for creation, deletion and cleaning of volatile and 126 + temporary files automatically. 127 + ''; 128 + type = types.attrsOf (types.submodule { 129 + options = { 130 + rules = mkOption { 131 + type = types.listOf types.str; 132 + default = []; 133 + example = [ "D %C - - - 7d" ]; 134 + description = mdDoc '' 135 + Per-user rules for creation, deletion and cleaning of volatile and 136 + temporary files automatically. See 137 + {manpage}`tmpfiles.d(5)` 138 + for the exact format. 139 + ''; 140 + }; 141 + }; 142 + }); 143 + }; 144 + }; 145 + 96 146 systemd.additionalUpstreamUserUnits = mkOption { 97 147 default = []; 98 148 type = types.listOf types.str; ··· 154 204 # Some overrides to upstream units. 155 205 systemd.services."user@".restartIfChanged = false; 156 206 systemd.services.systemd-user-sessions.restartIfChanged = false; # Restart kills all active sessions. 207 + 208 + # enable systemd user tmpfiles 209 + systemd.user.services.systemd-tmpfiles-setup.wantedBy = 210 + optional 211 + (cfg.tmpfiles.rules != [] || any (cfg': cfg'.rules != []) (attrValues cfg.tmpfiles.users)) 212 + "basic.target"; 213 + 214 + # /run/current-system/sw/etc/xdg is in systemd's $XDG_CONFIG_DIRS so we can 215 + # write the tmpfiles.d rules for everyone there 216 + environment.systemPackages = 217 + optional 218 + (cfg.tmpfiles.rules != []) 219 + (writeTmpfiles { inherit (cfg.tmpfiles) rules; }); 220 + 221 + # /etc/profiles/per-user/$USER/etc/xdg is in systemd's $XDG_CONFIG_DIRS so 222 + # we can write a single user's tmpfiles.d rules there 223 + users.users = 224 + mapAttrs 225 + (user: cfg': { 226 + packages = optional (cfg'.rules != []) (writeTmpfiles { 227 + inherit (cfg') rules; 228 + inherit user; 229 + }); 230 + }) 231 + cfg.tmpfiles.users; 157 232 }; 158 233 }
+1
nixos/tests/all-tests.nix
··· 658 658 systemd-portabled = handleTest ./systemd-portabled.nix {}; 659 659 systemd-shutdown = handleTest ./systemd-shutdown.nix {}; 660 660 systemd-timesyncd = handleTest ./systemd-timesyncd.nix {}; 661 + systemd-user-tmpfiles-rules = handleTest ./systemd-user-tmpfiles-rules.nix {}; 661 662 systemd-misc = handleTest ./systemd-misc.nix {}; 662 663 systemd-userdbd = handleTest ./systemd-userdbd.nix {}; 663 664 systemd-homed = handleTest ./systemd-homed.nix {};
+35
nixos/tests/systemd-user-tmpfiles-rules.nix
··· 1 + import ./make-test-python.nix ({ lib, ... }: { 2 + name = "systemd-user-tmpfiles-rules"; 3 + 4 + meta = with lib.maintainers; { 5 + maintainers = [ schnusch ]; 6 + }; 7 + 8 + nodes.machine = { ... }: { 9 + users.users = { 10 + alice.isNormalUser = true; 11 + bob.isNormalUser = true; 12 + }; 13 + 14 + systemd.user.tmpfiles = { 15 + rules = [ 16 + "d %h/user_tmpfiles_created" 17 + ]; 18 + users.alice.rules = [ 19 + "d %h/only_alice" 20 + ]; 21 + }; 22 + }; 23 + 24 + testScript = { ... }: '' 25 + machine.succeed("loginctl enable-linger alice bob") 26 + 27 + machine.wait_until_succeeds("systemctl --user --machine=alice@ is-active systemd-tmpfiles-setup.service") 28 + machine.succeed("[ -d ~alice/user_tmpfiles_created ]") 29 + machine.succeed("[ -d ~alice/only_alice ]") 30 + 31 + machine.wait_until_succeeds("systemctl --user --machine=bob@ is-active systemd-tmpfiles-setup.service") 32 + machine.succeed("[ -d ~bob/user_tmpfiles_created ]") 33 + machine.succeed("[ ! -e ~bob/only_alice ]") 34 + ''; 35 + })