1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-08 19:46:05 +01:00

Revert "tmpfiles: add option to purge rules' targets on change"

This reverts commit b4350d54c2.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
This commit is contained in:
Austin Horstman 2025-11-05 12:19:54 -06:00
parent 6a40be5eaf
commit 06aeeed62f
7 changed files with 58 additions and 151 deletions

View file

@ -89,46 +89,6 @@ 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);
};
configSubmodule = lib.types.submodule {
options.rules = lib.mkOption {
description = "The rules contained in this configuration.";
example = {
"%C".d = {
mode = "0755";
user = "alice";
group = "alice";
age = "4 weeks";
};
};
type = nonEmptyAttrsWith' "path" (nonEmptyAttrsWith' "tmpfiles-type" ruleSubmodule);
};
options.purgeOnChange = lib.mkOption {
description = ''
Whether the rules that are marked for purging, will automatically
be purged when the set of rules changes.
See {manpage}`systemd-tmpfiles(8)` for details about purging.
'';
type = lib.types.bool;
default = false;
};
};
modulePrefix = [ modulePrefix = [
"systemd" "systemd"
"user" "user"
@ -140,9 +100,6 @@ let
mkConfigFile = mkConfigFile =
name: rules: name: rules:
{
suffix ? [ name ],
}:
let let
escapeArgument = lib.strings.escapeC [ escapeArgument = lib.strings.escapeC [
"\t" "\t"
@ -158,7 +115,7 @@ let
{ {
text = '' text = ''
# This file was generated by Home Manager and should not be modified. # This file was generated by Home Manager and should not be modified.
# Please change the option '${lib.showAttrPath (modulePrefix ++ suffix)}' instead. # Please change the option '${lib.showAttrPath (modulePrefix ++ [ name ])}' instead.
${lib.pipe rules [ ${lib.pipe rules [
(lib.mapAttrs (_path: lib.attrValues)) (lib.mapAttrs (_path: lib.attrValues))
(lib.mapAttrsToList (path: map (mkRule path))) (lib.mapAttrsToList (path: map (mkRule path)))
@ -171,13 +128,6 @@ let
''; '';
}; };
nonPurgedConfigs = lib.filterAttrs (_name: config: !config.purgeOnChange) cfg.settings;
purgedConfigs = lib.filterAttrs (_name: config: config.purgeOnChange) cfg.settings;
# WARNING: When changing this path, the next home-manager generation will
# not find and the rules of the old generation that are subject to purging.
purgedRulesConfigName = "purge-on-change";
in in
{ {
meta.maintainers = with lib.maintainers; [ meta.maintainers = with lib.maintainers; [
@ -200,7 +150,7 @@ in
persistent files. persistent files.
''; '';
example = { example = {
cache.rules."%C".d = { cache."%C".d = {
mode = "0755"; mode = "0755";
user = "alice"; user = "alice";
group = "alice"; group = "alice";
@ -208,70 +158,58 @@ in
}; };
}; };
default = { }; default = { };
type = attrsWith' "config-name" configSubmodule; 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.mkMerge [ config = lib.mkIf (cfg.settings != { }) {
assertions = [
(lib.hm.assertions.assertPlatform "systemd.user.tmpfiles" pkgs lib.platforms.linux)
];
(lib.mkIf pkgs.stdenv.hostPlatform.isLinux { warnings = lib.flatten (
# The activation script must be enabled unconditionally in order to lib.mapAttrsToListRecursive (
# guarantee that the old rules are purged even if the new set of rules path: value:
# is empty, i.e. `cfg.rulesToPurgeOnChange == [ ]`. lib.optional
home.activation.purgeTmpfiles = lib.hm.dag.entryAfter [ "writeBoundary" ] ( (lib.last path == "argument" && lib.match ''.*\\([nrt]|x[0-9A-Fa-f]{2}).*'' value != null)
let ''
relativeXdgConfigHome = lib.strings.removePrefix "${config.home.homeDirectory}/" config.xdg.configHome; The '${lib.showAttrPath (modulePrefix ++ path)}' option
configPath = "home-files/${relativeXdgConfigHome}/${purgedRulesConfigName}"; appears to contain escape sequences, which will be escaped again.
in Unescape them if this is not intended. The assigned string is:
'' "${value}"
if [[ -v oldGenPath && -f $oldGenPath/${configPath} ]] && ''
diff -q $oldGenPath/${configPath} $newGenPath/${configPath} &>/dev/null; then ) cfg.settings
verboseEcho "Purge old tmpfiles" );
run ${pkgs.systemd}/bin/systemd-tmpfiles --user --purge ''${DRY_RUN:+--dry-run} $oldGenPath/${configPath}
fi
''
);
})
(lib.mkIf (cfg.settings != { }) { xdg.configFile = {
assertions = [ "systemd/user/basic.target.wants/systemd-tmpfiles-setup.service".source =
(lib.hm.assertions.assertPlatform "systemd.user.tmpfiles" pkgs lib.platforms.linux) "${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-setup.service";
]; "systemd/user/systemd-tmpfiles-setup.service".source =
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-setup.service";
warnings = lib.flatten ( "systemd/user/timers.target.wants/systemd-tmpfiles-clean.timer".source =
lib.mapAttrsToListRecursive ( "${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-clean.timer";
path: value: "systemd/user/systemd-tmpfiles-clean.service".source =
lib.optional "${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-clean.service";
(lib.last path == "argument" && lib.match ''.*\\([nrt]|x[0-9A-Fa-f]{2}).*'' value != null) }
'' // lib.mapAttrs' (
The '${lib.showAttrPath (modulePrefix ++ path)}' option name: rules: lib.nameValuePair (mkFileName name) (mkConfigFile name rules)
appears to contain escape sequences, which will be escaped again. ) cfg.settings;
Unescape them if this is not intended. The assigned string is: };
"${value}"
''
) cfg.settings
);
xdg.configFile = {
"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 =
"${pkgs.systemd}/example/systemd/user/systemd-tmpfiles-setup.service";
"systemd/user/timers.target.wants/systemd-tmpfiles-clean.timer".source =
"${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: config: lib.nameValuePair (mkFileName name) (mkConfigFile name config.rules { })
) nonPurgedConfigs
// lib.optionalAttrs (purgedConfigs != { }) {
${mkFileName purgedRulesConfigName} =
let
purgedConfigsMerged = lib.foldl' lib.recursiveUpdate { } (lib.attrValues purgedConfigs);
in
mkConfigFile purgedRulesConfigName purgedConfigsMerged.rules { suffix = [ ]; };
};
})
];
} }

View file

@ -37,7 +37,7 @@ in
# Use `systemd-tmpfiles` since glab requires its configuration file to have # Use `systemd-tmpfiles` since glab requires its configuration file to have
# mode 0600. # mode 0600.
systemd.user.tmpfiles.settings.glab = lib.mkIf (cfg.settings != { }) { systemd.user.tmpfiles.settings.glab = lib.mkIf (cfg.settings != { }) {
rules."${config.xdg.configHome}/glab-cli/config.yml" = { "${config.xdg.configHome}/glab-cli/config.yml" = {
"C+".argument = yaml.generate "glab-config" cfg.settings; "C+".argument = yaml.generate "glab-config" cfg.settings;
z.mode = "0600"; z.mode = "0600";
}; };

View file

@ -28,7 +28,7 @@ in
uid = 1000; uid = 1000;
}; };
systemd.tmpfiles.settings.age.rules."/home/alice/age-key".f = { systemd.tmpfiles.settings.age."/home/alice/age-key".f = {
mode = "400"; mode = "400";
user = "alice"; user = "alice";
group = "users"; group = "users";

View file

@ -2,8 +2,8 @@
imports = [ ./common-stubs.nix ]; imports = [ ./common-stubs.nix ];
systemd.user.tmpfiles.settings = { systemd.user.tmpfiles.settings = {
cache.rules."%C".d.age = "4 weeks"; cache."%C".d.age = "4 weeks";
myTool.rules."%h/.config/myTool.conf"."f+" = { myTool."%h/.config/myTool.conf"."f+" = {
mode = "0644"; mode = "0644";
user = "alice"; user = "alice";
group = "users"; group = "users";
@ -12,8 +12,6 @@
}; };
nmt.script = '' nmt.script = ''
assertPathNotExists home-files/.config/user-tmpfiles.d/home-manager-purge-on-change.conf
cacheRulesFile=home-files/.config/user-tmpfiles.d/home-manager-cache.conf cacheRulesFile=home-files/.config/user-tmpfiles.d/home-manager-cache.conf
assertFileExists $cacheRulesFile assertFileExists $cacheRulesFile
assertFileRegex $cacheRulesFile "^'d' '%C' '-' '-' '-' '4 weeks' $" assertFileRegex $cacheRulesFile "^'d' '%C' '-' '-' '-' '4 weeks' $"

View file

@ -1,7 +1,6 @@
{ {
tmpfiles-no-rules = ./no-rules.nix; tmpfiles-no-rules = ./no-rules.nix;
tmpfiles-basic-rules = ./basic-rules.nix; tmpfiles-basic-rules = ./basic-rules.nix;
tmpfiles-rules-with-purging = ./rules-with-purging.nix;
tmpfiles-escaped-argument-warning = ./escaped-argument-warning.nix; tmpfiles-escaped-argument-warning = ./escaped-argument-warning.nix;
} }

View file

@ -1,11 +1,11 @@
{ {
imports = [ ./common-stubs.nix ]; imports = [ ./common-stubs.nix ];
systemd.user.tmpfiles.settings.foo.rules.path.f.argument = "my\\x20unescaped\\x20config"; systemd.user.tmpfiles.settings.foo.path.f.argument = "my\\x20unescaped\\x20config";
test.asserts.warnings.expected = [ test.asserts.warnings.expected = [
'' ''
The 'systemd.user.tmpfiles.settings.foo.rules.path.f.argument' option The 'systemd.user.tmpfiles.settings.foo.path.f.argument' option
appears to contain escape sequences, which will be escaped again. appears to contain escape sequences, which will be escaped again.
Unescape them if this is not intended. The assigned string is: Unescape them if this is not intended. The assigned string is:
"my\x20unescaped\x20config" "my\x20unescaped\x20config"

View file

@ -1,28 +0,0 @@
{
imports = [ ./common-stubs.nix ];
systemd.user.tmpfiles.settings = {
cache.rules."%C".d.age = "4 weeks";
myTool = {
rules = {
"%h/.config/myTool.conf"."f+".argument = "my_config";
"%h/.config/myToolPurged.conf"."f+$".argument = "my_config_purged";
};
purgeOnChange = true;
};
};
nmt.script = ''
cacheRulesFile=home-files/.config/user-tmpfiles.d/home-manager-cache.conf
assertFileExists $cacheRulesFile
assertFileRegex $cacheRulesFile "^'d' '%C' '-' '-' '-' '4 weeks' $"
assertPathNotExists home-files/.config/user-tmpfiles.d/home-manager-myTool.conf
myToolRulesFile=home-files/.config/user-tmpfiles.d/home-manager-purge-on-change.conf
assertFileExists $myToolRulesFile
assertFileRegex $myToolRulesFile \
"^'f+' '%h/.config/myTool.conf' '-' '-' '-' '-' my_config$"
assertFileRegex $myToolRulesFile \
"^'f+$' '%h/.config/myToolPurged.conf' '-' '-' '-' '-' my_config_purged$"
'';
}