nixos/locatedb: fix first run when /var/cache doesn't exist by using systemd-tmpfiles. Also document what's happening there.

+10 -2
+10 -2
nixos/modules/misc/locate.nix
··· 125 125 warnings = optional (isMLocate && cfg.localuser != null) "mlocate does not support searching as user other than root" 126 126 ++ optional (isFindutils && cfg.pruneNames != []) "findutils locate does not support pruning by directory component" 127 127 ++ optional (isFindutils && cfg.pruneBindMounts) "findutils locate does not support skipping bind mounts"; 128 - 128 + 129 + # directory creation needs to be separated from main service 130 + # because ReadWritePaths fails when the directory doesn't already exist 131 + systemd.tmpfiles.rules = [ "d ${dirOf cfg.output} 0755 root root -" ]; 132 + 129 133 systemd.services.update-locatedb = 130 134 { description = "Update Locate Database"; 131 135 path = mkIf (!isMLocate) [ pkgs.su ]; 132 136 script = 133 137 '' 134 - mkdir -m 0755 -p ${dirOf cfg.output} 135 138 exec ${cfg.locate}/bin/updatedb \ 136 139 ${optionalString (cfg.localuser != null && ! isMLocate) ''--localuser=${cfg.localuser}''} \ 137 140 --output=${toString cfg.output} ${concatStringsSep " " cfg.extraFlags} ··· 148 151 serviceConfig.PrivateNetwork = "yes"; 149 152 serviceConfig.NoNewPrivileges = "yes"; 150 153 serviceConfig.ReadOnlyPaths = "/"; 154 + # Use dirOf cfg.output because mlocate creates temporary files next to 155 + # the actual database. We could specify and create them as well, 156 + # but that would make this quite brittle when they change something. 157 + # NOTE: If /var/cache does not exist, this leads to the misleading error message: 158 + # update-locatedb.service: Failed at step NAMESPACE spawning …/update-locatedb-start: No such file or directory 151 159 serviceConfig.ReadWritePaths = dirOf cfg.output; 152 160 }; 153 161