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
|
|
@ -14,7 +14,6 @@ const (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
reHostonlyInterfaceCreated = regexp.MustCompile(`Interface '(.+)' was successfully created`)
|
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")
|
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")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -75,7 +74,8 @@ func listHostOnlyNetworks(vbox VBoxManager) (map[string]*hostOnlyNetwork, error)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
m := map[string]*hostOnlyNetwork{}
|
byName := map[string]*hostOnlyNetwork{}
|
||||||
|
byIP := map[string]*hostOnlyNetwork{}
|
||||||
n := &hostOnlyNetwork{}
|
n := &hostOnlyNetwork{}
|
||||||
|
|
||||||
err = parseKeyValues(out, reColonLine, func(key, val string) error {
|
err = parseKeyValues(out, reColonLine, func(key, val string) error {
|
||||||
|
|
@ -110,7 +110,19 @@ func listHostOnlyNetworks(vbox VBoxManager) (map[string]*hostOnlyNetwork, error)
|
||||||
n.Status = val
|
n.Status = val
|
||||||
case "VBoxNetworkName":
|
case "VBoxNetworkName":
|
||||||
n.NetworkName = val
|
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{}
|
n = &hostOnlyNetwork{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,7 +132,7 @@ func listHostOnlyNetworks(vbox VBoxManager) (map[string]*hostOnlyNetwork, error)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return m, nil
|
return byName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHostOnlyNetwork(nets map[string]*hostOnlyNetwork, hostIP net.IP, netmask net.IPMask) *hostOnlyNetwork {
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(nets) != countUniqueIps(nets) {
|
|
||||||
return nil, errDuplicateHostOnlyInterfaceNetworks
|
|
||||||
}
|
|
||||||
|
|
||||||
hostOnlyNet := getHostOnlyNetwork(nets, hostIP, netmask)
|
hostOnlyNet := getHostOnlyNetwork(nets, hostIP, netmask)
|
||||||
if hostOnlyNet != nil {
|
if hostOnlyNet != nil {
|
||||||
return hostOnlyNet, nil
|
return hostOnlyNet, nil
|
||||||
|
|
@ -188,16 +196,6 @@ func getOrCreateHostOnlyNetwork(hostIP net.IP, netmask net.IPMask, dhcpIP net.IP
|
||||||
return hostOnlyNet, nil
|
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.
|
// DHCP server info.
|
||||||
type dhcpServer struct {
|
type dhcpServer struct {
|
||||||
NetworkName string
|
NetworkName string
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ VBoxNetworkName: HostInterfaceNetworking-vboxnet0
|
||||||
Name: vboxnet1
|
Name: vboxnet1
|
||||||
GUID: 786f6276-656e-4174-8000-0a0027000001
|
GUID: 786f6276-656e-4174-8000-0a0027000001
|
||||||
DHCP: Disabled
|
DHCP: Disabled
|
||||||
IPAddress: 192.168.99.1
|
IPAddress: 169.254.37.187
|
||||||
NetworkMask: 255.255.255.0
|
NetworkMask: 255.255.255.0
|
||||||
IPV6Address:
|
IPV6Address:
|
||||||
IPV6NetworkMaskPrefixLength: 0
|
IPV6NetworkMaskPrefixLength: 0
|
||||||
|
|
@ -185,7 +185,7 @@ func TestListTwoHostOnlyNetworks(t *testing.T) {
|
||||||
assert.Equal(t, "vboxnet1", net.Name)
|
assert.Equal(t, "vboxnet1", net.Name)
|
||||||
assert.Equal(t, "786f6276-656e-4174-8000-0a0027000001", net.GUID)
|
assert.Equal(t, "786f6276-656e-4174-8000-0a0027000001", net.GUID)
|
||||||
assert.False(t, net.DHCP)
|
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.Equal(t, "ffffff00", net.IPv4.Mask.String())
|
||||||
assert.Empty(t, net.IPv6.IP)
|
assert.Empty(t, net.IPv6.IP)
|
||||||
assert.Equal(t, "0a:00:27:00:00:01", net.HwAddr.String())
|
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)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFailWithDuplicateHostOnlyNetworks(t *testing.T) {
|
func TestFailIfTwoNetworksHaveSameIP(t *testing.T) {
|
||||||
vbox := &VBoxManagerMock{
|
vbox := &VBoxManagerMock{
|
||||||
args: "list hostonlyifs",
|
args: "list hostonlyifs",
|
||||||
stdOut: stdOutTwoHostOnlyNetwork,
|
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)
|
net, err := getOrCreateHostOnlyNetwork(net.ParseIP("192.168.99.1"), parseIPv4Mask("255.255.255.0"), nil, nil, nil, vbox)
|
||||||
|
|
||||||
assert.Nil(t, net)
|
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) {
|
func TestGetDHCPServers(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -223,6 +223,11 @@ func (d *Driver) PreCreateCheck() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that Host-only interfaces are ok
|
||||||
|
if _, err = listHostOnlyNetworks(d.VBoxManager); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue