Use a module from nixpkgs unstable in flake

I’m using deploy-rs to deploy my systems with a flake config, and I’m trying to get the netdata module from unstable into my configuration.

I can use disableModules to skip importing the netdata module, but I don’t know how to import the one from unstable.
There’s modulesPath but that refers to the path of the “base” nixpkgs.

So, is this possible?

2 Likes

Maybe I’m missing something, but can’t you add an additional input to your flake called nixpkgs-unstable that tracks unstable, and wrap you ./configuration.nix in another function that passes this in?

In configuration.nix:

{ nixpkgs-unstable }:
{ config, pkgs, ... }:
{
  # use the module here I guess?
}

In flake.nix:

nixpkgs.lib.nixosSystem {
  modules = [
    (import ./configuration.nix { inherit nixpkgs-unstable; })
    # ... other modules  
  ];
}

Right so I already have unstable as an input to my flake, but I don’t know how to get to the module definition from the flake. It’s not an attribute, or at least I can’t find it.

modulesPath gives you the filesystem location of the main nixpkgs flake, so that you can read files from there, but there’s no modulesPath for nixpkgs-unstable, I think?

The flake input can be converted to a string, yielding the path to the flake source in the nix store. Continuing based on the code from @iFreilicht:

{ nixpkgs-unstable }:
{ config, pkgs, ... }:
{
  imports = [
    "${nixpkgs-unstable}/nixos/modules/services/monitoring/netdata.nix";
  ];
}

I don’t like this approach though because it adds another function call layer. I’m actually passing all in my inputs to my NixOS configurations as specialArgs in flake.nix to the module system:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05";
    nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
  };

  outputs = { nixpkgs, ... }@inputs: {
    nixosConfigurations.example = nixpkgs.lib.nixosSystem {
      specialArgs.inputs = inputs;
      modules = [ ./mymodule.nix ];
    };
  };
}

And in mymodule.nix, I can get the inputs again from the NixOS module arguments:

{ config, pkgs, inputs, ... }:
{
  imports = [
    "${inputs.nixpkgs-unstable}/nixos/modules/services/monitoring/netdata.nix";
  ];
}

If you want to inspect what other attributes are available for your input flakes, I would suggest using nix-repl:

nix-repl> :lf .
Added 18 variables.

nix-repl> inputs.nixpkgs
{ _type = "flake"; checks = { ... }; htmlDocs = { ... }; inputs = { ... }; lastModified = 1691464053; lastModifiedDate = "20230808030733"; legacyPackages = { ... }; lib = { ... }; narHash = "sha256-D21ctOBjr2Y3vOFRXKRoFr6uNBvE8q5jC4RrMxRZXTM="; nixosModules = { ... }; outPath = "/nix/store/qx67jipw01zps1rqgmmpl7as1irff275-source"; outputs = { ... }; rev = "844ffa82bbe2a2779c86ab3a72ff1b4176cec467"; shortRev = "844ffa8"; sourceInfo = { ... }; }
2 Likes

This details one way to do it:

The specialArgs way of doing it instead of an overlay is what I use now, but I used the way described in that URL (an overlay) without issue for a good while.

1 Like

Thanks all! So the solution is twofold: interpolate the flake to get the path, and pass the flake as module attributes.

The specialArgs approach is great, I didn’t know about it, but it’s very undiscoverable and in the modules also provides magic attributes which is bad for me in the future that forgot about them. I’ll name those added arguments like specialArgs.specialArgs-inputs = inputs; so that it’s clearer in the module sources.

1 Like

I hate to keep giving my own links, but this may be helpful when it comes to using specialArgs

2 Likes

The links are great, keep doing it :slight_smile:

BTW it’s funny to me that your entire knowledge base is inside a “hidden” git repo. (starts with dot)

1 Like

For future reference, this is how I use netdata unstable in my 23.05 flake-based install (simplified):

  # flake.nix
  outputs = { nixpkgs, ... }@flakeInputs: rec {
    system = "x86_64-linux";
    nixosConfigurations.example = nixpkgs.lib.nixosSystem {
      specialArgs = { inherit system flakeInputs; };
      modules = [ ./mymodule.nix ];
    };
  };
  # mymodule.nix
  { specialArgs, ... }: {
    imports = let
      inherit (specialArgs) system flakeInputs;
      inherit (flakeInputs) nixpkgs-unstable;
      unstablePkgs = nixpkgs-unstable.legacyPackages.${system};
      inherit (unstablePkgs) netdata;
    in [
      # Override netdata from nixpkgs-unstable
      {
        disabledModules = [ "services/monitoring/netdata.nix" ];
        nixpkgs.overlays = [ (self: super: { inherit netdata; }) ];
      }
      (nixpkgs-unstable + /nixos/modules/services/monitoring/netdata.nix)
    ];
  };
2 Likes

I recently also covered this in Nix Hour #41 :smiley:

3 Likes

Wouldn’t it make sense for the nixpkgs repo’s flake.nix to expose all the modules, rather than just the two it does now?

1 Like

Since these changes are often temporary (i.e. when the stable releases advance, I want to get rid of them) I often prefer to keep them localized to flake.nix, which is where the input bump will take place. This way I also avoid the specialArgs shenanigans.

So in my flake.nix I have something like:

     nixosConfigurations.foo = nixpkgs.lib.nixosSystem {
        modules = [
          # TODO: remove once we switch to 24.05
          {
            imports = [
              (nixos-unstable + "/nixos/modules/services/matrix/maubot.nix")
            ];

            nixpkgs.overlays = [
              (final: prev: {
                maubot = nixos-unstable.legacyPackages.${system}.maubot;
              })
            ];
          }
      # ...

This way configuration.nix can remain unchanged when I bump my input to 24.05.

2 Likes

Can I somehow set this up such that the added module runs in the context of the unstable repository?
The module I am trying to add depends on other modules and packages that are only present in unstable.

It seems to me that the module argument should have the unstable pkgs, and as such it can’t be part of the regular module loading :-/