nix icon indicating copy to clipboard operation
nix copied to clipboard

Use envvars NIX_CACHE_HOME, NIX_CONFIG_HOME, NIX_DATA_HOME, NIX_STATE_HOME if defined

Open noamraph opened this issue 1 year ago • 6 comments

Motivation

Currently Nix uses the XDG environment variables XDG_{CACHE,CONFIG,DATA,STATE}_HOME for locating files. I suggest to also look for environment variables NIX_{CACHE,CONFIG,DATA,STATE}_HOME, and if they exist, use them instead of the XDG_* ones.

This allows more fine-grained control over where Nix looks for files. This allows to have a stand-alone Nix environment, which only uses files in a specific directory, and doesn't touch any global user configuration. Specifically, this makes Nixsa possible, a project I'm working on, which allows you to extract a tarball and immediately get a standalone working Nix environment.

Context

A detail: Nix always uses the nix directory inside the XDG_*_HOME variables (for example, the profile is at $XDG_STATE_HOME/nix/profile, the configuration is at $XDG_CONFIG_HOME/nix/nix.conf). If NIX_*_HOME is defined, there's no point in adding /nix to it.

This means that this PR can be split into two simpler commits (let me know if you want me to modify it): one commit which is pure refactoring, which makes the get*Dir() functions return directories ending with /nix, and a second commit which makes the get*Dir() functions first look for a NIX_*_HOME envvar.

I don't see any backwards-compatibility issues with this change, since if the NIX_*_HOME envvars don't exist the behavior doesn't change.

Priorities and Process

Add :+1: to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

noamraph avatar Aug 21 '24 17:08 noamraph

Why does Nixsa need separate variables for this? Can it not substitute in a wrapper for nix that sets the XDG_ variables for that process?

rhendric avatar Aug 22 '24 22:08 rhendric

Why does Nixsa need separate variables for this? Can it not substitute in a wrapper for nix that sets the XDG_ variables for that process?

I think it will basically work, however the problem is that Nix can run other commands, certainly when using nix run, and the XDG envvars will be inherited by the child process.

noamraph avatar Aug 22 '24 22:08 noamraph

I'm not sure if _HOME is the right suffix here. I think _HOME in XDG is meant to refer to a replacement of the role $HOME used to play for dotfiles. Notably these environment variables that have in common that they are generic locations where each application is expected to pick a subdirectory name, but NIX_*_HOME variables do not have this subdirectory behavior. Perhaps it should just be _DIR instead of _HOME?

Could you document these environment variables in doc/manual/src/command-ref/env-common.md?

roberth avatar Aug 23 '24 09:08 roberth

I'm not sure if _HOME is the right suffix here. I think _HOME in XDG is meant to refer to a replacement of the role $HOME used to play for dotfiles. Notably these environment variables that have in common that they are generic locations where each application is expected to pick a subdirectory name, but NIX_*_HOME variables do not have this subdirectory behavior. Perhaps it should just be _DIR instead of _HOME?

Could you document these environment variables in doc/manual/src/command-ref/env-common.md?

Thanks for the suggestion, it makes a lot of sense.

It's such a good suggestion, that it raises a question. I looked at env-common.md and it mentions NIX_CONF_DIR , NIX_DATA_DIR, and NIX_STATE_DIR (3 of the 4 suggested new variables, ignoring the difference between CONF and CONFIG). If those envvars are not set, they are taken to be /nix/etc/nix, /nix/share, /nix/var/nix. But I still don't understand how they relate to how nix uses XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_STATE_HOME. Are they only used when Nix is run as root, or when use-xdg-base-directories is not set?

noamraph avatar Aug 23 '24 11:08 noamraph

@roberth Ok, I dug a bit in the code. From what I see, NIX_STATE_DIR and NIX_CONF_DIR are used for various things, treating them as being global for the system. NIX_STATE_DIR is also used only for the root user to get the profiles directory. I didn't see any uses of NIX_DATA_DIR, it seems to have no effect.

So, I don't want to touch NIX_STATE_DIR and NIX_CONF_DIR.

Therefore, I don't think that the suffix _DIR can work, since it's already used for something else.

I still think that the _HOME suffix is a reasonable choice, as it makes the relation to the XDG_*_HOME envvars clearer, and since the default is really in the home dir.

Another alternative can be NIX_USER_CACHE_DIR, NIX_USER_STATE_DIR etc, to differentiate those envvars from the system ones.

What do you think?

noamraph avatar Aug 23 '24 12:08 noamraph

I didn't realise the names collided. Sorry for the red herring.

NIX_USER_CACHE_DIR

Also reasonable. I think I'm fine with either of your proposed naming schemes.

roberth avatar Aug 24 '24 21:08 roberth

@roberth sorry it took me so long. I updated env-common.md with a description of the NIX_*_HOME envvars.

What are the next steps?

Thanks!

noamraph avatar Sep 09 '24 15:09 noamraph

@fricklerhandwerk Thanks! I committed your suggestions, they improve my text. I added a changelog. How does it look?

noamraph avatar Sep 11 '24 08:09 noamraph

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/nix-2-25-released/55994/1

nixos-discourse avatar Nov 13 '24 14:11 nixos-discourse