5 ms·
Thank you! Your comments are always great. :) Especially this bit was I think the insight I was looking for: > This does mean that the experience of using Nix
by mehrdadn 6y ago
Thank you! Your comments are always great. :) Especially this bit was I think the insight I was looking for:
> This does mean that the experience of using Nix is different from using a traditional package manager - you'll need to take care of starting the services you need, etc.
I was trying to figure out where exactly the trade-offs would be -- so that's one of them: it seems like (in some sense, to simplify) Nix takes responsibility for the data & programs, and leaves you with the responsibility of handling the control flow (at least externally).
If you don't mind, this leaves me with one more question. A typical headache that comes up during upgrades (on pretty much any distro) is config changes -- i.e., where the user and the package manager are both responsible for handling data. (Contrast this with the data/control-flow responsibility split we discussed above.) Like you modify /etc/ssh/sshd_config or any other one of the countless /etc config files that you can't configure with a .d folder, then the system upgrades and leaves you to handle the merge conflict. How does Nix deal with these? Presumably "never modify /nix/etc/..." is neither a realistic expectation for the user nor for the package manager, so there are bound to be merge conflicts, right? But that goes squarely against having a deterministic build configuration, so what happens?
- geofft 6y agoSo, there is no /nix/etc - anything in /nix is immutable. I haven't done this and hopefully someone will correct me if I get the details wrong, but I think the way you'd make this work within nix is you'd make your own package, let's call it "my-sshd-config," and it depends on a certain version of sshd. Then you'd have /nix/store/abcd1234-my-sshd-config-1.0/etc/sshd_config. (where "abcd1234" is a hash of everything in your package, including the specific version of ssh you depend on) If you want to upgrade sshd and the config changes, you'd make my-sshd-config 2.0, and nix would put its files in /nix/store/efgh5678-my-sshd-config-2.0/etc/ssh_config. You could have both of these installed at the same time. Then, it's up to you to stop the sshd running out of my-sshd-config 1.0 and to start the one running out of my-sshd-config 2.0. Once you're confident of the upgrade, you can then tell Nix to clean up my-sshd-config 1.0, but that's just removing files, since you've already stopped the service. (We're about to upgrade sshd at work next week and I wish we had something like this, honestly, both so I could distribute the files to machines well before the upgrade and so that it's easy to roll the upgrade back - just stop the new sshd and start the old one. Then there wouldn't be concerns about config drift, forgetting to revert files, etc. The only configuration that I'd have to manage is which one is active.) Most people who use Nix without NixOS aren't running services like sshd out of it, but NixOS will do basically this for handling service upgrades. Conceptually NixOS gives you one mutable configuration knob, which is "what is all the systemwide stuff for this system." You can depend on some particular sshd and its config, some particular init system and its config, some particular syslogd and its config, etc. If you want to change any config, you make a new package with the changed config, and then flip the one mutable thing to point to it instead. (This does mean that it's easy to roll back your system to an old state if you realize you made a mistake!) There is a limitation here, which is that Nix can't do a lot about config in your home directory, like ~/.ssh/ssh_config (for the SSH client). You'll have to be careful with that just like you would with upgrades in general. Alternatively, you could make your own Nix packages that include client config, and avoid storing config in your home directory.
- mehrdadn 6y agoOh dear... so you have to write a Nix package (and learn how the language and package management work) just to modify global config files, instead of just editing them? That sounds like an absolute nightmare for a local machine, though possibly a great tool for automated systems. Also, if there's no /nix/etc... then what is Nix modifying? sshd (or any other more common program; I'm just using sshd as an example to understand the rest of the system) won't magically know to look at /nix/store/efgh5678-my-sshd-config-2.0/etc/ssh_config, right? I thought you'd at least need a symlink like /nix/etc/ssh/sshd_config to link to it. Unless you're saying Nix modifies your system's /etc/ssh/sshd_config directly and makes it a symlink to the immutable Nix store? In which case, wouldn't it just trample everything your own distro's package manager does in that folder?
- geofft 6y agoI haven't used NixOS, so take me with a grain of salt - it looks like the actual way of doing this in NixOS is that you have a systemwide configuration file that you can edit, and running "nixos-rebuild" will pick up your changes and automatically make the packages you need. See "Changing the Configuration" in the manual: https://nixos.org/nixos/manual/index.html https://nixos.org/nixos/manual/index.html So, at the end of the day, there is a Nix package, but you don't interact with it by using the packaging tools, you interact with it by editing a file and then running a command that snapshots the current version of the file and does everything for you. If you're running your own services, you don't have to go through Nix packaging, you can handle this yourself if you have a way you prefer. For example, if you're running WordPress out of your home directory, you can have a git repo with some config files and a script that runs a particular version of Apache, MySQL, PHP, WordPress, etc. out of Nix. If you want to upgrade, edit the versions in the script and also the config files, then tell them all to restart. You can't rely on having a single systemwide version of Apache like you can with a traditional distro, but on the other hand, you aren't tied to whatever version the system wants to give you, you can keep running the current version until you're ready to upgrade. I'm looking forward to Shopify's part 2 blog post to see what they do exactly. :) > sshd (or any other more common program; I'm just using sshd as an example to understand the rest of the system) won't magically know to look at /nix/store/efgh5678-my-sshd-config-2.0/etc/ssh_config, right? Conceptually, my-sshd-config includes a script (or systemd unit, or whatever) that has a reference to a particular version of sshd and also has your config, and so it would run "/nix/store/aaaa1111-openssh-9.0/bin/sshd -f /nix/store/efgh5678-my-sshd-config-2.0/etc/sshd_config". The openssh package doesn't know about you, and you can't change it, but you know about it. (In other words, the inputs that resulted in the hash efgh5678 include "aaaa1111-openssh-9.0".) It looks like the actual way you do this in NixOS is that the sshd package provides a function in the Nix language which takes some config as input and spits out a package as output. So your systemwide config file loads the sshd package and calls a function, which returns a systemd unit with the right filenames. https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/ssh/sshd.nix#L84 https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/s...