at 22.05-pre 4.4 kB view raw
1{ system 2, # Use a minimal kernel? 3 minimal ? false 4, # Ignored 5 config ? null 6, # Nixpkgs, for qemu, lib and more 7 pkgs, lib 8, # !!! See comment about args in lib/modules.nix 9 specialArgs ? {} 10, # NixOS configuration to add to the VMs 11 extraConfigurations ? [] 12}: 13 14with lib; 15 16rec { 17 18 inherit pkgs; 19 20 # Build a virtual network from an attribute set `{ machine1 = 21 # config1; ... machineN = configN; }', where `machineX' is the 22 # hostname and `configX' is a NixOS system configuration. Each 23 # machine is given an arbitrary IP address in the virtual network. 24 buildVirtualNetwork = 25 nodes: let nodesOut = mapAttrs (n: buildVM nodesOut) (assignIPAddresses nodes); in nodesOut; 26 27 28 buildVM = 29 nodes: configurations: 30 31 import ./eval-config.nix { 32 inherit system specialArgs; 33 modules = configurations ++ extraConfigurations; 34 baseModules = (import ../modules/module-list.nix) ++ 35 [ ../modules/virtualisation/qemu-vm.nix 36 ../modules/testing/test-instrumentation.nix # !!! should only get added for automated test runs 37 { key = "no-manual"; documentation.nixos.enable = false; } 38 { key = "no-revision"; 39 # Make the revision metadata constant, in order to avoid needless retesting. 40 # The human version (e.g. 21.05-pre) is left as is, because it is useful 41 # for external modules that test with e.g. nixosTest and rely on that 42 # version number. 43 config.system.nixos.revision = mkForce "constant-nixos-revision"; 44 } 45 { key = "nodes"; _module.args.nodes = nodes; } 46 ] ++ optional minimal ../modules/testing/minimal-kernel.nix; 47 }; 48 49 50 # Given an attribute set { machine1 = config1; ... machineN = 51 # configN; }, sequentially assign IP addresses in the 192.168.1.0/24 52 # range to each machine, and set the hostname to the attribute name. 53 assignIPAddresses = nodes: 54 55 let 56 57 machines = attrNames nodes; 58 59 machinesNumbered = zipLists machines (range 1 254); 60 61 nodes_ = forEach machinesNumbered (m: nameValuePair m.fst 62 [ ( { config, nodes, ... }: 63 let 64 interfacesNumbered = zipLists config.virtualisation.vlans (range 1 255); 65 interfaces = forEach interfacesNumbered ({ fst, snd }: 66 nameValuePair "eth${toString snd}" { ipv4.addresses = 67 [ { address = "192.168.${toString fst}.${toString m.snd}"; 68 prefixLength = 24; 69 } ]; 70 }); 71 72 networkConfig = 73 { networking.hostName = mkDefault m.fst; 74 75 networking.interfaces = listToAttrs interfaces; 76 77 networking.primaryIPAddress = 78 optionalString (interfaces != []) (head (head interfaces).value.ipv4.addresses).address; 79 80 # Put the IP addresses of all VMs in this machine's 81 # /etc/hosts file. If a machine has multiple 82 # interfaces, use the IP address corresponding to 83 # the first interface (i.e. the first network in its 84 # virtualisation.vlans option). 85 networking.extraHosts = flip concatMapStrings machines 86 (m': let config = (getAttr m' nodes).config; in 87 optionalString (config.networking.primaryIPAddress != "") 88 ("${config.networking.primaryIPAddress} " + 89 optionalString (config.networking.domain != null) 90 "${config.networking.hostName}.${config.networking.domain} " + 91 "${config.networking.hostName}\n")); 92 93 virtualisation.qemu.options = 94 let qemu-common = import ../lib/qemu-common.nix { inherit lib pkgs; }; 95 in flip concatMap interfacesNumbered 96 ({ fst, snd }: qemu-common.qemuNICFlags snd fst m.snd); 97 }; 98 99 in 100 { key = "ip-address"; 101 config = networkConfig // { 102 # Expose the networkConfig items for tests like nixops 103 # that need to recreate the network config. 104 system.build.networkConfig = networkConfig; 105 }; 106 } 107 ) 108 (getAttr m.fst nodes) 109 ] ); 110 111 in listToAttrs nodes_; 112 113}