Why does NixOS not have a rolling release system?

Just to add to that, in fact, it’s easier in NixOS because you have a stronger indication that your package sets will play together nicely, because their dependencies can retain the version they were without compromising security for other packages (because the nix store is great).

I.e. if nextcloud doesn’t work on a newer php you can pin nextcloud’s php, but upgrade everyone else’s.

The problem are the more hidden interactions, say between X and a GUI application, where NixOS behaves exactly like other distros. The advantage of a versioned stable branch is that you don’t need to worry about any of this (or file a bug upstream).

4 Likes

Yes, Nix is great with having different versions of packages installed. I chose a bad example. I was referring to the fact that we as Nixpkgs users can only pull in all the changes merged into Nixpkgs at once, some of which may be breaking. We can not only merge in security related changes, for example.

1 Like

On Arch Linux partial upgrades are explicitly unsupported, see System maintenance - ArchWiki.

1 Like

Maybe I am miscommunicating. I don’t want to do a partial upgrade. I want to do a full upgrade.

However, I cannot do this, because my configuration does not evaluate (because of some dependencies). I could now disable the affected derivations, or pin them to older versions but that is a lot of work. What I tend to do is wait until the problem is fixed in Nixpkgs.

However, this sometimes takes weeks. Right now, Google starts to complain that my browser is outdated although I am running nixos-unstable. I would love to update all packages but the ones failing to evaluate because of the faulty dependency. Do you see my point? I never had this problem with Arch Linux, which I had been using for a long time.

So I was thinking, can we improve on this? Maybe a nix[pkgs,os]-stable channel would be nice alternative, but I see there is a lot of tension and counter arguments.

1 Like

This seems to be nextcloud specific. Looks like the intention was to make the upgrade path more ergonomic for people upgrading their system, as nextcloud upgrades seem to only support bumping a single version. And they wanted to enforce that people first bumped to v20 before going to v21, or bump to v21 before going onto v22.

I agree in this situation, it should probably be on the user to determine the package version as this looks to be stateful operation, and nix doesn’t really have a good way to do stateful upgrades.

stateVersion in practice shouldn’t do much except determine where things are located. For example, stateVersion will help determine where a postgresql database should be located, but not much else. The stateVersion should be more like, “where you should be able to find things”, and less “determine the version or configuration of something”.

Also, the releases don’t really know about the stateVersion, but modules are aware of stateVersion, which use the releases as a convention.

3 Likes

We have stable releases, current stable is nixos-21.05. As others have mentioned we just have a 6 month cadence on keeping it alive. [With our current volunteer manhours (people hours?)] we will never have an lts like branch, it just requires too much work to constantly backport potentially relevant items. It’s hard enough doing that with just a difference of 6 months let alone years.

I could now disable the affected derivations, or pin them to older versions but that is a lot of work. What I tend to do is wait until the problem is fixed in Nixpkgs.

Generally I will fix them in a local checkout of nixpkgs, then chunk up the changes into PRs and upstream them. You can apply changes locally by doing, sudo nixos-rebuild -I nixpkgs=$PWD switch, or use path urls if you are using flakes.

I don’t intend for all users to upstream PRs, but it is nice. And when a PR fixes a package, they are usually quickly merged as they are generally a net positive.

Right now, Google starts to complain that my browser is outdated although I am running nixos-unstable .

One thing I do is update my configuration.nix and home-manager independently. Generally they will have smaller scopes, so it’s less likely that a particular evaluation will fail.

3 Likes

Ahah! TIL.

I assume it’s most useful to do this with a checkout of the current tagged revision, so that the majority of stuff still comes from the build cache - but very useful tip. Thankyou.

Population of the nixpkgs cache is a continuous process. The jobset gets triggered every 4 hrs (IIRC), so there’s rarely a time when there’s not a populated cache.

Updates to the release channel can see long delays, if certain things are failing. https://status.nixos.org/

1 Like

Fair enough. I was conflating two things:

  • likelihood of being in the cache (yet)
  • likelihood of actually building

What I actually want is the latter; if my goal is fix/tweak/upgrade a particular particular package to PR, I mostly don’t want to trip over other unrelated build failures. So unless I’m trying to fix one of those build failures holding the release channel back, I’ll use that branch.

Of course the cache is very useful too, I just hadn’t really thought about the fact that it will have (most) stuff ahead of the channel. Which also means I can use this the other way. If there’s a fix for something I want in the tree, ahead of the current channel, but before something else that’s broken the build and prevented channel updates for days (as has happened recently), I can pick that revision and still have stuff from cache. Or even take something more current, if the build failure is something I don’t use.

I suspect this is, at least in part, an issue with visibility. You see into earlier parts of the pipeline. With most distributions, you just check for updates, and if there are none or few, you don’t really think about it, and you don’t really see the build failures to even realise you’re waiting for them.

1 Like

This is perfectly doable via services.nextcloud.package = pkgs.nextcloud22; for instance. This is also the preferred way to do. However Nextcloud is inherently stateful and if you accidentally deploy some wrong config, you can screw up quite much (been there, done that), so a few helpers don’t hurt. Also I don’t expect an administrator to keep track of everything that happens in an upstream package (as a maintainer of this, it’s my job!), so it’s better to try solving most of the issues (considering that the alternative to using NixOS is “just pull this Docker image”).

If one’s interested, I shared some thoughts in Safe service upgrades using system.stateVersion.

4 Likes

You can and it’s pretty easy usually: Simply cherry-pick the changes with git.

The nixpkgs in my NIX_PATH (indirectly) points at GitHub - Atemu/nixpkgs: Nix Packages collection where I merge-pull nixos-unstable to update. When I need some change before it made it through the channel, I simply cherry-pick it.

You sound like you’d benefit from a setup like this too @uep.

This isn’t always optimal because it doesn’t account for caching but it’s the best you can do or reasonably expect. (What should and shouldn’t be built is a social problem.)

I cannot do this, because my configuration does not evaluate (because of some dependencies). I could now disable the affected derivations, or pin them to older versions but that is a lot of work. What I tend to do is wait until the problem is fixed in Nixpkgs.

Well, that’s what you get with rolling releases. They are inherently unstable like that. The only way to improve the situation is more maintainers and more thorough testing of the regular upstream.

2 Likes

This sounds useful, is there somewhere a detailed write up about it?

Don’t know of one but it’s very simple conceptually (merge-pull unstable, cherry-pick off master) and the rest is just using git for which there are tutorials o’ plenty.

If there’s interest I could write up my strategy in a bit more detail.

I would certainly be interested :slight_smile:

EDIT: I replied before I saw that other people in the thread had also recommended this to you, sorry. But maybe there’ll still be something useful in what I wrote.

It seems to me that this exposes one of the (very few!) weaknesses of Nix. Namely, that you cannot (at least not in an easy way) pull in one change (let’s say a security change) without also pulling in all other changes that have been made (merged) in the meantime. On Arch/Debian/…, you can just postpone updating a major version of PHP, if you really wanted. Of course, then you also don’t have any guarantees that your package set plays together well.

Some people really don’t like this, but my reccomendation is to forgo channels, and have your own Nixpkgs git tree that you can pull in changes you want to. If all you’re doing is pulling in small changes that have already made it into master, then when you git pull --rebase to update to a new nixpkgs version, those changes will be transparently removed, so you’ll be back in sync and maintaining it won’t get out of hand.

2 Likes

I’d highly recommend using regular merge pulls. They let you easily trace back your steps without having to rely on the reflog and you can actually push them for synchronising Nixpkgs state between machines.

2 Likes

Atemu via NixOS Discourse discourse@discourse.nixos.org writes:

I’d highly recommend using regular merge pulls. They let you easily trace back your steps without having to rely on the reflog and you can actually push them for synchronising Nixpkgs state between machines.

That’s actually what I’d do as well, but I wouldn’t recommend them to a
beginner, because you’re basically committing to never using upstream
Nixpkgs again. With a rebase flow, on the other hand, unless you’re
doing something complicated, when you update you’ll end up on the same
git revision you’d get from using a channel.

The ideal solution is
git-imerge, but the current
implementation is nowhere near fast enough to be useful for Nixpkgs.
When I tried it out it took more than a day to merge upstream Nixpkgs
into my tree. :frowning:

2 Likes

What I like to do is to use rebase to keep the history clean and simple, but before I rebase, I create a new branch, so I can easily switch back to my previous branch.

What I like to do is to use rebase to keep the history clean and simple, but before I rebase, I create a new branch, so I can easily switch back to my previous branch.

Git automatically stores your version before rebasing in ORIG_HEAD, so there’s not even any need to manually create a new branch. (And if you’ve done more things since and ORIG_HEAD has been updated, you can look in git reflog.) But the reflog is automatically garbage collected eventually, so if there’s a chance you’ll want to go back a month from now to a previous version it still makes sense to create a branch.

1 Like