From af119feb17cb242398e0fb97f92b867d25882522 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Wed, 5 Nov 2025 12:19:54 -0600 Subject: [PATCH] Revert "tmpfiles: migrate to an RFC42-style option" This reverts commit 090aa14e5dbaa73f16624f408977582869c0c49a. Signed-off-by: Austin Horstman --- modules/misc/tmpfiles.nix | 198 ++---------------- modules/programs/glab.nix | 14 +- tests/default.nix | 1 - .../standalone/rclone/sops-nix.nix | 9 +- tests/modules/misc/tmpfiles/basic-rules.nix | 24 --- tests/modules/misc/tmpfiles/common-stubs.nix | 3 - tests/modules/misc/tmpfiles/default.nix | 6 - .../tmpfiles/escaped-argument-warning.nix | 14 -- tests/modules/misc/tmpfiles/no-rules.nix | 9 - 9 files changed, 31 insertions(+), 247 deletions(-) delete mode 100644 tests/modules/misc/tmpfiles/basic-rules.nix delete mode 100644 tests/modules/misc/tmpfiles/common-stubs.nix delete mode 100644 tests/modules/misc/tmpfiles/default.nix delete mode 100644 tests/modules/misc/tmpfiles/escaped-argument-warning.nix delete mode 100644 tests/modules/misc/tmpfiles/no-rules.nix diff --git a/modules/misc/tmpfiles.nix b/modules/misc/tmpfiles.nix index e5d21a6e9..15fc5c38d 100644 --- a/modules/misc/tmpfiles.nix +++ b/modules/misc/tmpfiles.nix @@ -9,125 +9,6 @@ let cfg = config.systemd.user.tmpfiles; - ruleSubmodule = lib.types.submodule ( - { name, ... }: - { - options.type = lib.mkOption { - type = lib.types.str; - readOnly = true; - default = name; - defaultText = "‹tmpfiles-type›"; - example = "d"; - description = '' - The type of operation to perform on the file. - - The type consists of a single letter and optionally one or more - modifier characters. - - Please see the upstream documentation for the available types and - more details: {manpage}`tmpfiles.d(5)` - ''; - }; - options.mode = lib.mkOption { - type = lib.types.str; - default = "-"; - example = "0755"; - description = '' - The file access mode to use when creating this file or directory. - ''; - }; - options.user = lib.mkOption { - type = lib.types.str; - default = "-"; - example = "root"; - description = '' - The user of the file. - - This may either be a numeric ID or a user/group name. - - If omitted or when set to `"-"`, the user and group of the user who - invokes systemd-tmpfiles is used. - ''; - }; - options.group = lib.mkOption { - type = lib.types.str; - default = "-"; - example = "root"; - description = '' - The group of the file. - - This may either be a numeric ID or a user/group name. - - If omitted or when set to `"-"`, the user and group of the user who - invokes systemd-tmpfiles is used. - ''; - }; - options.age = lib.mkOption { - type = lib.types.str; - default = "-"; - example = "10d"; - description = '' - Delete a file when it reaches a certain age. - - If a file or directory is older than the current time minus the age - field, it is deleted. - - If set to `"-"`, no automatic clean-up is done. - ''; - }; - options.argument = lib.mkOption { - type = lib.types.str; - default = ""; - example = ""; - description = '' - An argument whose meaning depends on the type of operation. - - Please see the upstream documentation for the meaning of this - parameter in different situations: {manpage}`tmpfiles.d(5)` - ''; - }; - } - ); - - modulePrefix = [ - "systemd" - "user" - "tmpfiles" - "settings" - ]; - - mkFileName = configName: "user-tmpfiles.d/home-manager-${configName}.conf"; - - mkConfigFile = - name: rules: - let - escapeArgument = lib.strings.escapeC [ - "\t" - "\n" - "\r" - " " - "\\" - ]; - mkRule = path: rule: '' - '${rule.type}' '${path}' '${rule.mode}' '${rule.user}' '${rule.group}' '${rule.age}' ${escapeArgument rule.argument} - ''; - in - { - text = '' - # This file was generated by Home Manager and should not be modified. - # Please change the option '${lib.showAttrPath (modulePrefix ++ [ name ])}' instead. - ${lib.pipe rules [ - (lib.mapAttrs (_path: lib.attrValues)) - (lib.mapAttrsToList (path: map (mkRule path))) - lib.flatten - lib.concatStrings - ]} - ''; - onChange = '' - run ${pkgs.systemd}/bin/systemd-tmpfiles --user --remove --create ''${DRY_RUN:+--dry-run} '${mkFileName name}' - ''; - }; - in { meta.maintainers = with lib.maintainers; [ @@ -135,70 +16,34 @@ in dawidsowa ]; - imports = [ - (lib.mkRemovedOptionModule [ "systemd" "user" "tmpfiles" "rules" ] '' - It has been replaced by 'systemd.user.tmpfiles.settings'. - '') - ]; - - options.systemd.user.tmpfiles.settings = lib.mkOption { + options.systemd.user.tmpfiles.rules = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + example = [ "L /home/user/Documents - - - - /mnt/data/Documents" ]; description = '' - Declare systemd-tmpfiles rules to create, delete, and clean up volatile - and temporary files and directories. - - Even though the service is called `*tmp*files` you can also create - persistent files. + Rules for creating and cleaning up temporary files + automatically. See + {manpage}`tmpfiles.d(5)` + for the exact format. ''; - example = { - cache."%C".d = { - mode = "0755"; - user = "alice"; - group = "alice"; - age = "4 weeks"; - }; - }; - default = { }; - type = - let - attrsWith' = placeholder: elemType: lib.types.attrsWith { inherit elemType placeholder; }; - nonEmptyAttrsWith' = - placeholder: elemType: - let - attrs = lib.types.addCheck (attrsWith' placeholder elemType) (s: s != { }); - in - attrs - // { - name = "nonEmptyAttrsOf"; - description = "non-empty ${attrs.description}"; - emptyValue = { }; # no .value attribute, meaning there is not empty value - substSubModules = m: nonEmptyAttrsWith' placeholder (elemType.substSubModules m); - }; - in - attrsWith' "config-name" ( - nonEmptyAttrsWith' "path" (nonEmptyAttrsWith' "tmpfiles-type" ruleSubmodule) - ); }; - config = lib.mkIf (cfg.settings != { }) { + config = lib.mkIf (cfg.rules != [ ]) { assertions = [ (lib.hm.assertions.assertPlatform "systemd.user.tmpfiles" pkgs lib.platforms.linux) ]; - warnings = lib.flatten ( - lib.mapAttrsToListRecursive ( - path: value: - lib.optional - (lib.last path == "argument" && lib.match ''.*\\([nrt]|x[0-9A-Fa-f]{2}).*'' value != null) - '' - The '${lib.showAttrPath (modulePrefix ++ path)}' option - appears to contain escape sequences, which will be escaped again. - Unescape them if this is not intended. The assigned string is: - "${value}" - '' - ) cfg.settings - ); - xdg.configFile = { + "user-tmpfiles.d/home-manager.conf" = { + text = '' + # This file is created automatically and should not be modified. + # Please change the option ‘systemd.user.tmpfiles.rules’ instead. + ${lib.concatStringsSep "\n" cfg.rules} + ''; + onChange = '' + run ${pkgs.systemd}/bin/systemd-tmpfiles --user --remove --create ''${DRY_RUN:+--dry-run} + ''; + }; "systemd/user/basic.target.wants/systemd-tmpfiles-setup.service".source = "${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-setup.service"; "systemd/user/systemd-tmpfiles-setup.service".source = @@ -207,9 +52,6 @@ in "${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-clean.timer"; "systemd/user/systemd-tmpfiles-clean.service".source = "${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-clean.service"; - } - // lib.mapAttrs' ( - name: rules: lib.nameValuePair (mkFileName name) (mkConfigFile name rules) - ) cfg.settings; + }; }; } diff --git a/modules/programs/glab.nix b/modules/programs/glab.nix index 1aac3c004..525456dc4 100644 --- a/modules/programs/glab.nix +++ b/modules/programs/glab.nix @@ -36,12 +36,14 @@ in # Use `systemd-tmpfiles` since glab requires its configuration file to have # mode 0600. - systemd.user.tmpfiles.settings.glab = lib.mkIf (cfg.settings != { }) { - "${config.xdg.configHome}/glab-cli/config.yml" = { - "C+".argument = yaml.generate "glab-config" cfg.settings; - z.mode = "0600"; - }; - }; + systemd.user.tmpfiles.rules = + let + target = "${config.xdg.configHome}/glab-cli/config.yml"; + in + lib.mkIf (cfg.settings != { }) [ + "C+ ${target} - - - - ${yaml.generate "glab-config" cfg.settings}" + "z ${target} 0600" + ]; xdg.configFile."glab-cli/aliases.yml" = lib.mkIf (cfg.aliases != { }) { source = yaml.generate "glab-aliases" cfg.aliases; diff --git a/tests/default.nix b/tests/default.nix index 735e1f246..88ff40ece 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -203,7 +203,6 @@ import nmtSrc { ./modules/misc/numlock ./modules/misc/pam ./modules/misc/qt - ./modules/misc/tmpfiles ./modules/misc/xdg/linux.nix ./modules/misc/xsession ./modules/systemd diff --git a/tests/integration/standalone/rclone/sops-nix.nix b/tests/integration/standalone/rclone/sops-nix.nix index a7baf0614..71283edf5 100644 --- a/tests/integration/standalone/rclone/sops-nix.nix +++ b/tests/integration/standalone/rclone/sops-nix.nix @@ -28,12 +28,9 @@ in uid = 1000; }; - systemd.tmpfiles.settings.age."/home/alice/age-key".f = { - mode = "400"; - user = "alice"; - group = "users"; - argument = ageKey; - }; + systemd.tmpfiles.rules = [ + "f /home/alice/age-key 400 alice users - ${ageKey}" + ]; home-manager.users.alice = { config, ... }: diff --git a/tests/modules/misc/tmpfiles/basic-rules.nix b/tests/modules/misc/tmpfiles/basic-rules.nix deleted file mode 100644 index 30a451737..000000000 --- a/tests/modules/misc/tmpfiles/basic-rules.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ - imports = [ ./common-stubs.nix ]; - - systemd.user.tmpfiles.settings = { - cache."%C".d.age = "4 weeks"; - myTool."%h/.config/myTool.conf"."f+" = { - mode = "0644"; - user = "alice"; - group = "users"; - argument = "my unescaped config"; - }; - }; - - nmt.script = '' - cacheRulesFile=home-files/.config/user-tmpfiles.d/home-manager-cache.conf - assertFileExists $cacheRulesFile - assertFileRegex $cacheRulesFile "^'d' '%C' '-' '-' '-' '4 weeks' $" - - myToolRulesFile=home-files/.config/user-tmpfiles.d/home-manager-myTool.conf - assertFileExists $myToolRulesFile - assertFileRegex $myToolRulesFile \ - "^'f+' '%h/.config/myTool.conf' '0644' 'alice' 'users' '-' my\\\\x20unescaped\\\\x20config$" - ''; -} diff --git a/tests/modules/misc/tmpfiles/common-stubs.nix b/tests/modules/misc/tmpfiles/common-stubs.nix deleted file mode 100644 index abc4c732d..000000000 --- a/tests/modules/misc/tmpfiles/common-stubs.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - test.stubs.systemd.outPath = null; -} diff --git a/tests/modules/misc/tmpfiles/default.nix b/tests/modules/misc/tmpfiles/default.nix deleted file mode 100644 index 1caa5fc7e..000000000 --- a/tests/modules/misc/tmpfiles/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ - tmpfiles-no-rules = ./no-rules.nix; - tmpfiles-basic-rules = ./basic-rules.nix; - - tmpfiles-escaped-argument-warning = ./escaped-argument-warning.nix; -} diff --git a/tests/modules/misc/tmpfiles/escaped-argument-warning.nix b/tests/modules/misc/tmpfiles/escaped-argument-warning.nix deleted file mode 100644 index 9284de3c8..000000000 --- a/tests/modules/misc/tmpfiles/escaped-argument-warning.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ - imports = [ ./common-stubs.nix ]; - - systemd.user.tmpfiles.settings.foo.path.f.argument = "my\\x20unescaped\\x20config"; - - test.asserts.warnings.expected = [ - '' - The 'systemd.user.tmpfiles.settings.foo.path.f.argument' option - appears to contain escape sequences, which will be escaped again. - Unescape them if this is not intended. The assigned string is: - "my\x20unescaped\x20config" - '' - ]; -} diff --git a/tests/modules/misc/tmpfiles/no-rules.nix b/tests/modules/misc/tmpfiles/no-rules.nix deleted file mode 100644 index 8c8f0e77e..000000000 --- a/tests/modules/misc/tmpfiles/no-rules.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ - imports = [ ./common-stubs.nix ]; - - systemd.user.tmpfiles.settings = { }; - - nmt.script = '' - assertPathNotExists home-files/.config/user-tmpfiles.d/ - ''; -}