How to install a previous version of a specific package with configuration.nix?

I’d like to use a specific version of singularity (https://github.com/NixOS/nixpkgs/blob/74c3268a1cefeb89796d93272ea90d6f112a6390/nixos/modules/programs/singularity.nix). From https://lazamar.co.uk/nix-versions/?channel=nixpkgs-unstable&package=singularity I’ve found that the specific version that I’m after, 3.7.2, is available in unstable at ref a765beccb52f30a30fee313fbae483693ffe200d. There’s even a page for how to use it: Nix Package Versions. However, I’d like to add this to my configuration.nix, so I’ve tried this:

# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, pkgs, ... }:

let
  nix_pkgs_with_singularity_version_3_7_2 = import (builtins.fetchGit {
         # Descriptive name to make the store path easier to identify                
         name = "nix_pkgs_with_singularity";                                                 
         url = "https://github.com/NixOS/nixpkgs/";                       
         ref = "refs/heads/nixpkgs-unstable";                     
         rev = "a765beccb52f30a30fee313fbae483693ffe200d";                                           
     }) {};
in {
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];
  ...
    programs.singularity = {
    enable = true;
    package = nix_pkgs_with_singularity_version_3_7_2.singularity;
  };
  ...
}

However when I try to build that, I get this error:

error: attribute 'currentSystem' missing

       at /nix/store/nd0x64ljbw98y50ypph1pg9mb42pwbjz-nix_pkgs_with_singularity/pkgs/top-level/impure.nix:18:43:

           17|   # (build, in GNU Autotools parlance) platform.
           18|   localSystem ? { system = args.system or builtins.currentSystem; }
             |                                           ^
           19|
(use '--show-trace' to show detailed location information)

My system is using flakes, and my flake.nix and flake.lock looks like this:

flake.nix

{
  description = "dell flake config";

  inputs = {
    nixpkgs = {
      url = "nixpkgs/nixos-unstable";
    };
    home-manager = {
      url = "github:nix-community/home-manager/release-22.05";
      inputs = {
        nixpkgs = {
          follows = "nixpkgs";
        };
      };
    };
  };

  outputs = { nixpkgs, home-manager, ... }:
  let
    system = "x86_64-linux";
    pkgs = import nixpkgs {
      inherit system;
      config = { allowUnfree = true; };
    };
    lib = nixpkgs.lib;
  in {
    nixosConfigurations = {
      nixos-dell = lib.nixosSystem {
        inherit system;
        modules = [
          # System config
          ./configuration.nix
          # Make home-manager available in the above configuration.nix:
          home-manager.nixosModules.home-manager
          {
            # use system-level nixpkgs rather than the HM private ones
            # "This saves an extra Nixpkgs evaluation, adds consistency, and removes the dependency on NIX_PATH, which is otherwise used for importing Nixpkgs."
            home-manager.useGlobalPkgs = true;
          }
        ];
      };
    };
  };
}

flake.lock

{
  "nodes": {
    "home-manager": {
      "inputs": {
        "nixpkgs": [
          "nixpkgs"
        ]
      },
      "locked": {
        "lastModified": 1667907331,
        "narHash": "sha256-bHkAwkYlBjkupPUFcQjimNS8gxWSWjOTevEuwdnp5m0=",
        "owner": "nix-community",
        "repo": "home-manager",
        "rev": "6639e3a837fc5deb6f99554072789724997bc8e5",
        "type": "github"
      },
      "original": {
        "owner": "nix-community",
        "ref": "release-22.05",
        "repo": "home-manager",
        "type": "github"
      }
    },
    "nixpkgs": {
      "locked": {
        "lastModified": 1676300157,
        "narHash": "sha256-1HjRzfp6LOLfcj/HJHdVKWAkX9QRAouoh6AjzJiIerU=",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "545c7a31e5dedea4a6d372712a18e00ce097d462",
        "type": "github"
      },
      "original": {
        "id": "nixpkgs",
        "ref": "nixos-unstable",
        "type": "indirect"
      }
    },
    "root": {
      "inputs": {
        "home-manager": "home-manager",
        "nixpkgs": "nixpkgs"
      }
    }
  },
  "root": "root",
  "version": 7
}

Is there a nice way to add this to my machine system-wide? Or should I instead create a custom shell where I have what I need available? Thanks!

1 Like

You’ll need to inherit (pkgs) system; in the argument to the imported nixpkgs, so it knows what system to build for.

Also, I would use fetchTree { type = "github"; owner = "nixos"; repo = "nixpkgs"; rev = "a765beccb52f30a30fee313fbae483693ffe200d"; } rather than use fetchGit. The zips are generally easier to deal with than doing clones.

1 Like

Thanks for responding! Where exactly do I write ìnherit (pkgs) system? I naively tried a couple of places but couldn’t figure it out.

“in the argument to the imported nixpkgs” means:

let
  nix_pkgs_with_singularity_version_3_7_2 = import (builtins.fetchGit {
         # Descriptive name to make the store path easier to identify                
         name = "nix_pkgs_with_singularity";                                                 
         url = "https://github.com/NixOS/nixpkgs/";                       
         ref = "refs/heads/nixpkgs-unstable";                     
         rev = "a765beccb52f30a30fee313fbae483693ffe200d";                                           
     }) { ìnherit (pkgs) system; };
in
2 Likes

Thanks That got me further, but to another error:

error: anonymous function at /nix/store/nd0x64ljbw98y50ypph1pg9mb42pwbjz-nix_pkgs_with_singularity/pkgs/applications/virtualization/singularity/default.nix:1:1 called with unexpected argument 'enableSuid'

       at /nix/store/nd0x64ljbw98y50ypph1pg9mb42pwbjz-nix_pkgs_with_singularity/lib/customisation.nix:69:16:

           68|     let
           69|       result = f origArgs;
             |                ^
           70|
(use '--show-trace' to show detailed location information)

I’m not sure how to trace this. I can find both files (on the same git sha):

But I’m not able to follow the error.

You’re still using the nixos module from your main version of nixpkgs, and it seems like the module depends on overridable options that weren’t present in that older version’s nix expression for the package itself. It’s possible you can get around this by disabling the normal module and importing one from the old commit of nixpkgs, but that may also just introduce other incompatibilities between modules.

1 Like

Ah, thanks. So it’s this thing (https://github.com/NixOS/nixpkgs/blob/545c7a31e5dedea4a6d372712a18e00ce097d462/nixos/modules/programs/singularity.nix#L56) from the new module (the module on the git rev I have in my flake.lock for nixpkgs) that’s not compatible with the old module for the version I’d like to use?

Is there a way to use (or try to use) a module from an old rev?

Correct-ish. It’s more this.

There is, see this section of the nixos manual. However this may introduce incompatibilities between the old module and the rest of the nixos modules.

1 Like

I tried to follow your instructions but it seems nix-shell ignores the rev.

let
  specificPkgs = import (builtins.fetchTree {
    type = "github";
    owner = "nixos";
    repo = "nixpkgs";
    rev = "2f4b73d310266e3f8664f4a65586ce6500c4f407";
  }) {};
in
  specificPkgs.vscode

which I run as

nix-shell vscode-1.84.nix

I get the last version (v1.86) instead

Is there any obvious mistake?

There is another approach: put the old package into an overlay, wrap it to satisfy the module, and apply the overlay to Nixpkgs before calling module evaluation. It has the advantage that you can manage the dependency on the old version in the flake, like the rest. (This is not great because the module isn’t self-contained any more and there are spooky effects at a distance, but at least it’s consistent. I wrote more about the architectural issue if you care.)

When you use nix-shell foo.nix, it enters the build environment of the derivation that foo.nix evaluates to, in this case vscode. So vscode itself isn’t available. Rather, the tools necessary to build vscode (or more likely, necessary to wrap it) are available. You’re probably just seeing the system-wide instance of vscode, still. You need to use mkShell to create an environment containing vscode.

If all you want to do is run the thing, btw, the flakes CLI has a simpler method to do so:

$ NIXPKGS_ALLOW_UNFREE=1 nix run --extra-experimental-features 'flakes nix-command' --impure github:nixos/nixpkgs/2f4b73d310266e3f8664f4a65586ce6500c4f407#vscode
1 Like

@tejing Thanks that solution works for me (although extensions are messed up, but I can deal with this)

@fricklerhandwerk, sorry but I hardly understand any of your answer. I am far from that level with Nix.

Ah, sure, let’s be a bit more concrete. I imagine it to work something along these lines in your flake (not tested, only for illustration):

let
  # ...
  # your specific old version of Nixpkgs
  old_nixpkgs = import inputs.old_nixpkgs { inherit system; };
  # the mainly used version of Nixpkgs, with the overlay below applied
  pkgs = import inputs.nixpkgs { inherit system; overlays = [ overlay ]; };
  # set just your package to come from the old Nixpkgs
  overlay = final: prev {
    # advanced: add a wrapper here which allows calling `.override { <whatever the module needs> }` 
    singularity = old_nixpkgs.singularity;
  };
in
{
  # ...
  # evaluate your configuration, using your custom pkgs
  nixosConfigurations.myConfig = nixosSystem {
    modules = [ ./configuration.nix ];
    inherit pkgs system;
}