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

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.

2 Likes

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.

2 Likes

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
2 Likes

@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;
}
1 Like

@stianlagstad – Can you post the final solution please?

I don’t have a final solution. I never figured it out.

may be try init a different pkgs instance?

  1. find the commit number: singularity | How to install with Nix or Devbox
{ pkgs ? import <nixpkgs> {} }:

let
 pkgOld = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/dce8fc727dc2891628e4f878bb18af643b7b255d.tar.gz") {
   config =  { allowBroken=true; allowUnfree=true; };
 };
in

pkgs.mkShell {
 buildInputs = [
   pkgs.nodejs-18_x
   pkgOld.singularity
 ];
}

The overlay example by @fricklerhandwerk above will work for sure.

Can you post the flake you are trying to work with?

Here’s how I did it in a package (NOTE: this isn’t fully working yet, but the previous version is):

{
  lib,
  makeWrapper,
  buildGoModule,
  fetchFromGitHub,
  pulumi-bin,
  nodejs_20,
  esbuild,
  system,
}: let
  # Fetch the specific version of nixpkgs
  specificPkgs =
    import (builtins.fetchTarball {
      # URL to the tarball of the specific nixpkgs commit
      # Choose the right version for bun using https://lazamar.co.uk/nix-versions/?channel=nixpkgs-unstable&package=bun
      url = "https://github.com/NixOS/nixpkgs/archive/e89cf1c932006531f454de7d652163a9a5c86668.tar.gz";
      sha256 = "sha256:09cbqscrvsd6p0q8rswwxy7pz1p1qbcc8cdkr6p6q8sx0la9r12c";
    }) {
      inherit system;
    };

  # Use bun from the specific nixpkgs version
  bun = specificPkgs.bun;
in
  buildGoModule rec {
...
    buildInputs = [makeWrapper pulumi-bin bun nodejs_20 esbuild];
...

Just stumbled upon this thread as I had the same problem.

Since you mentioned it’s not fully working yet, adding (pkgs) to the inherit system; call made it work for me:
inherit (pkgs) system;

Hope this helps!

Kindof.

Abstractly, substituting version B for version A relies on the two interfaces being close enough.

Upthread, an example is given where the recent NixOS module code assumes the Nix derivation (Nix package) it’s given has certain attributes. When the older Nix derivation is given, the NixOS module doesn’t build because the assumption breaks.

Maybe using the older NixOS module alongside the older package would work (or maybe there are further incompatibilities between that module and other modules). – Another way of working around “incompatibility between new module old package”: copy-paste the NixOS module & beat it into working shape.

Seems like OP’s title is catching search engine results a bit broader than the problem of “use specific older package in module in configuration.nix”.

FWIW, I’d suggest it’s somewhat more idiomatic to pass in bun as an attribute (alongside pulumi-bin, nodejs_20, bun, ...), and then pass in bun like goModWithSpecificBun = pkgs.callPackage ./my-package.nix { inherit (specificPkgs) bun; };. (Or perhaps even overriding the bun passed to an existing package).

1 Like

I see what you are saying here ok. There are more factors than just using an overlay to override attributes in nix.

@rgoulter – I don’t disagree, but in my case I was trying to get SST working. It requires specific versions of bun and pulumi, so I felt locking them down in the package was the right way to do this. Does that make it OK?

I think “it’s not really variable” is a good argument for why you might arrange it like that.

My intuition against it is it’s nicer for “what I know about SST” to be in sst.nix, and “what I know about bun” to be in bun.nix. If the package recipe’s attributes had docstrings, I’d certainly put “must be this specific bun version” for the bun. (Or perhaps mimick how nodejs_20 suggests a specific version).

An advantage to having bun as a parameter is it’d let you try the package with different versions of bun. (e.g. built with more features, or built with fewer features, or etc.). Whereas if the dependency isn’t exposed as an attribute to the package recipe, you’d have to modify the source code to vary that.

I think this is ‘OK’ in the sense that it works.

I’d argue that fetching a particular version of nixpkgs within a package recipe isn’t a very tidy/elegant thing to do. (In kinda the same sense that it’s nicer to have a package definition that builds from source compared to one that runs a prebuilt binary).

Agreed – my solution is a hack, but sometimes you just need a hack to test something out LOL. The right solution is to build from source as you recomment

1 Like