Skip to content

Updating Garuda Nix

Garuda Nix installs the garuda-update command on GUI systems and on systems managed through garuda-managed.json. It is a convenient way to keep the system up to date.

Terminal window
garuda-update

garuda-update itself is only a small launcher. On every run it fetches the latest updater from the stable branch of the Garuda Nix repo and hands over to it. This allows us to fix common problems before the actual update starts, even on systems that have not been updated for a long time.

  1. The updater is fetched with Nix. If Nix is unable to fetch it, the same updater is fetched with git and run without Nix. If both fail, the update is aborted and nothing is changed.
  2. Fixes for known problems are applied, for example a flake input that uses a fetcher which no longer works. Files changed by a fix are backed up to /var/lib/garuda/garuda-update/backups.
  3. The system is updated:
    • NixOS flake setups update the flake inputs, rebuild with nh os switch, and commit the refreshed flake.lock when the flake lives in a Git repository. The flake defaults to /etc/nixos and can be pointed elsewhere with GARUDA_FLAKE or --flake.
    • Managed systems (/etc/nixos/garuda-managed.json exists) regenerate the managed configuration, update the flake inputs and rebuild.
  4. Fixes that need the new system are applied and a notice is printed for every fix that changed something.

The output of every run is appended to /var/log/garuda/garuda-update.

The updater lives in packages/garuda-update and is the same for NixOS flake setups, managed systems and the subsystem:

FilePurpose
launcher.shThe garuda-update command installed on the system. Fetches the updater and starts it.
runner.pyThe updater. Detects the kind of system, applies the fixes and runs the update.
fixes.pyThe list of fixes. Every fix checks whether it is needed, applies itself and leaves a notice.
nixedit.pyHelpers to change Nix files without touching comments or formatting.

Fixes are applied without asking. Which fixes a system has already received is tracked in /var/lib/garuda/garuda-update/intervention_sequence, so a fix is only applied once. A fix that fails is skipped and tried again on the next update. It never stops the update itself.

It can also be started directly, which is the same as running garuda-update:

Terminal window
sudo nix run "git+https://gitlab.com/garuda-linux/garuda-nix.git?ref=stable#garuda-update"

GitLab started to reject the requests of the gitlab: flake fetcher, which makes updates fail with HTTP error 403 (see NixOS/nix#16588). Older installations of Garuda Nix use this fetcher for the garuda input. The fix changes all inputs in flake.nix that point to GitLab.com to the git+https fetcher, which is not affected:

garuda.url = "gitlab:garuda-linux/garuda-nix/stable";
garuda.url = "git+https://gitlab.com/garuda-linux/garuda-nix.git?ref=stable";

Inputs of self-hosted GitLab instances (?host=) are left alone.

Systems installed before garuda-update fetched the updater from stable do not receive this fix automatically, because their garuda-update is the one that fails. There are two ways to get going again. After that, garuda-update works as usual.

  1. Run the updater once by hand. It applies the fix and updates the system:

    Terminal window
    sudo nix run "git+https://gitlab.com/garuda-linux/garuda-nix.git?ref=stable#garuda-update"
  2. Or edit /etc/nixos/flake.nix yourself as shown above and update the system:

    Terminal window
    sudo nix flake update --flake /etc/nixos
    sudo nixos-rebuild switch --flake /etc/nixos

On a Garuda subsystem that can not be updated from inside, run sudo garuda-nix-subsystem update from the Garuda host instead.

The repository was renamed from garuda-nix-subsystem to garuda-nix. GitLab still redirects the old name, but only for as long as nothing else claims it. The fix points every input in flake.nix that uses the old name of our repository to the new one, whatever fetcher it uses:

garuda.url = "git+https://gitlab.com/garuda-linux/garuda-nix-subsystem.git?ref=stable";
garuda.url = "git+https://gitlab.com/garuda-linux/garuda-nix.git?ref=stable";

It runs after the gitlab-fetcher fix, so an old gitlab:garuda-linux/garuda-nix-subsystem/stable input ends up as the second line above in a single update. Repositories of other owners with the same name are left alone.

No action is needed, because garuda-update applies it on the next update. To do it by hand, replace garuda-nix-subsystem with garuda-nix in the garuda input of /etc/nixos/flake.nix and run sudo nix flake update garuda --flake /etc/nixos.

Roll back to the previous generation (only on standalone NixOS):

Terminal window
garuda-update --rollback

On a Garuda subsystem, garuda-update runs from inside Garuda Nix with the managed path described above. The update can also be triggered from the Garuda host with sudo garuda-nix-subsystem update.