Nixpkgs' policy as for Systemd prestart setup scripts vs Systemd tmpfiles

Some modules / services in Nixpkgs which go along with a Systemd service, set up certain directories (usually in /var/) for the services to be able to use when running. Usually this is done using PreStart or in Nix:

systemd.services.<name>.prestart = ''
  mkdir /var/lib/this and that
  chmod this to that
''

Sometimes, these scripts force settings / permissions a user wouldn’t necessary be comfortable with. An example of a discussion demonstrating this kind of debate is in https://github.com/NixOS/nixpkgs/pull/76552 .

An idea come up during it which reminded me of the classic and more settled way of doing such a setup: Using systemd tmpfiles which are somewhat supported in Nixpkgs’ options. I’m not yet experienced enough with it but git grep suggests many services use it but that the prestart approach is more common.

Perhaps in order to encourage services maintainers to use tmpfiles, we could improve it by making it more expressive. Perhaps it’s usage may go like this:

systemd.tmpfiles.rules = {
	"/var/lib/servicehome" = {
		type = "d";
		mode = "0775";
		user = "service-daemon";
		group = "admins";
		age = "";
		argument = "/dev/null";
	};
};

This way a user using a service which set up such a tmpfiles directory may override only the relevant part with e.g:

systemd.tmpfiles.rules."/var/lib/servicehome".mode = "0770";

BTW while I read tmpfiles.d(5) I noticed the vast support for all kinds of configurations which a mere script may do less reliably and in a harder to configure way IMO.

I would like to hear your opinions and maybe I’ll raise an RFC in Nixos/rfcs.

1 Like

Dozens upon dozens of services have been converted to use tmpfiles instead of preStart. Ideally you will use StateDirectory and friends, but when that is not possible tmpfiles is (my) preferred method, and I think generally accepted as a good solution.

I like your idea. @arianvp is actually working on something like this already. Maybe he’ll comment.

1 Like

So there is a move towards using a better approach other then preStart scripts. Nice :slight_smile: Yet it could be better if it was done more formally.

I noticed many services use such a configuration option but it seems they just handle the implementation of it themselves using preStart

StateDirectory automatically provisions directories for you, so if there is a service which is using StateDirectory and using mkdir to create the same folder this is likely a mistake. Do you have an example of this?

Yes, see https://github.com/NixOS/nixpkgs/blob/52a4fd27adf02987467b4afb8b2c3675cb13b51a/nixos/modules/services/web-servers/apache-httpd/default.nix#L687 .

See https://github.com/NixOS/nixpkgs/blob/14e842ec021ea18618f893fea8e7ce332f858a4a/nixos/modules/services/web-servers/apache-httpd/default.nix#L713 and https://github.com/NixOS/nixpkgs/blob/14e842ec021ea18618f893fea8e7ce332f858a4a/nixos/modules/services/web-servers/apache-httpd/default.nix#L686 for fixed version :slight_smile:

1 Like