Build NixOS config without environment dependencies and have `nixos-option`/`nixos-rebuild` support?

You may be interested in my suggestion in this GitHub issue on pinning configuration.nix, as it solves your main question of using nixos-rebuild transparently with pinned nixpkgs/nixos.

These days I updated the solution slightly and export $NIX_PATH to match the pinned version, such that home-manager picks up the system’s nixpkgs without additional setup. You can deduce from the way nixos-config is defined that in this case per-machine configuration is organized in $PREFIX/nixos/machines/<machine>/.

It gets easier if you have only one machine, then you can just fix configuration to a file name instead of my somewhat confusing round-tripping with environment variables.

$PREFIX/nixos/default.nix:

# ideally this would be the *only* entry point to each machine, but then
# 1) this file is the same everywhere, as it imports the same relative paths
# 2) since `nixos` lives in the same repository as `nixpkgs`, and
#    `nixos-rebuild` searches `<nixpkgs/nixos>`, we have to point it at
#    `machines/$machine/nixos`, which is annoying. that is also why this file
#    lives at the toplevel and the repository around it is conveniently named
#    `nixos` (only slightly less annoying).

{
  system ? builtins.currentSystem,
  configuration ? <nixos-config>,
  ...
}:
import "${import ./common/nixpkgs.nix}/nixos" { inherit system configuration; }

$PREFIX/nixos/common/nixpkgs.nix:

fetchGit {
  name = "nixpkgs-channels";
  url = "https://github.com/NixOS/nixpkgs-channels";
  ref = "nixos-19.09";
  rev = "dae3575cee5b88de966d06b11861c602975cb23a";
}

$PREFIX/nixos/common/default.nix:

{ config, pkgs, ...}:
{
  nix.nixPath = [
    # NOTE: updated values are only available on a fresh user session
    "nixpkgs=${(import ./nixpkgs.nix)}"
    # XXX: spell out the filename for `nixos-rebuild edit` to work
    "nixos-config=${toString ../machines}/${config.networking.hostName}/default.nix"
  ];
  config.environment.systemPackages =
  let
    nixos-rebuild = pkgs.writeShellScriptBin "nixos-rebuild" ''
      exec ${config.system.build.nixos-rebuild}/bin/nixos-rebuild -I ${toString ../../.} $@
    '';
  in [ nixos-rebuild ];
}
2 Likes