>I like how Nix obsoletes a lot of what Puppet&co are all about, and does so in a very straight forward manner.
I like that a lot, too. It's a great example of taking a step back, examining a problem from a different perspective, and coming up with a better, simpler solution than the current state of the art.
It would be awesome to see a Nix package manager module for puppet, saltstack, ansible, chef & co.
I think that for package installation and rollback, a simple model like that proposed by DJ Bernstein with slashpackage http://cr.yp.to/slashpackage.html seems to accomplish the same goals but with much less complexity.
I just started reading about Nix, do you have some good resources to suggest me on the provisioning in puppet/saltstack/... like scenario? What advantages, how it does things differently... Thanks
Edit: I ask because I understand it's a package manager so I find comparisons to other package managers, but not to provisioning systems
After using Nix and NixOps, my sense was that a Nix package manager module for puppet&co would be really really useful. With NixOps, my concern was that I need to have a trusted OS, and I didn't feel comfortable having to use a custom build of something Ubuntu-ish.
Maybe there's a way to convert or bootstrap any Linux OS into a NixOps-compatible distro. But I didn't see anything.
Nix packages live in isolated directories on a read-only filesystem and their build process is repeatable (usually; any exceptions are bugs!). This means that installing a Nix package will always give you the same result, and that result cannot be interfered with afterwards. Since everything's isolated and read-only, changes are transactional.
For example, let's say package A v1.0 is using some dependency B v3.0:
B v3.0 --> A v1.0
Let's say we want to update B to v3.1. Since the packages are read-only, we can't touch any of B's files at all. Instead, B v3.1 gets installed alongside the existing v3.0. A v1.0 doesn't notice, since it's still using v3.0:
B v3.0 --> A v1.0
B v3.1
We want A v1.0 to use this new version of B, but again we can't touch any of its files. Instead, we install another copy of A v1.0 which uses B v3.1 as a dependency. Again, since they're isolated these two copies of A v1.0 won't interfere with each other:
B v3.0 --> A v1.0
B v3.1 --> A v1.0
So, how does the system know which copy of A to use? Firstly, Nix identifies packages by hashing them and their dependencies, which is why we can have two A v1.0 packages (there's no unnecessary duplication; we only get two copies when something's different). Secondly, each user has a "profile" listing which packages they want. So what's a profile? It's just another package. When you "install" a package, you're actually just creating a new version of your profile package, which has different dependencies than the old version. Hence, a more complete version of the above diagram would be:
B v3.0 --> A v1.0 --> chris-profile-1
B v3.1 --> A v1.0 --> chris-profile-2
We can easily rollback changes by using a previous version of our profile package (it's not even a "rollback" really, since the new profile is still there if we want it). To reclaim disk space we can do a "garbage collection" to get rid of old profile packages, then clean out anything which isn't in the dependency graph of any remaining profile package.
To get two machines into the same state (the use-case of Puppet and friends), we just need to install the same profile package on each. There's a Linux distro called NixOS which uses Nix to manage all of its packages and configuration.
In fact, since we can install multiple profile packages side-by-side, we can use profiles as a poor man's container. They don't offer strong protection, eg. in a shared hosting environment, but from a sysadmin perspective they give us some of the non-interference advantages (eg. no dependency hell, since there are no package conflicts or version-unification difficulties).
If we want a stronger containment system we can use NixOps, which gives Nix packages a Vagrant-like ability to provision and spin-up real or virtual machines, EC2 instances, etc. For example, we might have a "DB server" package.
If we want to orchestrate these services, we can turn them into Nix packages using DisNix; then we can have packages like "Load Balancer" which depends on "Web Server", which in turn depends on "Users DB".
I have to admit I've not used NixOps or DisNix, but I do use NixOS as my main OS and have grown to love it :)
Whelp.. I've been seeing a lot about Nix on and off for the last year or so, and looked at it once or twice, but never quite got why it was compelling. Now I see... time to go investigate.
I recommend copypasta-ing this to an FAQ associated with Nix!
It's these simple solutions that make me tick :)