Nixos-rebuild precedence /etc/nixos and -f vs -I

Hi,

until recently I had symlinks for /etc/nixos –> gitrepo1and just used ansible to run nixos-rebuild on every machine (_shame_?).

For most systems I switched to colmena and everything works as expected. However, some machines (work workstations) I deploy locally from gitrepo2 and neither

sudo nixos-rebuild -f $PWD -A nixosConfigurations.<host> switch

nor

sudo nixos-rebuild -I nixos-config=$(pwd)/default.nix -A nixosConfigurations.<host> switch

changed the system configuration. In fact it seemed to still use the configuration from /etc/nixos.

After deleting /etc/nixos both commands seem to do the trick. Why could that be (I couldn’t reproduce it interestingly by readding /etc/nixos symlink even though I tried rebuilding like 10 times before with different variation, e.g. absolut paths)?

And man nixos-build does not give me documentation for the -f and -I flags, where can I find it?

For -I, refer to man nix-build. This is not immediately obvious from the manpage for nixos-rebuild, but -I is listed as a “builder option”.

The manpage for nix-build explains -I: it is used to add paths to NIX_PATH, which is a search path (same concept as a normal shell PATH) for various nix-related things; your config, the version of nixpkgs to use when referring to <nixpkgs> (although channels are prioritised here AFAIK), etc. The manpage claims that this should take precedence over both the nix-path config setting and the NIX_PATH environment variable, but the fact that it used /etc/nixos over what you provided seems to contradict this?

man nixos-rebuild does specify -f:

--file path, -f path
           Enable  and  build the NixOS system from the specified file. The file must evaluate to an attribute set, and it must contain a valid NixOS
           configuration at attribute attrPath. This is useful for building a NixOS system from a nix file that is not a flake or a NixOS  configura‐
           tion  module.  Attribute  set  a  with  valid  NixOS  configuration  can  be made using nixos function in nixpkgs or importing and calling
           nixos/lib/eval-config.nix from nixpkgs. If specified without --attr option, builds the configuration from the top-level attribute  of  the
           file.

This probably isn’t what you’re looking for, since it requires that the file (or attribute within the attrset in the file, if you pass -A) resolves to an already-evaluated config (ie. you would generally have to use one of the functions mentioned to evaluate your top-level module(s) yourself).

Other things:

  • I don’t know if mixing -A and -I is specified? The manpage claims that -A “uses default.nix in current directory” if -f is not given, although this doesn’t seem to match your experience…
  • When you use nixosConfigurations as an attribute, I assume this is unrelated to the flake output of the same name? Make sure you aren’t using -I and -f/-A with flakes.

Thank you!

Maybe to clear thing up, my default.nix in root of path I refer to with -f down below.

I am not using flakes, I am using [lon](GitHub - nikstur/lon: Lock & update Nix dependencies · GitHub) for locking.

So yes, nixosConfigurations is not the flake output.

{ self ? (import ./. { })
, sources ? (import ./lon.nix)
, nixpkgs ? sources.nixos-stable
, ...
}:
let
  # Helper function to create a NixOS configuration
  nixos = nixpkgs: configuration: extraModules:
    import "${nixpkgs}/nixos/lib/eval-config.nix" {
      modules = [ configuration ] ++ extraModules;
      specialArgs = {
        inherit nixpkgs self sources;
        pkgsUnstable = import sources.nixos-unstable { };
      };
    };
in
{
  inherit self sources;

  outPath = ./.;

  # Host configurations
  nixosConfigurations = {
    laptop = nixos nixpkgs
      ./laptop/nixos/configuration.nix
      [
        ./laptop/nixos/hardware-configuration.nix
      ];
  };
}

Ah, thank you for the clarification.

With a setup like this, using -f and -A is correct.

1 Like