NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
12.19k stars 1.47k forks source link

Declarative env management with nix profile is too hard #11544

Open dukc opened 1 day ago

dukc commented 1 day ago

Describe the bug

So, I'm wanting to migrate my personal Nix configurations to flakes. I figured out that since the new-gen nix commands are needed to understand flakes, I should migrate my commands before I start rewriting my .nix files.

I'm managing my user environment declaratively, pretty much how the NixPkgs manual suggests except I put the buildEnv derivation as the top-level expression of the file. By running nix-env -irf file.nix the user environment gets rebuilt transactionally in a single step, just like NixOS gets with sudo nixos-rebuild switch.

Now, turns out the experience of trying to do the same with nix profile is subpar. First off, I can't do it transactionally with one command. I have to write nix profile remove '.*' followed by nix profile install -f file.nix.

If I try writing a bash script to automate this there's another problem. If the installation of the new profile fails, I want to roll back. But how is the script supposed to know what profile number to roll back to? There is no (documented) command to query the number of the current profile before the remove command. nix profile history indicates the current generation only by colour of the profile number in question.

Maybe with enough bash-fu I could extract the coloured number but frankly, this is way too hard. Unless I'm mistaken, I should be able to use nix profile as a drop-in replacement for nix-env. This is pretty far from it.

nix-env --version output nix-env (Nix) 2.18.5

dukc commented 1 day ago

download [shady link] I put the necessary dlls in the archive

This comment is some sort of automated spam. It appeared literally the same second I published this issue so there's no way it's a genuine reply.

Do not follow the link!!

roberth commented 1 day ago

I've reported it.

UPDATE: GitHub has removed the spam comment

dukc commented 1 day ago

:+1: I also did.

roberth commented 1 day ago

Can this be made to work with nix profile upgrade?

The documentation is rather flake-oriented, but does list -f/--file as an option.

dukc commented 1 day ago

I did experiment with nix-env -u --leq before migrating, figuring that if that works nix profile upgrade would work too and vice-versa. it didn't work.

Probably it would work with some change to my overall scheme, but it's clearly not very easy way to go either as I have no idea what precisely I would have to change.

dukc commented 1 day ago

The documentation is rather flake-oriented, but does list -f/--file as an option.

I can confirm the -f option does work, and therefore nix profile is at least usable. But I can't upgrade my whole profile transactionally in one go like I can with nix-env.

edolstra commented 1 day ago

If your profile consists of only one buildEnv derivation, you're probably better off using nix build --profile /path/to/profile --file file.nix.

dukc commented 1 day ago

Huh, I can set my profile with nix-build/nix build? I'd certainly have tried if I knew! I'll try.

dukc commented 1 day ago

Doesn't seem to work. I removed one package from my file.nix and ran nix build --profile $NIX_USER_PROFILE_DIR -f file.nix.

It said no priviledge to do so. That's already bad, I shouldn't need super user priviledges to change my own user environment. Still, i attempted the same command with sudo, and it didn't do anything. Am I doing something wrong?

dukc commented 1 day ago

Never mind! the correct command was nix build --profile ~/.local/state/nix/profiles/profile -f file.nix, works and without sudo as it should. Thanks!

So my problem is solved. The question remains though whether it's easy enough for the user to figure out s/he should be looking at nix build instead of nix profile, especially since there doesn't seem to be a similar --profile option for the old-school nix-build.

roberth commented 1 day ago

Too hard IMO. Is anything stopping us from making nix profile upgrade just work for --file?

dukc commented 10 hours ago

I think updating relies on fetching the new derivation from the same flake spec as the old one was fetched. In this case though we don't have a flake spec. We only have a local .nix file, which might be even moved or renamed since the last generation, so nix profile upgrade can't know the derivation in file.nix is new version of the file.nix of the previous generation.

I'm pretty sure the user could make some sort of a shim flake that would refer to the file.nix as a flake spec, so that the update command would match the derivations. But that's something that's also hard to figure out if the documentation doesn't provide an example how to do it, especially considering someone using these commands the first time can't know much about flakes yet.

What would work IMO is if nix profile would let to install and remove packages with the same invocation.