at master 7.9 kB view raw
1testModuleArgs@{ 2 config, 3 lib, 4 hostPkgs, 5 nodes, 6 options, 7 ... 8}: 9 10let 11 inherit (lib) 12 literalExpression 13 literalMD 14 mapAttrs 15 mkDefault 16 mkIf 17 mkMerge 18 mkOption 19 mkForce 20 optional 21 optionalAttrs 22 types 23 ; 24 25 inherit (hostPkgs.stdenv) hostPlatform; 26 27 guestSystem = 28 if hostPlatform.isLinux then 29 hostPlatform.system 30 else 31 let 32 hostToGuest = { 33 "x86_64-darwin" = "x86_64-linux"; 34 "aarch64-darwin" = "aarch64-linux"; 35 }; 36 37 supportedHosts = lib.concatStringsSep ", " (lib.attrNames hostToGuest); 38 39 message = "NixOS Test: don't know which VM guest system to pair with VM host system: ${hostPlatform.system}. Perhaps you intended to run the tests on a Linux host, or one of the following systems that may run NixOS tests: ${supportedHosts}"; 40 in 41 hostToGuest.${hostPlatform.system} or (throw message); 42 43 baseOS = import ../eval-config.nix { 44 inherit lib; 45 system = null; # use modularly defined system 46 inherit (config.node) specialArgs; 47 modules = [ config.defaults ]; 48 baseModules = (import ../../modules/module-list.nix) ++ [ 49 ./nixos-test-base.nix 50 { 51 key = "nodes"; 52 _module.args.nodes = config.nodesCompat; 53 } 54 ( 55 { config, ... }: 56 { 57 virtualisation.qemu.package = testModuleArgs.config.qemu.package; 58 virtualisation.host.pkgs = hostPkgs; 59 } 60 ) 61 ( 62 { options, ... }: 63 { 64 key = "nodes.nix-pkgs"; 65 config = optionalAttrs (!config.node.pkgsReadOnly) ( 66 mkIf (!options.nixpkgs.pkgs.isDefined) { 67 # TODO: switch to nixpkgs.hostPlatform and make sure containers-imperative test still evaluates. 68 nixpkgs.system = guestSystem; 69 } 70 ); 71 } 72 ) 73 testModuleArgs.config.extraBaseModules 74 ]; 75 }; 76 77 # TODO (lib): Dedup with run.nix, add to lib/options.nix 78 mkOneUp = opt: f: lib.mkOverride (opt.highestPrio - 1) (f opt.value); 79 80in 81 82{ 83 84 options = { 85 sshBackdoor = { 86 enable = mkOption { 87 default = config.enableDebugHook; 88 defaultText = lib.literalExpression "config.enableDebugHook"; 89 type = types.bool; 90 description = "Whether to turn on the VSOCK-based access to all VMs. This provides an unauthenticated access intended for debugging."; 91 }; 92 vsockOffset = mkOption { 93 default = 2; 94 type = types.ints.between 2 4294967296; 95 description = '' 96 This field is only relevant when multiple users run the (interactive) 97 driver outside the sandbox and with the SSH backdoor activated. 98 The typical symptom for this being a problem are error messages like this: 99 `vhost-vsock: unable to set guest cid: Address already in use` 100 101 This option allows to assign an offset to each vsock number to 102 resolve this. 103 104 This is a 32bit number. The lowest possible vsock number is `3` 105 (i.e. with the lowest node number being `1`, this is 2+1). 106 ''; 107 }; 108 }; 109 110 node.type = mkOption { 111 type = types.raw; 112 default = baseOS.type; 113 internal = true; 114 }; 115 116 nodes = mkOption { 117 type = types.lazyAttrsOf config.node.type; 118 visible = "shallow"; 119 description = '' 120 An attribute set of NixOS configuration modules. 121 122 The configurations are augmented by the [`defaults`](#test-opt-defaults) option. 123 124 They are assigned network addresses according to the `nixos/lib/testing/network.nix` module. 125 126 A few special options are available, that aren't in a plain NixOS configuration. See [Configuring the nodes](#sec-nixos-test-nodes) 127 ''; 128 }; 129 130 defaults = mkOption { 131 description = '' 132 NixOS configuration that is applied to all [{option}`nodes`](#test-opt-nodes). 133 ''; 134 type = types.deferredModule; 135 default = { }; 136 }; 137 138 extraBaseModules = mkOption { 139 description = '' 140 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). 141 ''; 142 type = types.deferredModule; 143 default = { }; 144 }; 145 146 node.pkgs = mkOption { 147 description = '' 148 The Nixpkgs to use for the nodes. 149 150 Setting this will make the `nixpkgs.*` options read-only, to avoid mistakenly testing with a Nixpkgs configuration that diverges from regular use. 151 ''; 152 type = types.nullOr types.pkgs; 153 default = null; 154 defaultText = literalMD '' 155 `null`, so construct `pkgs` according to the `nixpkgs.*` options as usual. 156 ''; 157 }; 158 159 node.pkgsReadOnly = mkOption { 160 description = '' 161 Whether to make the `nixpkgs.*` options read-only. This is only relevant when [`node.pkgs`](#test-opt-node.pkgs) is set. 162 163 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. 164 ''; 165 type = types.bool; 166 default = config.node.pkgs != null; 167 defaultText = literalExpression ''node.pkgs != null''; 168 }; 169 170 node.specialArgs = mkOption { 171 type = types.lazyAttrsOf types.raw; 172 default = { }; 173 description = '' 174 An attribute set of arbitrary values that will be made available as module arguments during the resolution of module `imports`. 175 176 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. 177 ''; 178 }; 179 180 nodesCompat = mkOption { 181 internal = true; 182 description = '' 183 Basically `_module.args.nodes`, but with backcompat and warnings added. 184 185 This will go away. 186 ''; 187 }; 188 }; 189 190 config = { 191 _module.args.nodes = config.nodesCompat; 192 nodesCompat = mapAttrs ( 193 name: config: 194 config 195 // { 196 config = 197 lib.warnIf (lib.oldestSupportedReleaseIsAtLeast 2211) 198 "Module argument `nodes.${name}.config` is deprecated. Use `nodes.${name}` instead." 199 config; 200 } 201 ) config.nodes; 202 203 passthru.nodes = config.nodesCompat; 204 205 extraDriverArgs = mkIf config.sshBackdoor.enable [ 206 "--dump-vsocks=${toString config.sshBackdoor.vsockOffset}" 207 ]; 208 209 defaults = mkMerge [ 210 (mkIf config.node.pkgsReadOnly { 211 nixpkgs.pkgs = config.node.pkgs; 212 imports = [ ../../modules/misc/nixpkgs/read-only.nix ]; 213 }) 214 (mkIf config.sshBackdoor.enable ( 215 let 216 inherit (config.sshBackdoor) vsockOffset; 217 in 218 { config, ... }: 219 { 220 services.openssh = { 221 enable = true; 222 settings = { 223 PermitRootLogin = "yes"; 224 PermitEmptyPasswords = "yes"; 225 }; 226 }; 227 228 security.pam.services.sshd = { 229 allowNullPassword = true; 230 }; 231 232 virtualisation.qemu.options = [ 233 "-device vhost-vsock-pci,guest-cid=${ 234 toString (config.virtualisation.test.nodeNumber + vsockOffset) 235 }" 236 ]; 237 } 238 )) 239 ]; 240 241 # Docs: nixos/doc/manual/development/writing-nixos-tests.section.md 242 /** 243 See https://nixos.org/manual/nixos/unstable#sec-override-nixos-test 244 */ 245 passthru.extendNixOS = 246 { 247 module, 248 specialArgs ? { }, 249 }: 250 config.passthru.extend { 251 modules = [ 252 { 253 extraBaseModules = module; 254 node.specialArgs = mkOneUp options.node.specialArgs (_: specialArgs); 255 } 256 ]; 257 }; 258 259 }; 260}