Use only 1 channel for my user's `nix-env` and root's `nixos-rebuild`

With the nixpkgs channel I had from before, I get 1 update. Maybe that’s a sign of that small gap between nixos-unstable and nixpkgs-unstable… Meaning it’s OK that nix-env --upgrade think there’s nothing to upgrade.

(EDIT) Moreover, I’m trying to investigate while at it, the issue of multiple search results in nix search - Why now, even with only 1 channel for root and no channels for myself, I get 3 search results from 3 channels:

* nixos-unstable.blender (blender)
  3D Creation/Animation/Publishing System

* nixos.blender (blender)
  3D Creation/Animation/Publishing System

* nixpkgs.blender (blender)
  3D Creation/Animation/Publishing System

Here’s are the files in ~/.nix-defexpr/:

$ tree ~/.nix-defexpr/*
/home/doron/.nix-defexpr/channels
├── binary-caches -> /nix/store/n8q83dx47i6n562l9q23ppf2c92i0112-nixos-unstable-19.09pre186563.b5f5c97f7d6/binary-caches
├── manifest.nix -> /nix/store/fshsa1v74jv8b9ssjnq1yf783lfdissg-env-manifest.nix
└── nixos-unstable -> /nix/store/n8q83dx47i6n562l9q23ppf2c92i0112-nixos-unstable-19.09pre186563.b5f5c97f7d6/nixos-unstable
/home/doron/.nix-defexpr/channels_root
├── manifest.nix -> /nix/store/g8kvv93976mzsmmvcgln1kmj5kqn6dv0-env-manifest.nix
└── nixos -> /nix/store/i3a8qpsc117i3sbj0mafnsq8dv730zfp-nixos-20.09pre217261.a2e06fc3423/nixos

3 directories, 2 files

not sure if you talk about user profile or root profile. Because default-5-link is root profile, that is sudo nix-env -i .... It might be you rarely install anything as root.

The nixos-unstable channel looks like a bug. It should have been removed by nix tools… But duplication nixos/nixpkgs is kinda expected - I believe this is an old bug.

Makes sense.

The nixos-unstable channel looks like a bug. It should have been removed by nix tools… But duplication nixos/nixpkgs is kinda expected - I believe this is an old bug.

I see. Say @danbst I’d like to file a bug in Issues · NixOS/nix · GitHub , where should I start? What info is relevant? Should I tell them my $NIX_PATH as well? It is set by /etc/set-environment as generated by my NixOS config… Currently:

$ grep NIX_PATH /etc/set-environment
export NIX_PATH="nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels"
  export NIX_PATH="$HOME/.nix-defexpr/channels${NIX_PATH:+:$NIX_PATH}"

I think I’ve fixed the duplicate search results issue in nix search by using the following:

NIX_PATH=nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos

Otherwise, it’s:

NIX_PATH=$HOME/.nix-defexpr/channels:nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels

But if then, what’s the purpose of the rest of the paths set there? Could it be merely a $NIX_PATH default value issue of NixOS/nixpkgs ?

$HOME/.nix-defexpr/channels lets you use <channelname> to refer to user channels you got from nix-channels, and /nix/var/nix/profiles/per-user/root/channels also does that but lets regular users use root’s channels, that is those configured with sudo nix-channels. nixos-config=/etc/nixos/configuration.nix lets nixos-rebuild, nixos-options etc. find the configuration file.

Thanks for joining the discussion @dramforever .

My nixos-config= has:

/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels

What’s the purpose of /nix/var/nix/profiles/per-user/root/channels there?

It does not. $NIX_PATH is several ‘things’ separated by :, and each ‘thing’ is either path or name=path. Please see my earlier reply again for what /nix/var/nix/profiles/per-user/root/channels does, and also the relevant section in the Nix manual.

OK I think I start to get it. Overall, all the paths that don’t include something= in my NIX_PATH are:

$HOME/.nix-defexpr/channels

And:

/nix/var/nix/profiles/per-user/root/channels

And <channelname> channels are looked up there right? If so, why is this:

nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos

is also set?

It allows <nixpkgs> to refer to the nixos channel

OK :).

Damn! Why is this has to be so complicated? My conclusion, is that I could get along just fine with only:

NIX_PATH=nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix

Do you think @dramforever I’d miss something with this $NIX_PATH? Would I have trouble if I’d want to use all kinds of default.nix files in development repos that use import <channelname>?

Actually IIRC the default configuration is exactly what you described in your original post title: only 1 channel for user nix-env and system nixos-rebuild. If the user doesn’t configure any channels, root’s ones are used. You didn’t really have to do anything :slight_smile:.

$NIX_PATH is like that because nix-channel is a completely separate mechanism. It would actually complicate things if in Nix <foo> referred to some ‘channel’ mechanism rather than just a path configured by an environment variable.

As of your NIX_PATH, I don’t see a problem. If it’s working for you then it’s most likely fine. The only NIX_PATH you can expect existing from most installations is <nixpkgs> anyway, so I think it’s okay.

you may also be interested in How is `NIX_PATH` managed regarding nix channel? - #3 by danbst

I agree with you it is all complicated. I think this is one of reasons why nix-channel and nix-env were not ported to Nix2, and why all this flakes + flake locks stuff is going on. So maybe don’t report a bug, but let’s just wait until flakes+nix2 stabilize.

My default $NIX_PATH includes paths without a something= and I think that’s what caused the multiple search results in nix search. As for the original issue of this thread, I can testify that currently:

$ nix-channel --list

Outputs nothing but:

$ ls -l ~/.nix-defexpr/channels/
total 12
lrwxrwxrwx 2 root root  99 Jan  1  1970 binary-caches -> /nix/store/n8q83dx47i6n562l9q23ppf2c92i0112-nixos-unstable-19.09pre186563.b5f5c97f7d6/binary-caches
lrwxrwxrwx 2 root root  60 Jan  1  1970 manifest.nix -> /nix/store/fshsa1v74jv8b9ssjnq1yf783lfdissg-env-manifest.nix
lrwxrwxrwx 2 root root 100 Jan  1  1970 nixos-unstable -> /nix/store/n8q83dx47i6n562l9q23ppf2c92i0112-nixos-unstable-19.09pre186563.b5f5c97f7d6/nixos-unstable

Maybe that’s the bug @danbst talked about in post #5? I expect the nixos-unstable directory not to be there.

That’s definitely helpful @danbst . It’ll take me some time though to get my head wrapped around it along @tohl2’s suggestion. What perplexes me the most is the fact that nix-env doesn’t care about $NIX_PATH. That’s pretty insane. Hence I’m considering:

alias nix-env='nix-env -f <nixpkgs>'
1 Like

Yes this does not look right to me. If you can cause this without doing anything funny like editing ~/.nix-channels by hand then it’s a bug. If you did do something funny though, you might consider it a bug but I guess you’re supposed to clean up after yourself…

alias is a nice trick! I’ve just tested and you can specify -f twice, so nix-env -if ... will not be broken

nix-env -f '<nixpkgs>' -f '<nixpkgs>' -iA hello

Actually, this is great news!

Actually that didn’t work out for me :upside_down_face: - something went wrong with zsh evaluating the brackets first. I’ve currently settled down with using:

ln -s /nix/var/nix/profiles/per-user/root/channels .nix-defexpr

I’ve done that after reading Introduction - Nix Reference Manual . Because of this. I’ll never use nix-channel --update again. Only nixos-rebuild --upgrade.

My $NIX_PATH is currently set to:

NIX_PATH=nixos=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix

I suppose it could be set via nix.nixPath (as @tohl2 suggested):

In the current state:

  • I don’t get duplicate search results from nix search and only the nixos. attribute prefix is used in it’s results.
  • nix-env -qa --json is showing only nixos. attributes which are all derived from the packages defined in /nix/var/nix/profiles/per-user/root/channels/nixos.
  • command-not-found is using the nixos. attribute to instruct how to install a package.

I’m satisfied by this setup.

isn’t nix-build '<nixpkgs>' -A ... broken now for you? Something like nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos is still required.

You are right @danbst, and many development repos that use a default.nix with import <nixpkgs> or alike are broken as well. I’m still not sure how to workaround this while keeping the 3 bullet points I desired in my solution post. In the meantime, at least for projects that use direnv, I have:

NIX_PATH=nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos

In my ~/.config/direnv/direnvrc.

(EDIT) TBH I almost never use nix-build not inside my nixpkgs clone, so it’s not such a big deal for me. However, I think I could do the following instead:

mkdir ~/.nix-defexpr
ln -s /nix/var/nix/profiles/per-user/root/channels/nixos ~/.nix-defexpr/nixpkgs

And set:

NIX_PATH=nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix

But in the meantime I’m more satisfied with the shorter nixos. attribute prefix.

I would rather recommend this:
nix.nixPath = [“nixpkgs=${toString pkgs.path}”];

because it takes less time and space:

$ echo $NIX_PATH
nixpkgs=/nix/store/3c7fs73pbrgg9lw9dj8dzvg0zw0wrlsm-nixpkgs-patched

$ time nix-instantiate --eval --expr ‘“${(import {}).path}”’
“/nix/store/dw3c31d3cgr79la1mby3h1ygk05wkzxx-3c7fs73pbrgg9lw9dj8dzvg0zw0wrlsm-nixpkgs-patched”
real 0m1,689s
user 0m0,555s
sys 0m1,125s

nix $ time nix-instantiate --eval --expr ‘“${toString (import {}).path}”’
“/nix/store/3c7fs73pbrgg9lw9dj8dzvg0zw0wrlsm-nixpkgs-patched”
real 0m0,179s
user 0m0,139s
sys 0m0,034s

Turns out this was a bad idea, please DO NOT use ${toString pkgs.path} but use ${pkgs.path}:
it makes sense only if you’re using a Nixpkgs which is already in the /nix/store/ like myself
(so if you’re using a git clone of Nixpkgs in your home directory,
your Nixpkgs won’t be included in the Nix store),
and you need to hack your way (eg. environment.systemPackages = [pkgs.path];)
to somehow register this path as a dependency of your built system
(without copying it a second time in the /nix/store which would defeat the purpose of the hack),
otherwise that store path can be garbage collected and won’t actually even be sent to the target host
if you’re using nixops.

Sorry for the wrong advice.

PS: lib/tests/release.nix does use ${toString pkgs.path} but also ${pkgs.path} in the same derivation.