···6767 "systemd-poweroff.service"
6868 "systemd-reboot.service"
6969 "systemd-sysctl.service"
7070- "systemd-tmpfiles-setup-dev.service"
7171- "systemd-tmpfiles-setup.service"
7270 "timers.target"
7371 "tpm2.target"
7472 "umount.target"
···518516 (v: let n = escapeSystemdPath v.where;
519517 in nameValuePair "${n}.automount" (automountToUnit v)) cfg.automounts);
520518521521- # make sure all the /dev nodes are set up
522522- services.systemd-tmpfiles-setup-dev.wantedBy = ["sysinit.target"];
523519524520 services.initrd-nixos-activation = {
525521 after = [ "initrd-fs.target" ];
+179-99
nixos/modules/system/boot/systemd/tmpfiles.nix
···11-{ config, lib, pkgs, utils, ... }:
11+{ config, lib, pkgs, ... }:
2233with lib;
4455let
66 cfg = config.systemd.tmpfiles;
77+ initrdCfg = config.boot.initrd.systemd.tmpfiles;
78 systemd = config.systemd.package;
99+1010+ settingsOption = {
1111+ description = ''
1212+ Declare systemd-tmpfiles rules to create, delete, and clean up volatile
1313+ and temporary files and directories.
1414+1515+ Even though the service is called `*tmp*files` you can also create
1616+ persistent files.
1717+ '';
1818+ example = {
1919+ "10-mypackage" = {
2020+ "/var/lib/my-service/statefolder".d = {
2121+ mode = "0755";
2222+ user = "root";
2323+ group = "root";
2424+ };
2525+ };
2626+ };
2727+ default = {};
2828+ type = types.attrsOf (types.attrsOf (types.attrsOf (types.submodule ({ name, config, ... }: {
2929+ options.type = mkOption {
3030+ type = types.str;
3131+ default = name;
3232+ example = "d";
3333+ description = ''
3434+ The type of operation to perform on the file.
3535+3636+ The type consists of a single letter and optionally one or more
3737+ modifier characters.
3838+3939+ Please see the upstream documentation for the available types and
4040+ more details:
4141+ <https://www.freedesktop.org/software/systemd/man/tmpfiles.d>
4242+ '';
4343+ };
4444+ options.mode = mkOption {
4545+ type = types.str;
4646+ default = "-";
4747+ example = "0755";
4848+ description = ''
4949+ The file access mode to use when creating this file or directory.
5050+ '';
5151+ };
5252+ options.user = mkOption {
5353+ type = types.str;
5454+ default = "-";
5555+ example = "root";
5656+ description = ''
5757+ The user of the file.
5858+5959+ This may either be a numeric ID or a user/group name.
6060+6161+ If omitted or when set to `"-"`, the user and group of the user who
6262+ invokes systemd-tmpfiles is used.
6363+ '';
6464+ };
6565+ options.group = mkOption {
6666+ type = types.str;
6767+ default = "-";
6868+ example = "root";
6969+ description = ''
7070+ The group of the file.
7171+7272+ This may either be a numeric ID or a user/group name.
7373+7474+ If omitted or when set to `"-"`, the user and group of the user who
7575+ invokes systemd-tmpfiles is used.
7676+ '';
7777+ };
7878+ options.age = mkOption {
7979+ type = types.str;
8080+ default = "-";
8181+ example = "10d";
8282+ description = ''
8383+ Delete a file when it reaches a certain age.
8484+8585+ If a file or directory is older than the current time minus the age
8686+ field, it is deleted.
8787+8888+ If set to `"-"` no automatic clean-up is done.
8989+ '';
9090+ };
9191+ options.argument = mkOption {
9292+ type = types.str;
9393+ default = "";
9494+ example = "";
9595+ description = ''
9696+ An argument whose meaning depends on the type of operation.
9797+9898+ Please see the upstream documentation for the meaning of this
9999+ parameter in different situations:
100100+ <https://www.freedesktop.org/software/systemd/man/tmpfiles.d>
101101+ '';
102102+ };
103103+ }))));
104104+ };
105105+106106+ # generates a single entry for a tmpfiles.d rule
107107+ settingsEntryToRule = path: entry: ''
108108+ '${entry.type}' '${path}' '${entry.mode}' '${entry.user}' '${entry.group}' '${entry.age}' ${entry.argument}
109109+ '';
110110+111111+ # generates a list of tmpfiles.d rules from the attrs (paths) under tmpfiles.settings.<name>
112112+ pathsToRules = mapAttrsToList (path: types:
113113+ concatStrings (
114114+ mapAttrsToList (_type: settingsEntryToRule path) types
115115+ )
116116+ );
117117+118118+ mkRuleFileContent = paths: concatStrings (pathsToRules paths);
8119in
9120{
10121 options = {
···20131 '';
21132 };
221332323- systemd.tmpfiles.settings = mkOption {
134134+ systemd.tmpfiles.settings = mkOption settingsOption;
135135+136136+ boot.initrd.systemd.tmpfiles.settings = mkOption (settingsOption // {
24137 description = ''
2525- Declare systemd-tmpfiles rules to create, delete, and clean up volatile
2626- and temporary files and directories.
138138+ Similar to {option}`systemd.tmpfiles.settings` but the rules are
139139+ only applied by systemd-tmpfiles before `initrd-switch-root.target`.
271402828- Even though the service is called `*tmp*files` you can also create
2929- persistent files.
141141+ See {manpage}`bootup(7)`.
30142 '';
3131- example = {
3232- "10-mypackage" = {
3333- "/var/lib/my-service/statefolder".d = {
3434- mode = "0755";
3535- user = "root";
3636- group = "root";
3737- };
3838- };
3939- };
4040- default = {};
4141- type = types.attrsOf (types.attrsOf (types.attrsOf (types.submodule ({ name, config, ... }: {
4242- options.type = mkOption {
4343- type = types.str;
4444- default = name;
4545- example = "d";
4646- description = ''
4747- The type of operation to perform on the file.
4848-4949- The type consists of a single letter and optionally one or more
5050- modifier characters.
5151-5252- Please see the upstream documentation for the available types and
5353- more details:
5454- <https://www.freedesktop.org/software/systemd/man/tmpfiles.d>
5555- '';
5656- };
5757- options.mode = mkOption {
5858- type = types.str;
5959- default = "-";
6060- example = "0755";
6161- description = ''
6262- The file access mode to use when creating this file or directory.
6363- '';
6464- };
6565- options.user = mkOption {
6666- type = types.str;
6767- default = "-";
6868- example = "root";
6969- description = ''
7070- The user of the file.
7171-7272- This may either be a numeric ID or a user/group name.
7373-7474- If omitted or when set to `"-"`, the user and group of the user who
7575- invokes systemd-tmpfiles is used.
7676- '';
7777- };
7878- options.group = mkOption {
7979- type = types.str;
8080- default = "-";
8181- example = "root";
8282- description = ''
8383- The group of the file.
8484-8585- This may either be a numeric ID or a user/group name.
8686-8787- If omitted or when set to `"-"`, the user and group of the user who
8888- invokes systemd-tmpfiles is used.
8989- '';
9090- };
9191- options.age = mkOption {
9292- type = types.str;
9393- default = "-";
9494- example = "10d";
9595- description = ''
9696- Delete a file when it reaches a certain age.
9797-9898- If a file or directory is older than the current time minus the age
9999- field, it is deleted.
100100-101101- If set to `"-"` no automatic clean-up is done.
102102- '';
103103- };
104104- options.argument = mkOption {
105105- type = types.str;
106106- default = "";
107107- example = "";
108108- description = ''
109109- An argument whose meaning depends on the type of operation.
110110-111111- Please see the upstream documentation for the meaning of this
112112- parameter in different situations:
113113- <https://www.freedesktop.org/software/systemd/man/tmpfiles.d>
114114- '';
115115- };
116116- }))));
117117- };
143143+ });
118144119145 systemd.tmpfiles.packages = mkOption {
120146 type = types.listOf types.package;
···140166 systemd.additionalUpstreamSystemUnits = [
141167 "systemd-tmpfiles-clean.service"
142168 "systemd-tmpfiles-clean.timer"
169169+ "systemd-tmpfiles-setup-dev-early.service"
170170+ "systemd-tmpfiles-setup-dev.service"
143171 "systemd-tmpfiles-setup.service"
144144- "systemd-tmpfiles-setup-dev.service"
145172 ];
146173147174 systemd.additionalUpstreamUserUnits = [
···236263 '';
237264 })
238265 ] ++ (mapAttrsToList (name: paths:
239239- pkgs.writeTextDir "lib/tmpfiles.d/${name}.conf" (concatStrings (mapAttrsToList (path: types:
240240- concatStrings (mapAttrsToList (_type: entry: ''
241241- '${entry.type}' '${path}' '${entry.mode}' '${entry.user}' '${entry.group}' '${entry.age}' ${entry.argument}
242242- '') types)
243243- ) paths ))
266266+ pkgs.writeTextDir "lib/tmpfiles.d/${name}.conf" (mkRuleFileContent paths)
244267 ) cfg.settings);
245268246269 systemd.tmpfiles.rules = [
···256279 "R! /nix/var/nix/gcroots/tmp - - - - -"
257280 "R! /nix/var/nix/temproots - - - - -"
258281 ];
282282+283283+ boot.initrd.systemd = {
284284+ additionalUpstreamUnits = [
285285+ "systemd-tmpfiles-setup-dev-early.service"
286286+ "systemd-tmpfiles-setup-dev.service"
287287+ "systemd-tmpfiles-setup.service"
288288+ ];
289289+290290+ # override to exclude the prefix /sysroot, because it is not necessarily set up when the unit starts
291291+ services.systemd-tmpfiles-setup.serviceConfig = {
292292+ ExecStart = [
293293+ ""
294294+ "systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev --exclude-prefix=/sysroot"
295295+ ];
296296+ };
297297+298298+ # sets up files under the prefix /sysroot, after the hierarchy is available and before nixos activation
299299+ services.systemd-tmpfiles-setup-sysroot = {
300300+ description = "Create Volatile Files and Directories in the Real Root";
301301+ after = [ "initrd-fs.target" ];
302302+ before = [
303303+ "initrd-nixos-activation.service"
304304+ "shutdown.target" "initrd-switch-root.target"
305305+ ];
306306+ conflicts = [ "shutdown.target" "initrd-switch-root.target" ];
307307+ wantedBy = [ "initrd.target" ];
308308+ serviceConfig = {
309309+ Type = "oneshot";
310310+ RemainAfterExit = true;
311311+ ExecStart = "systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev --prefix=/sysroot";
312312+ SuccessExitStatus = [ "DATAERR CANTCREAT" ];
313313+ ImportCredential = [
314314+ "tmpfiles.*"
315315+ "login.motd"
316316+ "login.issue"
317317+ "network.hosts"
318318+ "ssh.authorized_keys.root"
319319+ ];
320320+ };
321321+ unitConfig = {
322322+ DefaultDependencies = false;
323323+ RefuseManualStop = true;
324324+ };
325325+326326+ };
327327+328328+ contents."/etc/tmpfiles.d" = mkIf (initrdCfg.settings != { }) {
329329+ source = pkgs.linkFarm "initrd-tmpfiles.d" (
330330+ mapAttrsToList
331331+ (name: paths: {
332332+ name = "${name}.conf";
333333+ path = pkgs.writeText "${name}.conf" (mkRuleFileContent paths);
334334+ }
335335+ )
336336+ initrdCfg.settings);
337337+ };
338338+ };
259339 };
260340}