`nixpkgs.pkgs` not working as expected, nixos config as part of recursive package set

I have a recursive package set (by-name style, using lib.packagesFromDirectoryRecursive) and I want that set to contain both packages and nixos configuration (using pkgs.nixos). I want the nixos configs in the set to be able to use packages from that same set. Also there are packages that depend on nixos configs, which is why I can’t define the package set first, then put that in a top-level overlay and define my nixos configs based on that.

To do that, I tried to set nixpkgs.pkgs = pkgs'; in the nixos config, where pkgs' is the final package set, containing both the original pkgs of the nixpkgs evaluation and the packages from my set.

{
  inputs.nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
  outputs =
    { nixpkgs, ... }:
    let
      pkgs = import nixpkgs { system = "x86_64-linux"; };
      foo = pkgs.runCommand "foo" { } ''echo "this is foo and fails!"'';
      pkgs' = pkgs // { inherit foo; };
    in
    {
      nixosConfigurations.bar = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          ({ pkgs /* this pkgs should contain foo */, ... }: {
              nixpkgs.pkgs = pkgs';
              # This works
              # nixpkgs.overlays = [ (self: super: { inherit foo; }) ];
              environment.systemPackages = [ pkgs.foo ];

              # Satisfy assertions.
              boot.loader.systemd-boot.enable = true;
              fileSystems."/" = {
                device = "/dev/sda1";
                fsType = "ext4";
              };
            }
          )
        ];
      };
    };
}

Building that gives me error: attribute 'foo' missing, however nixpkgs.overlays works as expected.
Any idea how to get this working?

This is how I would do it:

  • Create some base packages with package args that can be controlled by NixOS config
  • Add them into the pkgs instance via an overlay
  • Create a .package option in the respective NixOS module(s)
  • Override said args in the NixOS config (you can look at modules that have e.g. .finalPackage options for examples of this in action)

There is also pkgs.config which is a bit clunky but allows you to configure multiple packages at once if they share some options (and assuming they use config in their package expression of course). You can control the values that are set via the nixpkgs.config option.

Not sure how this would solve the problem. Also, I’m not looking for a hacky solution (I got one, using nixpkgs.overlays) but I don’t want to add every package manually to be consumed inside the config. You suggestion, as I understand it, would include even more manual work.

What do you mean “manually add”?

Anything that is on a per-package scale. But maybe I misunderstand your proposal. Can you try to show what you mean based on the example above?