Live data from Hacker News

Nix solves the package manager ejection problem

zeroindexed.com

31–40 of 50 posts

Re: Nix solves the package manager ejection problem

#31
post #29
post #16

Earlier quoted context omitted.

Nix doesn't work by redirecting symlinks, much less between different versions of the same package. So there is no race condition as you describe. Simply, if package A depends on package B then A's files will end up mentioning the absolute path to B directly (say, /nix/store/abcdef-b-1.0/bin/some-bin-file, where "abcdef" is a hash). If package C depends on a different version of package B, then C's files will contain…

Thanks, let me clarify my question with a proper example. Let's say I install A-1.0 and A-1.1. Both versions will depend on say a resource file they expect is at /usr/share/A.res I was thinking that nix would symlink /bin/A -> /nix/store/abcdef-A-1.0/bin/A, and also /usr/share/A.res -> /nix/store/abcdef-A-1.0/usr/share/A.res So when I'm upgrading to A-1.1, maybe the /bin/A symlink would update a moment before the /us…

So, in Nix (and in NixOS) there is no /bin and there is no /usr/share.

So either A.res gets installed at /nix/store/abcdef-A-1.0/share/A.res and at /nix/store/xyw123-A-1.1/share/A.res, in case A.res is part of A, or, if it's considered a dependency, then it gets installed at /nix/store/jgh456-some-other-package-2.3/share/A.res which both A-1.0 and A-1.1 depend on.

Also, A-1.0 and A-1.1 may depend on exactly the same "some-other-package" or they may depend on different versions, which would be OK since the hash of some-other-package will be different for different versions (or different variations of the same version), so there would never be a conflict.

As other posters mentioned, there is something called a user profile (and a system profile for NixOS) which does contain symlinks to the final binaries that are supposed to be in $PATH for some user (or all users, in the case of the system profile).

But these are only symlinks to the top-level binaries. The binaries themselves (and all their dependencies, including data and other binaries) contain hardcoded paths, they don't get redirected through symlinks. So once the top-level symlink gets resolved by your shell, everything is hardcoded from then on, no package sees some half-between state of their data or their dependencies' data or binaries.

You could even have multiple versions of the same package running at the same time without any conflict, as long as their mutable data is stored in different directories. For example, you can have different versions of Firefox running at the same time, as long as they use different Firefox profiles (if you try to run the same Firefox profile with different versions of Firefox at the same time, the second Firefox will complain that it is already running, as it should -- this is not very different from trying to run the same program twice at the same time).

And also, these user profiles are themselves updated/modified atomically through a single symlink, so your effective $PATH is either the old one or the new one, but never anything in-between.

PS: to answer your question, yes, we do indeed make sure that binaries know to look for resources in the right place.

Rather than look for the files relative to their path, usually packages have a "./configure" script which allows someone to tell where to install resources such as data files, man pages, etc. Usually people install resources in /usr/share or /usr/local/share (or even $HOME/share in some cases). In Nix, we just tell the package to install their files in /nix/store/abcdef-A-1.0/share and binaries will usually know where to find these resources based on the path provided to ./configure (and if for some reason they don't, we do patch source files to make sure that they do).

Re: Nix solves the package manager ejection problem

#32
post #31
post #29

Earlier quoted context omitted.

Thanks, let me clarify my question with a proper example. Let's say I install A-1.0 and A-1.1. Both versions will depend on say a resource file they expect is at /usr/share/A.res I was thinking that nix would symlink /bin/A -> /nix/store/abcdef-A-1.0/bin/A, and also /usr/share/A.res -> /nix/store/abcdef-A-1.0/usr/share/A.res So when I'm upgrading to A-1.1, maybe the /bin/A symlink would update a moment before the /us…

So, in Nix (and in NixOS) there is no /bin and there is no /usr/share. So either A.res gets installed at /nix/store/abcdef-A-1.0/share/A.res and at /nix/store/xyw123-A-1.1/share/A.res, in case A.res is part of A, or, if it's considered a dependency, then it gets installed at /nix/store/jgh456-some-other-package-2.3/share/A.res which both A-1.0 and A-1.1 depend on. Also, A-1.0 and A-1.1 may depend on exactly the same…

Ah thank you SO much, this is extremely helpful. I really appreciate you taking the time to explain that!!

Re: Nix solves the package manager ejection problem

#33

How do NixOS users typically manage software that is not a Nix package, like a source code tarball where you would traditionally run configure && make && make install?

You write some Nix code to download said tarball and build it as you said. In fact, the ever present `mkDerivation` often Just Works for autotools and cmake projects.

Re: Nix solves the package manager ejection problem

#35
post #30

So, how does Guix compare to Nix in 2021 for the average user (who does not want to spend all their time on package management)?

Basic commands in guix are simpler, last I compared them. "guix install", "guix upgrade", etc. These are equivalent to longer guix package commands like "guix package -i" and "guix package -u". I recall nix's package install command being odd, something like "nix-env -ia". Package names in guix are very consistent, lowercase and hyphen-separated. I recall some nix packages having capital letters in them. It could cer…

This has been my experience, too. Granted, I have used guix longer than Nix.

Another advantage of Guix is just how readable package definitions are. Nix packages often contain embedded shell code + a "functional" DSL. Guix packages are written in a much more declarative style. It kind-of looks like executable JSON (I guess that's the point of lisp, right?).

Re: Nix solves the package manager ejection problem

#36
post #30

So, how does Guix compare to Nix in 2021 for the average user (who does not want to spend all their time on package management)?

Basic commands in guix are simpler, last I compared them. "guix install", "guix upgrade", etc. These are equivalent to longer guix package commands like "guix package -i" and "guix package -u". I recall nix's package install command being odd, something like "nix-env -ia". Package names in guix are very consistent, lowercase and hyphen-separated. I recall some nix packages having capital letters in them. It could cer…

FWIW, on NixOS, you can use buildEnv in a .nix file to have your user environment be completely declarative. I discovered this before I discovered home-manager and it's still what I use.

Re: Nix solves the package manager ejection problem

#37
post #6

That works for the kernel. But if you have to patch, say, glibc, under Nix doesn't that mean you can no longer use precompiled binaries, and have to recompile every single package that uses libc, from source? Sure, it still works. And in the off-chance that you need to make a patch that changes the ABI, recompiling the world is exactly what you want. But usually you don't need to change the ABI (at least not in a bac…

Nix has a facility for patching libraries without recompiling the world (the intended use case was for novel zero-days where waiting for hydra to rebuild the world was unacceptable). All I know about it is that I've heard it exists though.

Re: Nix solves the package manager ejection problem

#38

So, how does Guix compare to Nix in 2021 for the average user (who does not want to spend all their time on package management)?

Feature-wise, there's no fundamental difference. All of it boils down to a matter of taste.

But in terms of support, I must say Nix is currently ahead of Guix. It has a large quantity of packages that surpasses any other distros[1], (almost) all of which goes through review. It also has support for non-Linux platforms, namely macOS and BSDs. The community is large and active, and there are various avenues which you can reach out for help.

So if you're interested in either but don't know which to choose, I'd recommend Nix. If you're feeling adventurous and also like Scheme, Guix would be the way to go.

[1]: https://repology.org/repositories/graphs

Re: Nix solves the package manager ejection problem

#39

Read the NPM doc but I still don't understand what "ejection" is. What are we ejecting? Can someone explain this please?

> What are we ejecting?

Ourselves, it seems. A Javascript framework is like a jet, and we are the human payload. You can stay in the jet, zooming over the constantly changing landscape. But if you get tired of this zooming around (or if you get scared of hitting a mountain), then you can activate the ejection seat (https://en.wikipedia.org/wiki/Ejection_seat). Of course, now you're a mile high without a plane, but the ejection-seat comes with a parachute, so the descent will be pleasant (or, at least, non-fatal - which is a style of pleasantness).

Erm, wait, I think you were soliciting a more literal answer. :)

"create-react-app" is the Javascript framework/jet. If you want to go for the ride, then you declare a single-dependency on "create-react-app", and they will decide when/what/how to upgrade components in the framework. If you don't want to ride along with "create-react-app"s framework, then you "eject". They'll give you a little bundle (the concrete list of dependencies) and send you off on your way.

Re: Nix solves the package manager ejection problem

#40

Read the NPM doc but I still don't understand what "ejection" is. What are we ejecting? Can someone explain this please?

> What are we ejecting? Ourselves, it seems. A Javascript framework is like a jet, and we are the human payload. You can stay in the jet, zooming over the constantly changing landscape. But if you get tired of this zooming around (or if you get scared of hitting a mountain), then you can activate the ejection seat ( https://en.wikipedia.org/wiki/Ejection_seat ). Of course, now you're a mile high without a plane, but…

LOL, best answer so far!
Post reply on HN