Commit 7f6ea2a1 authored by Kierán Meinhardt's avatar Kierán Meinhardt
Browse files

nixos/test-driver: make /etc/hosts resolution VLAN-aware

Filter /etc/hosts entries by shared VLANs to ensure nodes resolve to
reachable interface addresses.
parent d1386a42
Loading
Loading
Loading
Loading
+33 −20
Original line number Diff line number Diff line
@@ -64,29 +64,42 @@ let
          optionalString (ipInterfaces != [ ])
            (head (head ipInterfaces).value.ipv6.addresses).address;

        # 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 = concatMapAttrsStringSep "" (
          m': config:
        # Generate /etc/hosts by only including IP addresses from VLANs that
        # both the local machine and the remote machine share. This prevents
        # machines from trying to connect via unreachable interfaces (e.g.,
        # a Management VLAN) and ensures name resolution matches the
        # actual network topology of the test.
        networking.extraHosts =
          let
            localVlans = config.virtualisation.vlans;
          in
          concatMapAttrsStringSep "" (
            mName: remoteConfig:
            let
              remoteInterfaces = remoteConfig.networking.interfaces;
              sharedIps = lib.flatten (
                lib.mapAttrsToList (
                  ifaceName: ifaceCfg:
                  let
                    remoteIfaceMeta = remoteConfig.virtualisation.allInterfaces."${ifaceName}" or { };
                    vlanId = remoteIfaceMeta.vlan or null;
                  in
                  if vlanId != null && builtins.elem vlanId localVlans then
                    builtins.map (addr: addr.address) ifaceCfg.ipv4.addresses
                    ++ builtins.map (addr: addr.address) ifaceCfg.ipv6.addresses
                  else
                    [ ]
                ) remoteInterfaces
              );
              hostnames =
                optionalString (
                config.networking.domain != null
              ) "${config.networking.hostName}.${config.networking.domain} "
              + "${config.networking.hostName}\n";
                  remoteConfig.networking.domain != null
                ) "${remoteConfig.networking.hostName}.${remoteConfig.networking.domain} "
                + "${remoteConfig.networking.hostName}\n";
            in
          optionalString (
            config.networking.primaryIPAddress != ""
          ) "${config.networking.primaryIPAddress} ${hostnames}"
          + optionalString (
            config.networking.primaryIPv6Address != ""
          ) "${config.networking.primaryIPv6Address} ${hostnames}"
            builtins.concatStringsSep "" (map (ip: "${ip} ${hostnames}") sharedIps)
          ) testModuleArgs.config.allMachines;
      };

    in
    {
      key = "network-interfaces";
+1 −1
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@
    c12.succeed("ping -c 1 c1")

    # Confirm containers in vlan 2 can talk to each other.
    # <<< c2.succeed("ping -c 1 c12")  # <<< TODO: this doesn't work because c12's "primary ip" is for vlan 1
    c2.succeed("ping -c 1 c12")
    c12.succeed("ping -c 1 c2")

    # Confirm containers in separate vlans cannot talk to each other.