New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
make nixos.stateVersion mandatory #65314
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest adding an assertion like this to provide a much better error message than the generic "Option is used but not defined"
{
assertions = [
{
assertion = options.system.stateVersion.isDefined;
message = "`system.stateVersion', which protects against future state migrations, "
+ "is not defined. Set it to its previous default value of \"${cfg.release}\".";
}
];
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having already seen people getting badly bitten by this, I'm all 👍 for this change!
@@ -188,6 +188,7 @@ in rec { | |||
networking.hostName = "client"; | |||
nix.readOnlyStore = false; | |||
virtualisation.writableStore = false; | |||
system.stateVersion = "19.09"; # TODO: determine automatically |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this TODO ought to be resolved before merging this, as otherwise we'll forget it after 19.09 branch-off, and we'll start testing outdated versions of postgresql on the next postgresql bump (or similar thing that would involve bumping stateVersion)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Giving it a bit more thought: either that or just add bumping this to the release process checklist, maybe -- definitely need to record the existence of this TODO somewhere at least, though.
@infinisil Regarding the assertion: Maybe replace the last paragraph. We want to avoid a situation where a user accidentally deletes the setting, gets that assertion message, then puts it back with a release possibly several versions ahead of their system's compatibility at the suggestion of the text. |
@srhb Yeah, but I'm not sure what would be a good replacement for it. Ideally I'd like to say
Not sure how this can be phrased better.. |
@infinisil Punting a bit, but how about referring to the option documentation and we can try to improve on that? Better than having to cook up a great explanation in multiple places. :) |
I took the liberty to push a better |
Actually, it's kind of bad UX if we now make So it's arguably better if we first figure out the per-module But then again, figuring out per-module |
But then again, figuring out per-module `stateVersion` will take some time, likely with an RFC, and until that point users who don't have the global `stateVersion` set are at risk of breakage
Yes. Which is why I think for now we should just copy-paste the warning from 1f0b692 (maybe with minor modifications describing what will break if they won't set it) to all the modules that actually depend on `stateVersion`. Users that don't have those modules enabled won't feel a thing, the rest could be affected by the issue, so, I say, let them see it.
Thoughts?
|
That sure would be the least-invasive solution for now, but copy-pasting it around doesn't sound very nice. Maybe an internal option |
To be more end-user friendly, the internal setting could be a list, Though, this is all well, but with this coming update, most, if not all, systems will require stateVersion to be set because of how it ends up being used for systemd-timesyncd. (#64922) So, in a way, it's now de facto required. Unless a solution is figured out before the 19.09 fork/release, to handle the issue in another way. |
I see. So it might be best to just go ahead with the original idea of this PR and make |
One can use NixOS without `systemd-timesyncd`. There are, at the very least, `ntpd` and `chrony` modules doing the same thing (the latter one is much simpler source-vise, yet also much more advanced, with automatic clock drift calculations and etc, btw).
Thus, I still vote for per-module warning (regardless of the actual implementation, the list proposal above sounds nice, though).
|
I'm contra to adding mandatory options. I'm also against of having
to just build. It should be |
@oxij Always requiring I feel like this is a band-aid like situation, we should just rip it off in one swoop by making @danbst That would be neat yeah, but I think that's something for the future. For most users whether the |
@infinisil
Firstly, I think everybody here agrees than a global `stateVersion` is a hack which should be eventually removed.
Secondly, modules using `stateVersion` should check it explicitly, if they don't I would consider it a bug.
Hence
If this was done with the module list thing,
(or any other listed non-mandatory method)
people could suddenly have to set `stateVersion` when they update their NixOS.
but only if they use something that depends on it, which is the point.
we should just rip it off in one swoop by making `stateVersion` mandatory
Firstly, concerning `systemd-timesync` use of `stateVersion` in `nixos/modules/system/boot/timesyncd.nix`, I don't see why that piece of code can't be made unconditional. It looks like a migration script that will work for both old and new version of the package to me. (Since the old version of `systemd-timesyncd` can just regenerate the old directory, there's nothing of essence stored there anyway. Though, if you boot into an older release it might create some junk on the second migration, but that seems easy to fix with one more conditional around the line doing `mv`.)
Which brings us back to the point that most systems should not, and with `systemd-timesyncd` fixed would not, ever use `stateVersion`. Currently `stateVersion` is used in conditional expressions in just a handful of services. Most uses of `stateVersion` in `nixos` tree are assignments to it to "avoid warnings during eval" and similar reasons, which is rather meh, IMHO.
In short, I think that making it mandatory is counterproductive. By making it mandatory we will just make it harder to remove.
After some more thinking about this I reverted to the opinion that copy-pasting edited warnings from 1f0b692 to modules using it should be better than any new infrastructure. Those copy-pasted pieces will just eventually turn into warnings/assertions for modularized `stateVersion`.
I.e. I vote for simple copy-paste.
@danbst
Well, adding some runtime checks that would check that on-disk `stateVersion` is equal to `stateVersion` of `configuration.nix` would be useful, but I don't see how we could ever remove it from `configuration.nix` eval altogether.
Because, in general, we can't just migrate on-disk service state a-la database schema migration because users can boot into older generations of their NixOS systems and booting into a newer one without explicit `stateVersion` could cause backward-incompatible migration for the older ones. (Which, I claim, is not the case for `systemd-timesyncd` issue above, especially since it does not store anything of essence in its state anyway.)
|
On second thought, yeah actually that doesn't sound half bad @oxij, having a warning copy-pasted to every module that uses |
To make the switch less painful, I think we should handle this like a deprecation (basically deprecating omittance of |
Thank you for your contributions.
|
still important to me |
I marked this as stale due to inactivity. → More info |
Is this still relevant? |
Yes, as an issue, it is still relevant. |
Duplicate of #149877 |
Motivation for this change
In #61321 a necessary migration was only run if the stateVersion is older than 19.09. The default value of cfg.release (= 19.09) prevented it from being run on systems without explicit stateVersion.
In this particular case, maybe using stateVersion could have been avoided, but in general, it is not safe to have a system without explicitly set stateVersion.
All systems installed in the last few years should have it set automatically, but there are surely still a lot of configs out there with it not set.
(While stateVersion as it is currently designed has other problems, like mentioned in #50112, the goal here is to just do the minimal change to get systems safe.)
Things done
sandbox
innix.conf
on non-NixOS)nix-shell -p nix-review --run "nix-review wip"
./result/bin/
)nix path-info -S
before and after)