9 with systemdUtils.unitOptions;
13 cfg = config.systemd.user;
15 systemd = config.systemd.package;
17 inherit (systemdUtils.lib)
35 "graphical-session-pre.target"
36 "graphical-session.target"
44 "systemd-exit.service"
46 "xdg-desktop-autostart.target"
47 ] ++ config.systemd.additionalUpstreamUserUnits;
55 suffix = optionalString (user != null) "-${user}";
58 name = "nixos-user-tmpfiles.d${suffix}";
59 destination = "/etc/xdg/user-tmpfiles.d/00-nixos${suffix}.conf";
61 # This file is created automatically and should not be modified.
62 # Please change the options ‘systemd.user.tmpfiles’ instead.
63 ${concatStringsSep "\n" rules}
69 systemd.user.extraConfig = mkOption {
72 example = "DefaultCPUAccounting=yes";
74 Extra config options for systemd user instances. See {manpage}`systemd-user.conf(5)` for
79 systemd.user.units = mkOption {
80 description = "Definition of systemd per-user units.";
82 type = systemdUtils.types.units;
85 systemd.user.paths = mkOption {
87 type = systemdUtils.types.paths;
88 description = "Definition of systemd per-user path units.";
91 systemd.user.services = mkOption {
93 type = systemdUtils.types.services;
94 description = "Definition of systemd per-user service units.";
97 systemd.user.slices = mkOption {
99 type = systemdUtils.types.slices;
100 description = "Definition of systemd per-user slice units.";
103 systemd.user.sockets = mkOption {
105 type = systemdUtils.types.sockets;
106 description = "Definition of systemd per-user socket units.";
109 systemd.user.targets = mkOption {
111 type = systemdUtils.types.targets;
112 description = "Definition of systemd per-user target units.";
115 systemd.user.timers = mkOption {
117 type = systemdUtils.types.timers;
118 description = "Definition of systemd per-user timer units.";
121 systemd.user.tmpfiles = {
123 type = types.listOf types.str;
125 example = [ "D %C - - - 7d" ];
127 Global user rules for creation, deletion and cleaning of volatile and
128 temporary files automatically. See
129 {manpage}`tmpfiles.d(5)`
130 for the exact format.
136 Per-user rules for creation, deletion and cleaning of volatile and
137 temporary files automatically.
140 type = types.attrsOf (
144 type = types.listOf types.str;
146 example = [ "D %C - - - 7d" ];
148 Per-user rules for creation, deletion and cleaning of volatile and
149 temporary files automatically. See
150 {manpage}`tmpfiles.d(5)`
151 for the exact format.
160 systemd.user.generators = mkOption {
161 type = types.attrsOf types.path;
164 systemd-gpt-auto-generator = "/dev/null";
167 Definition of systemd generators; see {manpage}`systemd.generator(5)`.
169 For each `NAME = VALUE` pair of the attrSet, a link is generated from
170 `/etc/systemd/user-generators/NAME` to `VALUE`.
174 systemd.additionalUpstreamUserUnits = mkOption {
176 type = types.listOf types.str;
179 Additional units shipped with systemd that should be enabled for per-user systemd instances.
186 systemd.additionalUpstreamSystemUnits = [
191 "systemd/user".source = generateUnits {
194 upstreamUnits = upstreamUserUnits;
198 "systemd/user.conf".text = ''
205 mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit v)) cfg.paths
206 // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit v)) cfg.services
207 // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit v)) cfg.slices
208 // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit v)) cfg.sockets
209 // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit v)) cfg.targets
210 // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit v)) cfg.timers;
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);
218 # Provide the systemd-user PAM service, required to run systemd
220 security.pam.services.systemd-user = {
221 # Ensure that pam_systemd gets included. This is special-cased
222 # in systemd to provide XDG_RUNTIME_DIR.
224 # Disable pam_mount in systemd-user to prevent it from being called
225 # multiple times during login, because it will prevent pam_mount from
226 # unmounting the previously mounted volumes.
230 # Some overrides to upstream units.
231 systemd.services."user@".restartIfChanged = false;
232 systemd.services.systemd-user-sessions.restartIfChanged = false; # Restart kills all active sessions.
234 # 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)
239 # /run/current-system/sw/etc/xdg is in systemd's $XDG_CONFIG_DIRS so we can
240 # write the tmpfiles.d rules for everyone there
241 environment.systemPackages = optional (cfg.tmpfiles.rules != [ ]) (writeTmpfiles {
242 inherit (cfg.tmpfiles) rules;
245 # /etc/profiles/per-user/$USER/etc/xdg is in systemd's $XDG_CONFIG_DIRS so
246 # we can write a single user's tmpfiles.d rules there
247 users.users = mapAttrs (user: cfg': {
248 packages = optional (cfg'.rules != [ ]) (writeTmpfiles {
249 inherit (cfg') rules;
252 }) cfg.tmpfiles.users;
254 system.userActivationScripts.tmpfiles = ''
255 ${config.systemd.package}/bin/systemd-tmpfiles --user --create --remove