1testModuleArgs@{ config, lib, hostPkgs, nodes, ... }:
2
3let
4 inherit (lib)
5 literalExpression
6 literalMD
7 mapAttrs
8 mdDoc
9 mkDefault
10 mkIf
11 mkOption mkForce
12 optional
13 optionalAttrs
14 types
15 ;
16
17 baseOS =
18 import ../eval-config.nix {
19 system = null; # use modularly defined system
20 inherit (config.node) specialArgs;
21 modules = [ config.defaults ];
22 baseModules = (import ../../modules/module-list.nix) ++
23 [
24 ./nixos-test-base.nix
25 { key = "nodes"; _module.args.nodes = config.nodesCompat; }
26 ({ config, ... }:
27 {
28 virtualisation.qemu.package = testModuleArgs.config.qemu.package;
29 })
30 (optionalAttrs (!config.node.pkgsReadOnly) {
31 key = "nodes.nix-pkgs";
32 config = {
33 # Ensure we do not use aliases. Ideally this is only set
34 # when the test framework is used by Nixpkgs NixOS tests.
35 nixpkgs.config.allowAliases = false;
36 # TODO: switch to nixpkgs.hostPlatform and make sure containers-imperative test still evaluates.
37 nixpkgs.system = hostPkgs.stdenv.hostPlatform.system;
38 };
39 })
40 testModuleArgs.config.extraBaseModules
41 ];
42 };
43
44
45in
46
47{
48
49 options = {
50 node.type = mkOption {
51 type = types.raw;
52 default = baseOS.type;
53 internal = true;
54 };
55
56 nodes = mkOption {
57 type = types.lazyAttrsOf config.node.type;
58 visible = "shallow";
59 description = mdDoc ''
60 An attribute set of NixOS configuration modules.
61
62 The configurations are augmented by the [`defaults`](#test-opt-defaults) option.
63
64 They are assigned network addresses according to the `nixos/lib/testing/network.nix` module.
65
66 A few special options are available, that aren't in a plain NixOS configuration. See [Configuring the nodes](#sec-nixos-test-nodes)
67 '';
68 };
69
70 defaults = mkOption {
71 description = mdDoc ''
72 NixOS configuration that is applied to all [{option}`nodes`](#test-opt-nodes).
73 '';
74 type = types.deferredModule;
75 default = { };
76 };
77
78 extraBaseModules = mkOption {
79 description = mdDoc ''
80 NixOS configuration that, like [{option}`defaults`](#test-opt-defaults), is applied to all [{option}`nodes`](#test-opt-nodes) and can not be undone with [`specialisation.<name>.inheritParentConfig`](https://search.nixos.org/options?show=specialisation.%3Cname%3E.inheritParentConfig&from=0&size=50&sort=relevance&type=packages&query=specialisation).
81 '';
82 type = types.deferredModule;
83 default = { };
84 };
85
86 node.pkgs = mkOption {
87 description = mdDoc ''
88 The Nixpkgs to use for the nodes.
89
90 Setting this will make the `nixpkgs.*` options read-only, to avoid mistakenly testing with a Nixpkgs configuration that diverges from regular use.
91 '';
92 type = types.nullOr types.pkgs;
93 default = null;
94 defaultText = literalMD ''
95 `null`, so construct `pkgs` according to the `nixpkgs.*` options as usual.
96 '';
97 };
98
99 node.pkgsReadOnly = mkOption {
100 description = mdDoc ''
101 Whether to make the `nixpkgs.*` options read-only. This is only relevant when [`node.pkgs`](#test-opt-node.pkgs) is set.
102
103 Set this to `false` when any of the [`nodes`](#test-opt-nodes) needs to configure any of the `nixpkgs.*` options. This will slow down evaluation of your test a bit.
104 '';
105 type = types.bool;
106 default = config.node.pkgs != null;
107 defaultText = literalExpression ''node.pkgs != null'';
108 };
109
110 node.specialArgs = mkOption {
111 type = types.lazyAttrsOf types.raw;
112 default = { };
113 description = mdDoc ''
114 An attribute set of arbitrary values that will be made available as module arguments during the resolution of module `imports`.
115
116 Note that it is not possible to override these from within the NixOS configurations. If you argument is not relevant to `imports`, consider setting {option}`defaults._module.args.<name>` instead.
117 '';
118 };
119
120 nodesCompat = mkOption {
121 internal = true;
122 description = mdDoc ''
123 Basically `_module.args.nodes`, but with backcompat and warnings added.
124
125 This will go away.
126 '';
127 };
128 };
129
130 config = {
131 _module.args.nodes = config.nodesCompat;
132 nodesCompat =
133 mapAttrs
134 (name: config: config // {
135 config = lib.warnIf (lib.isInOldestRelease 2211)
136 "Module argument `nodes.${name}.config` is deprecated. Use `nodes.${name}` instead."
137 config;
138 })
139 config.nodes;
140
141 passthru.nodes = config.nodesCompat;
142
143 defaults = mkIf config.node.pkgsReadOnly {
144 nixpkgs.pkgs = config.node.pkgs;
145 imports = [ ../../modules/misc/nixpkgs/read-only.nix ];
146 };
147
148 };
149}