Create directory with `environment.etc`?

According to this review message, I need to create a directory in /etc: nixos/crowdsec: use sensible defaults by TornaxO7 · Pull Request #446307 · NixOS/nixpkgs · GitHub

If I look up how to use environment.etc, I’m not seeing any option to create directories in /etc, only files.
What would you recommend to do to create a directory in /etc with environment.etc or should I rather use systemd.tmpfiles.settings for this?

First of all, hopefully you’ve exhausted the possibility of not putting config in /etc, but instead passing a /nix/store path as a config file location to whatever program is being configured.

Second, hopefully you don’t need to create an empty directory in /etc.

With those caveats out of the way: you need to put a file in /etc, but not in the top level of /etc. This is done as follows:

  # Creates /etc/directory_name/file_name with the given contents
  environment.etc."directory_name/file_name".text = "...";

Any number of parent directories will be created automatically.

First of all, hopefully you’ve exhausted the possibility of not putting config in /etc, but instead passing a /nix/store path as a config file location to whatever program is being configured.

My current idea is, to put paths in the config file which do point to /etc but those files will be symlinks to /nix/store. So I’d say

Second, hopefully you don’t need to create an empty directory in /etc.

It seems like so. At least that’s how I understand this comment.

With those caveats out of the way: you need to put a file in /etc, but not in the top level of /etc. This is done as follows:

  # Creates /etc/directory_name/file_name with the given contents
  environment.etc."directory_name/file_name".text = "...";

Any number of parent directories will be created automatically.

Alright, thank you

Why not just point to the store path directly? The /etc is a waste at that point IMO.

I changed that now: Some paths in the config file are going to point to the /nix/store files directly now.

If I use your approach I can’t set the owner (which is root as the default) and the mode but I need both.

What did you try?

I added the following config:

  environment.etc."crowdsec/some-random-file.txt" = {
    user = "crowdsec";
    group = "crowdsec";
    mode = "0750";
    text = "Hello there";
  };

which creates /etc/crowdsec/some-random-file.txt with the correct owner (crowdsec) and mode (0750) but
the parent directory /etc/crowdsec has the owner root and the mode 0755.

The most straightforward way IMO would be to use a tmpfiles rule to create the parent dir. (systemd.tmpfiles.settings)

2 Likes