summaryrefslogtreecommitdiffstats
path: root/nixos/lib/eval-config.nix
blob: 8c45412bda7b1bf006951b1313b6f3ee3626932a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# From an end-user configuration file (`configuration.nix'), build a NixOS
# configuration object (`config') from which we can retrieve option
# values.

# !!! Please think twice before adding to this argument list!
# Ideally eval-config.nix would be an extremely thin wrapper
# around lib.evalModules, so that modular systems that have nixos configs
# as subcomponents (e.g. the container feature, or nixops if network
# expressions are ever made modular at the top level) can just use
# types.submodule instead of using eval-config.nix
evalConfigArgs@{
  # !!! system can be set modularly, would be nice to remove,
  #     however, removing or changing this default is too much
  #     of a breaking change. To set it modularly, pass `null`.
  system ? builtins.currentSystem,
  # !!! is this argument needed any more? The pkgs argument can
  # be set modularly anyway.
  pkgs ? null,
  # !!! what do we gain by making this configurable?
  #     we can add modules that are included in specialisations, regardless
  #     of inheritParentConfig.
  baseModules ? import ../modules/module-list.nix,
  # !!! See comment about args in lib/modules.nix
  specialArgs ? { },
  modules,
  modulesLocation ? (builtins.unsafeGetAttrPos "modules" evalConfigArgs).file or null,
  prefix ? [ ],
  lib ? import ../../lib,
  extraModules ? [ ],
}:

let
  inherit (lib) optional warn;

  evalModulesMinimal =
    (import ./default.nix {
      inherit lib;
      # Implicit use of feature is noted in implementation.
      featureFlags.minimalModules = { };
    }).evalModules;

  pkgsModule = rec {
    _file = ./eval-config.nix;
    key = _file;
    config = lib.mkMerge (
      (optional (system != null) {
        # Explicit `nixpkgs.system` or `nixpkgs.localSystem` should override
        # this.  Since the latter defaults to the former, the former should
        # default to the argument. That way this new default could propagate all
        # they way through, but has the last priority behind everything else.
        nixpkgs.system = lib.mkDefault system;
      })
      ++ (optional (pkgs != null) {
        # This should be default priority, so it conflicts with any user-defined pkgs.
        nixpkgs.pkgs = pkgs;
      })
    );
  };

  withWarnings =
    if specialArgs ? pkgs then
      warn ''
        You have set specialArgs.pkgs, which means that options like nixpkgs.config
        and nixpkgs.overlays will be ignored. If you wish to reuse an already created
        pkgs, which you know is configured correctly for this NixOS configuration,
        please import the `nixosModules.readOnlyPkgs` module from the nixpkgs flake or
        `(modulesPath + "/misc/nixpkgs/read-only.nix"), and set `{ nixpkgs.pkgs = <your pkgs>; }`.
        This properly disables the ignored options to prevent future surprises.
      ''
    else
      x: x;

  userModules =
    # Add the invoking file (or specified modulesLocation) as error message location
    # for modules that don't have their own locations; presumably inline modules.
    if modulesLocation == null then
      modules
    else
      map (lib.setDefaultModuleLocation modulesLocation) modules;

  noUserModules = evalModulesMinimal {
    inherit prefix specialArgs;
    modules =
      baseModules
      ++ extraModules
      ++ [
        pkgsModule
        modulesModule
      ];
  };

  # Extra arguments that are useful for constructing a similar configuration.
  modulesModule = {
    config = {
      _module.args = {
        inherit
          noUserModules
          baseModules
          extraModules
          modules
          ;
      };
    };
  };

  nixosWithUserModules = noUserModules.extendModules { modules = userModules; };

  withExtraAttrs =
    configuration:
    configuration
    // {
      inherit (configuration._module.args) pkgs;
      inherit lib;
      extendModules = args: withExtraAttrs (configuration.extendModules args);
    };
in
withWarnings (withExtraAttrs nixosWithUserModules)