How to use unstable nixpkgs in imports with flake?

I’m trying to convert my nixos-config to Flakes, and it works well, but I found one edge case where I’m not sure what do do. I have a role that imports a service definition from nixos-unstable for mtr-exporter. In my flake.nix I do provide unstable channel:

As described in the wiiki article, which works fine for importing packages:

But does not work for imports when adding the service definition from unstable:

I just get:

error: cannot look up '<nixos-unstable>' in pure evaluation mode (use '--impure' to override)

       at /nix/store/iggskbhd3rl7cy9wb0d70bsxb2yjvsnr-source/roles/mtr-exporter.nix:5:5:

            4|   imports = [
            5|     <nixos-unstable>/nixos/modules/services/networking/mtr-exporter.nix
             |     ^
            6|   ];

I tried several formats:

error: syntax error, unexpected DOLLAR_CURLY

       at /nix/store/i8859bcp1gkcaqn1jfx6r564km2210zz-source/roles/mtr-exporter.nix:5:5:

            4|   imports = [
            5|     ${pkgs.unstable}/nixos/modules/services/networking/mtr-exporter.nix
             |     ^
            6|   ];
error: syntax error, unexpected '<'

       at /nix/store/4v2b7fgnydanqq8sl025rrbd7fd2afc7-source/roles/mtr-exporter.nix:5:5:

            4|   imports = [
            5|     <${pkgs.unstable}>/nixos/modules/services/networking/mtr-exporter.nix
             |     ^
            6|   ];

Using "${pkgs.unstable}/nixos/modules/services/networking/mtr-exporter.nix" gets me:

error: infinite recursion encountered

       at /nix/store/hdfjrcysq8zprj161jpffrf24yd77r3y-source/lib/modules.nix:365:28:

          364|         builtins.addErrorContext (context name)
          365|           (args.${name} or config._module.args.${name})
             |                            ^
          366|       ) (lib.functionArgs f);

But none work. What’s the correct way?

Tried some more options:


  imports = [
    /. + "${pkgs.unstable}/nixos/modules/services/networking/mtr-exporter.nix"
  ];
error: syntax error, unexpected '+'

       at /nix/store/fnfk8kiscy5c1kwn4xwrs2zdbn192nqn-source/roles/mtr-exporter.nix:5:8:

            4|   imports = [
            5|     /. + "${pkgs.unstable}/nixos/modules/services/networking/mtr-exporter.nix"
             |        ^
            6|   ];

  imports = [
    (/. + "${pkgs.unstable}/nixos/modules/services/networking/mtr-exporter.nix>")
  ];
error: infinite recursion encountered

       at /nix/store/hdfjrcysq8zprj161jpffrf24yd77r3y-source/lib/modules.nix:365:28:

          364|         builtins.addErrorContext (context name)
          365|           (args.${name} or config._module.args.${name})
             |                            ^
          366|       ) (lib.functionArgs f);

  imports = [
    (pkgs.unstable + /nixos/modules/services/networking/mtr-exporter.nix)
  ];
error: infinite recursion encountered

       at /nix/store/hdfjrcysq8zprj161jpffrf24yd77r3y-source/lib/modules.nix:365:28:

          364|         builtins.addErrorContext (context name)
          365|           (args.${name} or config._module.args.${name})
             |                            ^
          366|       ) (lib.functionArgs f);

I’m quite confused as to how this is supposed to work.

Interestingly, this format works in the modules section of arguments to nixpkgs.lib.nixosSystem:

    (unstable + /nixos/modules/services/networking/mtr-exporter.nix)

Which allows me to use the service, but if I move that syntax to the role file:

  imports = [
    (pkgs.unstable + /nixos/modules/services/networking/mtr-exporter.nix)
  ];

I just get a recursion error.

error: infinite recursion encountered

       at /nix/store/hdfjrcysq8zprj161jpffrf24yd77r3y-source/lib/modules.nix:365:28:

          364|         builtins.addErrorContext (context name)
          365|           (args.${name} or config._module.args.${name})
             |                            ^
          366|       ) (lib.functionArgs f);

What’s up with that?

And I don’t want to include this in modules because only one of my hosts uses this service.

You could add unstable to specialArgs like so

    nixosConfigurations.someHost =  nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      specialArgs = { inherit unstable; };
      modules = [ ./configuration.nix ];
    };

and then use it in your modules

{ unstable, ... }:
{
   environment.systemPackages = [ unstable.somePackage ];
}
2 Likes

My problem isn’t adding packages from unstable, my problem is adding a service modules from unstable.

Then you can try adding flake inputs to specialArgs or just nixos-unstable and import like this

   imports  = [ "${nixos-unstable}/nixos/modules/services/networking/mtr-exporter.nix" ];

But I have no idea if nixos modules can be mixed that way. I usually copy a module and then change it to match my needs if it’s not available on a current branch.

1 Like

Actually, for some reason if I use the specialArgs method it does work!

I think I get where the error: infinite recursion encountered err or is coming from.

If I get unstable from pkgs.unstable then i get the unstable.legacyPackages.${prev.system}; verison, but if I get unstable from module argument via specialArgs, then I’m getting the value from inputs, which is unstable.url = "nixpkgs/nixos-unstable". Those are two different things!

Thanks for the suggestion, it helped me identify the loop. I need to think about how to solve this though.

My fix uses specialArgs to pass the unstable channel instead of unstable packages:

I tried passing it via overlay as channels.unstable = unstable, but for some reason that also caused an infinite recursion error.

It works, but I’m not sure if it’s the best way to solve this issue. But hopefully once 22.05 is out I won’t have a need for loading additional nixos modules.