Skip to content

nixos:nixos-rebuild: allow switching to a specific generation number #105910

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

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

miallo
Copy link
Contributor

@miallo miallo commented Dec 4, 2020

Motivation for this change

If the user wants to rollback to any of the system generations but the last, this is currently not easily doable (see #24374).
In order to unify the interface with nix-env a bit more, I propose to add a flag ``nixos-rebuild --generation` to easily go to a specific generation.

I had an issue, where I didn't notice a package breaking ~10 generations ago and while fixing it, I had to go back and forth multiple times. Since I didn't know about

sudo nix-env --switch-generation 12345 -p /nix/var/nix/profiles/system
sudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch

I repeated the rollback n times.

This implementation would make it possible to run

sudo nixos-rebuild switch --generation 12345
Maintainers

@nbp added --rollback
@worldofpeace did the last edits
And I guess @edolstra ?

Things done
  • Tested manually on local system
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@ofborg ofborg bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. labels Dec 4, 2020
@miallo miallo changed the title WIP Allow nixos-rebuild --switch-generation WIP: Allow nixos-rebuild --switch-generation Dec 4, 2020
@miallo miallo changed the title WIP: Allow nixos-rebuild --switch-generation nixos:nixos-rebuild: [WIP] Allow nixos-rebuild --switch-generation Dec 4, 2020
@ofborg ofborg bot added the 8.has: documentation This PR adds or changes documentation label Dec 4, 2020
@miallo miallo changed the title nixos:nixos-rebuild: [WIP] Allow nixos-rebuild --switch-generation nixos:nixos-rebuild: Allow nixos-rebuild --switch-generation Dec 5, 2020
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/prs-ready-for-review/3032/394

@miallo miallo changed the title nixos:nixos-rebuild: Allow nixos-rebuild --switch-generation nixos:nixos-rebuild: Add --switch-generation flag Dec 12, 2020
@miallo
Copy link
Contributor Author

miallo commented Jan 3, 2021

I am not sure about having list-generations in nixos-rebuild, because it isn't strictly related to rebuilding. But on the other hand, having a seperate nixos-list-generations command feels a bit overkill as well, looking at the short list of existing nixos-* commands... On the other hand one could add parameters for formatting and so on, but I am not sure if that is really needed...

Any opinions @edolstra or others?

@miallo
Copy link
Contributor Author

miallo commented Jan 3, 2021

Many ideas for the list-generations come from the script that builds the grub-menu. Maybe it would be worth, having one script that produces a description for a given generation so that grub, as well as the list-generations can utilize it?

@edolstra
Copy link
Member

edolstra commented Jan 4, 2021

Maybe this should be its own subcommand? I.e. nixos-rebuild switch-generation rather than switch --switch-generation, which seems a bit superfluous.

Or alternatively, nixos-rebuild [switch|test] --generation.

@miallo miallo changed the title nixos:nixos-rebuild: Add --switch-generation flag nixos:nixos-rebuild: Add --generation flag Jan 4, 2021
@miallo
Copy link
Contributor Author

miallo commented Jan 4, 2021

I totally agree with your suggestions and I was a bit unhappy with the doubling of the "switch" as well. The reason I chose it nevertheless is that I took the same flag as nix-env...
So far I only used switch and I don't know if others would want to test old generations. But given the fact that --rollback supports both, I guess having a similar interface would be good. I think the nixos-rebuild [switch|test] --generation sounds nice.

@miallo
Copy link
Contributor Author

miallo commented Jan 4, 2021

Any opinions about the list-generations subcommand? I added it to this PR, because with the option to switch to a specific generation I thought it would be nice to have an overview about the main things. I guess a (current) tag as in nix-env --list-generations might be usefull as well.

@edolstra
Copy link
Member

edolstra commented Jan 4, 2021

I think it's okay to add it to nixos-rebuild for now. There is an issue somewhere about replacing nixos-rebuild with a nixos command that would resolve the fact that it's not related to building.

@miallo
Copy link
Contributor Author

miallo commented Jan 6, 2021

I prepared a branch with two clean commits instead of this mess and I could use those instead. I guess it would be easier to read that way

@miallo miallo force-pushed the nixos-rebuild/switch-generation branch from 5e37822 to dc528f0 Compare January 7, 2021 22:51
@miallo miallo force-pushed the nixos-rebuild/switch-generation branch from dc528f0 to 3073ca2 Compare January 15, 2021 07:59
@miallo
Copy link
Contributor Author

miallo commented Jan 15, 2021

Anyone wants to take a look and review this?

@miallo miallo force-pushed the nixos-rebuild/switch-generation branch from 1ab9cab to a0e6d87 Compare January 16, 2021 14:36
@SuperSandro2000 SuperSandro2000 added the 2.status: merge conflict This PR has merge conflicts with the target branch label Jan 18, 2021
@miallo miallo force-pushed the nixos-rebuild/switch-generation branch from a0e6d87 to 84f3e1f Compare January 23, 2021 19:49
@ofborg ofborg bot removed 8.has: module (update) This PR changes an existing module in `nixos/` 2.status: merge conflict This PR has merge conflicts with the target branch labels Jan 23, 2021
--generation)
if [ $# -eq 0 ]; then
log "Must provide a generation number"
log "Usage: \`$(basename "$0") ${action:-switch} --generation <NUMBER>'"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do I need to give an action when I just want to switch to a generation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't know if you want to switch, boot or test said generation, so you have to tell us what you want to do with it...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but if I want to switch to an older generation, why does it start to build the current config file from disk which might be newer than the current generation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is interesting - I don't think this happened to me before 🤔 Where did you see this behavior? If it is in the tests: the first three tests don't actually do the --generation, but they create the generations, so there it is expected that they build the config files...

I know it isn't a good answer, but: I don't really know what I am doing (at least not 3 years after I first wrote this patch). I just adapted the code for the --rollback since I thought they would be more or less identical... I have forgotten the few things I knew about the nix-env stuff and the rest on how this is activated 🙈 If we just wanted to activate the generation and don't care about the action I guess we could also just run /nix/var/nix/profiles/system-$generation-link/activate...

I tried to add a test for the boot --generation, but something is strange (maybe the QEMU runs some kind of tempfs - at least after the machine.reboot() and it doesn't have nix-channels or actually the old generations any more on the disk) and so I could only check that the current generation was still active...

Copy link
Contributor Author

@miallo miallo Dec 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could not reproduce the building of the current configuration.nix in the tests, as this passes, which I think is what you mean:

diff --git a/nixos/tests/nixos-rebuild-switch.nix b/nixos/tests/nixos-rebuild-switch.nix
index b9ed2954299a..e5f3e378ad73 100644
--- a/nixos/tests/nixos-rebuild-switch.nix
+++ b/nixos/tests/nixos-rebuild-switch.nix
@@ -84,12 +84,15 @@ import ./make-test-python.nix ({ pkgs, ... }: {

       with subtest("Create generation 3"):
           ${createConfig "3"}
-          machine.succeed("nixos-rebuild switch")
+          out = machine.succeed("nixos-rebuild switch 2>&1")
+          assert "building the system configuration..." in out
           ${testForBootGeneration "3"}
           ${testForActiveGeneration "3"}

       with subtest("must switch to `--generation 1`"):
-          machine.succeed("nixos-rebuild switch --generation 1")
+          ${createConfig "4"}
+          out = machine.succeed("nixos-rebuild switch --generation 1 2>&1")
+          assert "building the system configuration..." not in out
           ${testForBootGeneration "1"}
           ${testForActiveGeneration "1"}

Did I misunderstand you or do you have a reproduction by any chance?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we just wanted to activate the generation and don't care about the action I guess we could also just run /nix/var/nix/profiles/system-$generation-link/activate...

Yes, this is basically what I wanted to do.

Did I misunderstand you or do you have a reproduction by any chance?

I think this is what I did, yes.

well the script (re)executes itself

I am usually passing --fast to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we just wanted to activate the generation and don't care about the action I guess we could also just run /nix/var/nix/profiles/system-$generation-link/activate...

Yes, this is basically what I wanted to do.

I just implemented it with "feature parity" to the --rollback. I personally mostly use switch as an action, but maybe e.g. someone could want to set a "known good generation" as a default after a reboot when testing a server update and on error they can just do a reboot and everything should be back to normal. Could something like this be a use case (and if not, just out of curiosity: why would it be one for rollback)?

Did I misunderstand you or do you have a reproduction by any chance?

I think this is what I did, yes.

Very interesting... This should not happen (https://github.com/NixOS/nixpkgs/pull/105910/files#diff-fc23c722779993fcffc932965cd143b265aa196d577ca10173b63e5bdcbc0001R608-R609) and also the test that I wrote above passes... 🤔 I really don't have a clue how this could have happened... Anyone has any idea (or even better can add a failing test case)?

@theduke

This comment was marked as off-topic.

@wegank wegank added the 2.status: merge conflict This PR has merge conflicts with the target branch label Mar 20, 2024
@miallo miallo force-pushed the nixos-rebuild/switch-generation branch from 1860f2a to 9e37703 Compare May 24, 2024 10:05
@github-actions github-actions bot added the 8.has: maintainer-list (update) This PR changes `maintainers/maintainer-list.nix` label May 24, 2024
@miallo
Copy link
Contributor Author

miallo commented May 24, 2024

I rebased it and fixed the merge conflicts. Also added a tiny improvement to the test so that it is checked if a new genertion is built, or if it is just a simple switch

@ofborg ofborg bot added 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. and removed 2.status: merge conflict This PR has merge conflicts with the target branch 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. labels May 24, 2024
@wegank wegank added the 2.status: merge conflict This PR has merge conflicts with the target branch label Jul 4, 2024
@nyabinary
Copy link
Contributor

I rebased it and fixed the merge conflicts. Also added a tiny improvement to the test so that it is checked if a new genertion is built, or if it is just a simple switch

another merge conflict :P

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/where-did-you-get-stuck-in-the-nix-ecosystem-tell-me-your-story/31415/72

@wegank wegank added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jan 1, 2025
@miallo miallo force-pushed the nixos-rebuild/switch-generation branch from 9e37703 to 79c579c Compare March 25, 2025 06:20
@github-actions github-actions bot removed the 8.has: maintainer-list (update) This PR changes `maintainers/maintainer-list.nix` label Mar 25, 2025
@ofborg ofborg bot removed the 2.status: merge conflict This PR has merge conflicts with the target branch label Mar 25, 2025
@Creative-Difficulty
Copy link

Are there any updates on this?

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 7, 2025
@nixpkgs-ci nixpkgs-ci bot removed the 12.first-time contribution This PR is the author's first one; please be gentle! label Jun 25, 2025
Copy link
Contributor

@Jayman2000 Jayman2000 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The most important parts of this pull request are the changes to nixos/doc/manual/administration/rollback.section.md, nixos/doc/manual/release-notes/rl-2411.section.md and pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh. Those changes are good. There are some minor improvements that I would make to those files, but for the most part they’re good.

That being said, nixos/tests/nixos-rebuild-switch.nix needs work. I tried following the instructions in the NixOS manual for running NixOS tests, but I wasn’t able to run the test by following those instructions.

I created a branch named nixos-rebuild/switch-generation-proposals. Here’s what that branch contains:

  • A rebased version of the commit from this pull request. I rebased it on a newer revision of the master branch (3a16031).
  • A bunch of fixup commits that bring nixos/tests/nixos-rebuild-switch.nix into working order.
  • A few fixup commits that make minor improvements to the other parts of this pull request.

Each fixup commit contains a detailed explanation for why I think that the change from the fixup commit should be made. Here’s what you can do to review my fixup commits and incorporate some or all of them into this pull request:

Click here to show or hide instructions.
  1. Change directory into a clone of the Nixpkgs repository by running this command:

    cd <path to nixpkgs repo>
  2. Make sure that your local copy of the Nixpkgs’s master branch is sufficiently up-to-date by running this command:

    git switch master && git pull
  3. Create a local copy of my nixos-rebuild/switch-generation-proposals branch by running this command:

    git remote add codeberg-JasonYundt https://codeberg.org/JasonYundt/nixpkgs-backup.git && git fetch codeberg-JasonYundt && git switch --track codeberg-JasonYundt/nixos-rebuild/switch-generation-proposals
  4. Read through the fixup commits and the code that they change. I recommend using git log --reverse --patch master.. to read through the commits, but it doesn’t really matter how you do it.

  5. If there are any fixup commits that you don’t like, then use git rebase --interactive to drop those fixup commits.

  6. If there are any fixup commits that you do like, then incorporate them into this pull request by following these instructions:

    1. Figure out the hash for the first commit in the nixos-rebuild/switch-generation-proposals branch by running this command:

      git cherry -v master HEAD | head --lines=1
    2. Squash the commits in your local copy of the nixos-rebuild/switch-generation-proposals branch by running this command:

      git rebase --autosquash <hash>^
    3. Switch to your local nixos-rebuild/switch-generation branch by running this command:

      git switch nixos-rebuild/switch-generation
    4. Make your local nixos-rebuild/switch-generation branch the same as your local nixos-rebuild/switch-generation-proposals branch by running this command:

      git reset --hard nixos-rebuild/switch-generation-proposals
    5. Push a new version of this pull request by running this command:

      git push --force

nixpkgs-review result

Generated using nixpkgs-review.

Command: nixpkgs-review pr 105910
Commit: 79c579c37c119892647875fb53bb69f98e7d39b4


x86_64-linux

⏩ 2 packages blacklisted:
  • nixos-install-tools
  • tests.nixos-functions.nixos-test
✅ 1 package built:
  • nixos-rebuild

@eclairevoyant
Copy link
Contributor

eclairevoyant commented Aug 15, 2025

I'm wondering if it makes more sense to invest time in improving the -ng script since that's really where other improvements are being made. Given that this PR is 5 years old it doesn't seem like people want to touch the old script.

Run `nixos-rebuild switch --generation 12345` to roll back to generation
`12345`. This makes rolling back to an older generation easier

Also updated the release notes and add a test for the new feature

Co-Authored-By: Jason Yundt <jason@jasonyundt.email>
@miallo miallo force-pushed the nixos-rebuild/switch-generation branch from 79c579c to 487a3e9 Compare August 17, 2025 18:46
@miallo
Copy link
Contributor Author

miallo commented Aug 17, 2025

@Jayman2000, thank you for your suggestions! Your detailed commit messages clearly explained your changes, and you even created a POC repo for a potential bug. It is an absolute joy to see a changelog like this!

This PR was one of my first contributions to nixpkgs when I was just starting to learn software engineering. I made multiple mistakes, the biggest being that I combined two features into one PR because both were bothering me. After getting feedback, I split one feature into a separate PR for listing generations. However, this made the discussion on this PR too long for reviewers to read. I am tempted to create a new PR for this remaining feature as well to simplify reviews, but for now, I just pushed the combined changes from @Jayman2000 to this PR. I opted to directly squash them.

How to check differences

To see the difference between the suggestions of @Jayman2000 and this PR, run

git remote add github-miallo https://github.com/miallo/nixpkgs.git && git fetch github-miallo && \
git remote add codeberg-JasonYundt https://codeberg.org/JasonYundt/nixpkgs-backup.git && git fetch codeberg-JasonYundt && \
git diff codeberg-JasonYundt/nixos-rebuild/switch-generation-proposals github-miallo/nixos-rebuild/switch-generation

Only difference to his final suggestions is that this now is changing the correct next release notes instead of the 24.11 ones.

@eclairevoyant, I’m also looking into the -ng script and will try to add this feature there as well. Maybe this would be another reason to consider a merge then?

@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-darwin: 1 This PR causes 1 package to rebuild on Darwin. and removed 11.by: package-maintainer This PR was created by a maintainer of all the package it changes. labels Aug 17, 2025
@nix-owners nix-owners bot requested a review from thiagokokada August 17, 2025 18:52
@thiagokokada
Copy link
Contributor

As the maintainer of both nixos-rebuild and nixos-rebuild-ng, I prefer that we don't invest any more time in nixos-rebuild, especially now that the former is officially deprecated.

Copy link
Contributor

@thiagokokada thiagokokada left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not merge this unless this is reworked to use nixos-rebuild-ng instead.

@miallo miallo marked this pull request as draft August 17, 2025 19:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1.severity: significant Novel ideas, large API changes, notable refactorings, issues with RFC potential, etc. 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: changelog This PR adds or changes release notes 8.has: documentation This PR adds or changes documentation 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-darwin: 1 This PR causes 1 package to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux.
Projects
None yet
Development

Successfully merging this pull request may close these issues.