How to pass pkgs to openwrt-imagebuilder in a pure way?

Hi all, I am new to NixOS and have a grand plan to put a router in a VM in a VM.

For context I am using a NixOS VM on my proxmox server to practice and learn Nix and I am trying to use openwrt-imagebuilder and NixVirt flakes, and I am currently stuck on the first step of utilizing the openwrt-imagebuilder flake: https://github.com/astro/nix-openwrt-imagebuilder

The issue I am encountering is that when I run my nixos-rebuild switch command, it says I have to run in impure mode, as I have not provided pkgs to the openwrt-imagebuilder flake. When I put inherit pkgs in the config that is passed into the build command for that flake, I get an infinite recursion error for pkgs.here is the file:

{pkgs, nixvirt, inputs, ...}:

let
  config = {
    release = "24.10.4";
    target = "x86";
    variant = "64";
    profile = "generic";
    packages = [
      "luci"
      "luci-base"
      "luci-mod-admin-full"
      "luci-theme-bootstrap"
      "luci-app-firewall"
      "luci-app-opkg"
      "luci-ssl"
      "adblock"
      "luci-app-adblock"
      "kmod-tun"
      "ca-certificates"
      "ca-bundle"
      "libustream-openssl"
      "curl"
      "wget-ssl"
      "bash"
      "htop"
      "nano"
      "coreutils"
      "coreutils-base64"
      "tcpdump-mini"
      "bind-dig"
      "ip-full"
    ];

    disabledServices = [];

    files = pkgs.runCommand "image-files" {} ''
          mkdir -p $out/etc/uci-defaults
          cat > $out/etc/uci-defaults/99-custom <<EOF
          uci -q batch << EOI
          set system.@system[0].hostname='nixrouter'
          commit
          EOI
          EOF
        '';
  };

  openwrtImg = inputs.openwrt-imagebuilder.lib.build config;
  
in "${openwrtImg}"

Here is the error when I place inherit pkgs; in config above release:

warning: Git tree '/etc/nixos' is dirty
error:
       … while calling the 'seq' builtin
         at /nix/store/02hdlzb9xkjvpl4kdia3snvccdhmm893-source/lib/modules.nix:359:18:
          358|         options = checked options;
          359|         config = checked (removeAttrs config [ "_module" ]);
             |                  ^
          360|         _module = checked (config._module);

       … while evaluating a branch condition
         at /nix/store/02hdlzb9xkjvpl4kdia3snvccdhmm893-source/lib/modules.nix:295:9:
          294|       checkUnmatched =
          295|         if config._module.check && config._module.freeformType == null && merged.unmatchedDefns != [ ] then
             |         ^
          296|           let

       … while evaluating the module argument `pkgs' in "/nix/store/s6k9x1nn3gml03lsad23fpg6aj813j7b-source/network/openwrt.nix":

       (stack trace truncated; use '--show-trace' to show the full, detailed trace)

       error: infinite recursion encountered
       at /nix/store/02hdlzb9xkjvpl4kdia3snvccdhmm893-source/lib/modules.nix:652:66:
          651|       extraArgs = mapAttrs (
          652|         name: _: addErrorContext (context name) (args.${name} or config._module.args.${name})
             |                                                                  ^
          653|       ) (functionArgs f);

My goal is to run the build successfully in a “pure” fashion, I guess that means without the look up in openwrt-imagebuilder, which I believe happens when pkgs is not supplied directly.

I have tried pkgs = pkgs, inherit pkgs, and pkgs = inputs.nixpkgs.

Oh and here is my flake.nix:

{
  description = "A simple NixOS flake";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
    
    helix.url = "github:helix-editor/helix/master";
    
    openwrt-imagebuilder = {
      url = "github:astro/nix-openwrt-imagebuilder";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    
    nixvirt = {
      url = "https://flakehub.com/f/AshleyYakeley/NixVirt/*.tar.gz";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, ... }@inputs: {
    nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
      specialArgs = {inherit inputs;};
      modules = [
        ./configuration.nix
        ./network/openwrt.nix
      ];
    };
  };
}

https://github.com/astro/nix-openwrt-imagebuilder?tab=readme-ov-file#usage-with-nix-flakes

Also, your first file isn’t a module, I would not use it that way. It’s a package, so you should set it the way the readme mentions.

1 Like

Okay, I think that’s what my confusion was. So if I pull from a flake and want to use it, it needs to be in that inputs/outputs format? and whatever derivation is produced from that file can be imported into a module I presume so I can pass the image it produces to nixvirt to build my VM?

Different flakes have different outputs, you’ll have to use your best guess based off of context. I know that’s vague but without a specific example, that’s as much as I think I can explain without confusing further.

No, it’s a package.
At best you could put it in a package list, if you want to build this package as part of your config - but then this package would be in a location that’s probably not that helpful to you.

It’s most straightforward to just keep it as a separate output and build it via nix build <flake>#<output-name> as you need it.

So your flake.nix should have a structure like

{
  inputs = {
    # flake inputs here ...
  };

  outputs = { self, nixpkgs, ... }@inputs: {
    nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
      specialArgs = {inherit inputs;};
      modules = [
        ./configuration.nix
      ];
    };

    packages.x86_64-linux.my-router = # package stuff goes here...
  };
}
1 Like

Ohhhh okay, I think I understand a bit better, so I’d run it with nix-build command and save the output somewhere useful and take that actual file and have its result somewhere for import or use or point the path to it. It’s like a utility function I use manually from the command line, not a declarative package like nginx or something that spins up a service each time I run nix-rebuild switch or something

Will give it a shot thanks so much for the prompt replies!

Btw to save you some possible typo headaches: I referred to nix build not nix-build. Both commands exist and work slightly differently - and only the former supports flakes.

https://nix.dev/manual/nix/2.32/command-ref/new-cli/nix3-build.html
https://nix.dev/manual/nix/2.32/command-ref/nix-build.html

1 Like