5 ms·
Author here. Thanks for the clarification! I'm still new to Nix, so I'm trying to share useful things I'm learning without overstepping my expertise and saying
by mtlynch 3y ago
Author here.
Thanks for the clarification! I'm still new to Nix, so I'm trying to share useful things I'm learning without overstepping my expertise and saying wrong things.
My mental model of Nix was that if I'm in system state A, which is the result of performing task X + Y, and I want to get to system state B, which is the result of task X + Y + Z, then Nix would recognize that it's already in state A, so it only has to perform task Z to get to state B.
It sounds like what you're saying is that Nix's actual behavior is that if I'm in state A and tell Nix to bring me to state B, then Nix still performs tasks X and Y again, but the results are cached, so tasks X and Y feel as fast as a no-op, and the only task I perceive as taking time is task Z.
Is that right?
- Filligree 3y agoWhen it comes to building derivations, yes. Which describes almost everything you can do. For live system rebuilds in NixOS, the final step involves examining the system to decide which systemd services need restarting and restarting only those; that’s part of the process called activation. But that’s the only exception, and doesn’t happen if you reboot instead.
- hamandcheese 3y agoThat's largely correct! To use more precise language, let's discuss two distinct phases: building and activation. Nix will always "build" x, y, and z. But x and y might turn into a no-op by being cached in the nix store. System activation is when all those things are symlinked into place. If x, y, and z are, say, systemd services, then there might be some logic that checks if x and y have changed and if the services are already running and decide what to do -- this is probably the most similar to how Ansible works. But this is also a small part of the big picture. Activation is pretty fast even starting from nothing.
- mtlynch 3y agoAh, okay. That makes sense. Thanks! I've updated the post based on your feedback.
- pxc 3y agoYep! Nix builds don't know anything about state, and they work just like you describe. Nix builds power basically everything you do with Nix. But for 'installing' packages, more happens than just creating builds and leaving them somewhere in /nix/store. In those cases, you also have a profile manager (nix-env, `nix profile`, nixos-rebuild, darwin-rebuild, home-managwr) which builds a symlink forest (pointing into the Nix store) that represents your complete configuration. That forest is called a profile generation, and represents how, e.g., your user's Nix profile was configured that particular time. (When you perform a rollback, your profile manager is just setting the current profile to a previous generation.) Each generation of your profile has an activation script (and some profile managers may also have some bit of profile activation logic of their own, idk). That activation script may have to perform some state management, e.g., restarting a service or telling the service manager (systemd on Linux or launchd with Nix-Darwin) to reread its configuration files to recognize the availability of a new service. This little bit of state management is hopefully as minimal as it can be. In fact, it's generally expected/communally enforced that Nix packages have to work normally when run directly from their respective residences in /nix/store, without having been installed into any kind of profile at all! So during normal daily Nix usage, I've never really had to think about it. If you want to implement or contribute to a profile manager, you'll have to!