From 3c4fd63f939001c46c8246d4730dad716be579c3 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Fri, 18 Dec 2015 15:43:38 +0100 Subject: [PATCH] FIX #2624 reject duplicate hostonlyifs name/IP Signed-off-by: David Gageot --- drivers/virtualbox/network.go | 38 ++++++++++++++---------------- drivers/virtualbox/network_test.go | 34 +++++++++++++++++++++----- drivers/virtualbox/virtualbox.go | 5 ++++ 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/drivers/virtualbox/network.go b/drivers/virtualbox/network.go index b61fc279ea..7768675878 100644 --- a/drivers/virtualbox/network.go +++ b/drivers/virtualbox/network.go @@ -13,9 +13,8 @@ const ( ) var ( - reHostonlyInterfaceCreated = regexp.MustCompile(`Interface '(.+)' was successfully created`) - errDuplicateHostOnlyInterfaceNetworks = errors.New("VirtualBox is configured with multiple host-only interfaces with the same IP. Please remove all of them but one.") - errNewHostOnlyInterfaceNotVisible = errors.New("The host-only interface we just created is not visible. This is a well known bug of VirtualBox. You might want to uninstall it and reinstall the version listed here: https://www.virtualbox.org/ticket/14437?cversion=0&cnum_hist=42") + reHostonlyInterfaceCreated = regexp.MustCompile(`Interface '(.+)' was successfully created`) + errNewHostOnlyInterfaceNotVisible = errors.New("The host-only interface we just created is not visible. This is a well known bug of VirtualBox. You might want to uninstall it and reinstall the version listed here: https://www.virtualbox.org/ticket/14437?cversion=0&cnum_hist=42") ) // Host-only network. @@ -75,7 +74,8 @@ func listHostOnlyNetworks(vbox VBoxManager) (map[string]*hostOnlyNetwork, error) return nil, err } - m := map[string]*hostOnlyNetwork{} + byName := map[string]*hostOnlyNetwork{} + byIP := map[string]*hostOnlyNetwork{} n := &hostOnlyNetwork{} err = parseKeyValues(out, reColonLine, func(key, val string) error { @@ -110,7 +110,19 @@ func listHostOnlyNetworks(vbox VBoxManager) (map[string]*hostOnlyNetwork, error) n.Status = val case "VBoxNetworkName": n.NetworkName = val - m[val] = n + + if _, present := byName[n.NetworkName]; present { + return fmt.Errorf("VirtualBox is configured with multiple host-only interfaces with the same name %q. Please remove one.", n.NetworkName) + } + byName[n.NetworkName] = n + + if len(n.IPv4.IP) != 0 { + if _, present := byIP[n.IPv4.IP.String()]; present { + return fmt.Errorf("VirtualBox is configured with multiple host-only interfaces with the same IP %q. Please remove one.", n.IPv4.IP) + } + byIP[n.IPv4.IP.String()] = n + } + n = &hostOnlyNetwork{} } @@ -120,7 +132,7 @@ func listHostOnlyNetworks(vbox VBoxManager) (map[string]*hostOnlyNetwork, error) return nil, err } - return m, nil + return byName, nil } func getHostOnlyNetwork(nets map[string]*hostOnlyNetwork, hostIP net.IP, netmask net.IPMask) *hostOnlyNetwork { @@ -143,10 +155,6 @@ func getOrCreateHostOnlyNetwork(hostIP net.IP, netmask net.IPMask, dhcpIP net.IP return nil, err } - if len(nets) != countUniqueIps(nets) { - return nil, errDuplicateHostOnlyInterfaceNetworks - } - hostOnlyNet := getHostOnlyNetwork(nets, hostIP, netmask) if hostOnlyNet != nil { return hostOnlyNet, nil @@ -188,16 +196,6 @@ func getOrCreateHostOnlyNetwork(hostIP net.IP, netmask net.IPMask, dhcpIP net.IP return hostOnlyNet, nil } -func countUniqueIps(nets map[string]*hostOnlyNetwork) int { - ips := map[string]bool{} - - for _, n := range nets { - ips[n.IPv4.IP.String()] = true - } - - return len(ips) -} - // DHCP server info. type dhcpServer struct { NetworkName string diff --git a/drivers/virtualbox/network_test.go b/drivers/virtualbox/network_test.go index 736974fe48..1dec2efd25 100644 --- a/drivers/virtualbox/network_test.go +++ b/drivers/virtualbox/network_test.go @@ -39,7 +39,7 @@ VBoxNetworkName: HostInterfaceNetworking-vboxnet0 Name: vboxnet1 GUID: 786f6276-656e-4174-8000-0a0027000001 DHCP: Disabled -IPAddress: 192.168.99.1 +IPAddress: 169.254.37.187 NetworkMask: 255.255.255.0 IPV6Address: IPV6NetworkMaskPrefixLength: 0 @@ -185,7 +185,7 @@ func TestListTwoHostOnlyNetworks(t *testing.T) { assert.Equal(t, "vboxnet1", net.Name) assert.Equal(t, "786f6276-656e-4174-8000-0a0027000001", net.GUID) assert.False(t, net.DHCP) - assert.Equal(t, "192.168.99.1", net.IPv4.IP.String()) + assert.Equal(t, "169.254.37.187", net.IPv4.IP.String()) assert.Equal(t, "ffffff00", net.IPv4.Mask.String()) assert.Empty(t, net.IPv6.IP) assert.Equal(t, "0a:00:27:00:00:01", net.HwAddr.String()) @@ -230,16 +230,38 @@ func TestGetHostOnlyNetwork(t *testing.T) { assert.NoError(t, err) } -func TestFailWithDuplicateHostOnlyNetworks(t *testing.T) { +func TestFailIfTwoNetworksHaveSameIP(t *testing.T) { vbox := &VBoxManagerMock{ - args: "list hostonlyifs", - stdOut: stdOutTwoHostOnlyNetwork, + args: "list hostonlyifs", + stdOut: `Name: vboxnet0 +IPAddress: 192.168.99.1 +NetworkMask: 255.255.255.0 +VBoxNetworkName: HostInterfaceNetworking-vboxnet0 +Name: vboxnet1 +IPAddress: 192.168.99.1 +NetworkMask: 255.255.255.0 +VBoxNetworkName: HostInterfaceNetworking-vboxnet1`, } net, err := getOrCreateHostOnlyNetwork(net.ParseIP("192.168.99.1"), parseIPv4Mask("255.255.255.0"), nil, nil, nil, vbox) assert.Nil(t, net) - assert.Equal(t, errDuplicateHostOnlyInterfaceNetworks, err) + assert.EqualError(t, err, `VirtualBox is configured with multiple host-only interfaces with the same IP "192.168.99.1". Please remove one.`) +} + +func TestFailIfTwoNetworksHaveSameName(t *testing.T) { + vbox := &VBoxManagerMock{ + args: "list hostonlyifs", + stdOut: `Name: vboxnet0 +VBoxNetworkName: HostInterfaceNetworking-vboxnet0 +Name: vboxnet0 +VBoxNetworkName: HostInterfaceNetworking-vboxnet0`, + } + + net, err := getOrCreateHostOnlyNetwork(net.ParseIP("192.168.99.1"), parseIPv4Mask("255.255.255.0"), nil, nil, nil, vbox) + + assert.Nil(t, net) + assert.EqualError(t, err, `VirtualBox is configured with multiple host-only interfaces with the same name "HostInterfaceNetworking-vboxnet0". Please remove one.`) } func TestGetDHCPServers(t *testing.T) { diff --git a/drivers/virtualbox/virtualbox.go b/drivers/virtualbox/virtualbox.go index 444246e4b5..bbe03a474f 100644 --- a/drivers/virtualbox/virtualbox.go +++ b/drivers/virtualbox/virtualbox.go @@ -223,6 +223,11 @@ func (d *Driver) PreCreateCheck() error { return err } + // Check that Host-only interfaces are ok + if _, err = listHostOnlyNetworks(d.VBoxManager); err != nil { + return err + } + return nil }