about summary refs log tree commit diff
path: root/nixos/lib
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2022-06-06 23:46:39 +0200
committerRobert Hensing <robert@roberthensing.nl>2022-09-21 10:55:12 +0100
commit9e4277b970d96ddc1c2bbe4686757ae761baa18a (patch)
tree13074f8836b3605029fa455ce72426e53776f1c2 /nixos/lib
parent0691b450b1d1c5e2846e23fd145e7c08d242c0e1 (diff)
nixos/testing/network.nix: Fix for specialisations and specialArgs.name
Before this, it relied on being able to `imports` from the `name`
module argument, which wasn't really necessary and required a
potentially quite breaking change. We can revert that now.
Diffstat (limited to 'nixos/lib')
-rw-r--r--nixos/lib/testing/network.nix149
1 files changed, 93 insertions, 56 deletions
diff --git a/nixos/lib/testing/network.nix b/nixos/lib/testing/network.nix
index dfdd9b8314a29..c87abee30c93e 100644
--- a/nixos/lib/testing/network.nix
+++ b/nixos/lib/testing/network.nix
@@ -1,75 +1,112 @@
 { lib, nodes, ... }:
 
-with lib;
+let
+  inherit (lib)
+    attrNames concatMap concatMapStrings flip forEach head
+    listToAttrs mkDefault mkOption nameValuePair optionalString
+    range types zipListsWith zipLists
+    ;
 
+  nodeNumbers =
+    listToAttrs
+      (zipListsWith
+        nameValuePair
+        (attrNames nodes)
+        (range 1 254)
+      );
 
-let
-  machines = attrNames nodes;
+  networkModule = { config, nodes, pkgs, ... }:
+    let
+      interfacesNumbered = zipLists config.virtualisation.vlans (range 1 255);
+      interfaces = forEach interfacesNumbered ({ fst, snd }:
+        nameValuePair "eth${toString snd}" {
+          ipv4.addresses =
+            [{
+              address = "192.168.${toString fst}.${toString config.virtualisation.test.nodeNumber}";
+              prefixLength = 24;
+            }];
+        });
 
-  machinesNumbered = zipLists machines (range 1 254);
+      networkConfig =
+        {
+          networking.hostName = mkDefault config.virtualisation.test.nodeName;
 
-  nodes_ = forEach machinesNumbered (m: nameValuePair m.fst
-    [
-      ({ config, nodes, pkgs, ... }:
-        let
-          interfacesNumbered = zipLists config.virtualisation.vlans (range 1 255);
-          interfaces = forEach interfacesNumbered ({ fst, snd }:
-            nameValuePair "eth${toString snd}" {
-              ipv4.addresses =
-                [{
-                  address = "192.168.${toString fst}.${toString m.snd}";
-                  prefixLength = 24;
-                }];
-            });
+          networking.interfaces = listToAttrs interfaces;
 
-          networkConfig =
-            {
-              networking.hostName = mkDefault m.fst;
+          networking.primaryIPAddress =
+            optionalString (interfaces != [ ]) (head (head interfaces).value.ipv4.addresses).address;
 
-              networking.interfaces = listToAttrs interfaces;
+          # Put the IP addresses of all VMs in this machine's
+          # /etc/hosts file.  If a machine has multiple
+          # interfaces, use the IP address corresponding to
+          # the first interface (i.e. the first network in its
+          # virtualisation.vlans option).
+          networking.extraHosts = flip concatMapStrings (attrNames nodes)
+            (m':
+              let config = nodes.${m'}; in
+              optionalString (config.networking.primaryIPAddress != "")
+                ("${config.networking.primaryIPAddress} " +
+                  optionalString (config.networking.domain != null)
+                    "${config.networking.hostName}.${config.networking.domain} " +
+                  "${config.networking.hostName}\n"));
 
-              networking.primaryIPAddress =
-                optionalString (interfaces != [ ]) (head (head interfaces).value.ipv4.addresses).address;
+          virtualisation.qemu.options =
+            let qemu-common = import ../qemu-common.nix { inherit lib pkgs; };
+            in
+            flip concatMap interfacesNumbered
+              ({ fst, snd }: qemu-common.qemuNICFlags snd fst config.virtualisation.test.nodeNumber);
+        };
 
-              # Put the IP addresses of all VMs in this machine's
-              # /etc/hosts file.  If a machine has multiple
-              # interfaces, use the IP address corresponding to
-              # the first interface (i.e. the first network in its
-              # virtualisation.vlans option).
-              networking.extraHosts = flip concatMapStrings machines
-                (m':
-                  let config = getAttr m' nodes; in
-                  optionalString (config.networking.primaryIPAddress != "")
-                    ("${config.networking.primaryIPAddress} " +
-                      optionalString (config.networking.domain != null)
-                        "${config.networking.hostName}.${config.networking.domain} " +
-                      "${config.networking.hostName}\n"));
+    in
+    {
+      key = "ip-address";
+      config = networkConfig // {
+        # Expose the networkConfig items for tests like nixops
+        # that need to recreate the network config.
+        system.build.networkConfig = networkConfig;
+      };
+    };
 
-              virtualisation.qemu.options =
-                let qemu-common = import ../qemu-common.nix { inherit lib pkgs; };
-                in
-                flip concatMap interfacesNumbered
-                  ({ fst, snd }: qemu-common.qemuNICFlags snd fst m.snd);
-            };
+  nodeNumberModule = (regular@{ config, name, ... }: {
+    options = {
+      virtualisation.test.nodeName = mkOption {
+        internal = true;
+        default = name;
+        # We need to force this in specilisations, otherwise it'd be
+        # readOnly = true;
+        description = ''
+          The `name` in `nodes.<name>`; stable across `specialisations`.
+        '';
+      };
+      virtualisation.test.nodeNumber = mkOption {
+        internal = true;
+        type = types.int;
+        readOnly = true;
+        default = nodeNumbers.${config.virtualisation.test.nodeName};
+        description = ''
+          A unique number assigned for each node in `nodes`.
+        '';
+      };
 
-        in
-        {
-          key = "ip-address";
-          config = networkConfig // {
-            # Expose the networkConfig items for tests like nixops
-            # that need to recreate the network config.
-            system.build.networkConfig = networkConfig;
+      # specialisations override the `name` module argument,
+      # so we push the real `virtualisation.test.nodeName`.
+      specialisation = mkOption {
+        type = types.attrsOf (types.submodule {
+          options.configuration = mkOption {
+            type = types.submodule ({
+              config.virtualisation.test.nodeName =
+                # assert regular.config.virtualisation.test.nodeName != "configuration";
+                regular.config.virtualisation.test.nodeName;
+            });
           };
-        }
-      )
-    ]);
+        });
+      };
+    };
+  });
 
-  extraNodeConfigs = lib.listToAttrs nodes_;
 in
 {
   config = {
-    defaults = { config, name, ... }: {
-      imports = extraNodeConfigs.${name};
-    };
+    defaults = { imports = [ networkModule nodeNumberModule ]; };
   };
 }