mirror of https://github.com/docker/docs.git
				
				
				
			FIX #2624 reject duplicate hostonlyifs name/IP
Signed-off-by: David Gageot <david@gageot.net>
This commit is contained in:
		
							parent
							
								
									906ac38d5a
								
							
						
					
					
						commit
						3c4fd63f93
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue