Pārlūkot izejas kodu

Merge pull request #1611 from pysqz/master

Make sure 'Ghost' container is available with allocated IP
Michael Crosby 12 gadi atpakaļ
vecāks
revīzija
c2b273df5d
2 mainītis faili ar 51 papildinājumiem un 5 dzēšanām
  1. 35 4
      container.go
  2. 16 1
      network.go

+ 35 - 4
container.go

@@ -20,6 +20,7 @@ import (
 	"strings"
 	"syscall"
 	"time"
+	"net"
 )
 
 type Container struct {
@@ -799,14 +800,44 @@ func (container *Container) allocateNetwork() error {
 		return nil
 	}
 
-	iface, err := container.runtime.networkManager.Allocate()
-	if err != nil {
-		return err
+	var iface *NetworkInterface
+	var err error
+	if !container.State.Ghost {
+		iface, err = container.runtime.networkManager.Allocate()
+		if err != nil {
+			return err
+		}
+	} else {
+		manager := container.runtime.networkManager
+		if manager.disabled {
+			iface = &NetworkInterface{disabled: true}
+		} else {
+			iface = &NetworkInterface{
+				IPNet: net.IPNet{IP: net.ParseIP(container.NetworkSettings.IPAddress), Mask: manager.bridgeNetwork.Mask},
+				Gateway: manager.bridgeNetwork.IP,
+				manager: manager,
+				}
+			ipNum := ipToInt(iface.IPNet.IP)
+			manager.ipAllocator.inUse[ipNum] = struct{}{}
+		}
+	}
+
+	var portSpecs []string
+	if !container.State.Ghost {
+		portSpecs = container.Config.PortSpecs
+	} else {
+		for backend, frontend := range container.NetworkSettings.PortMapping["Tcp"] {
+			portSpecs = append(portSpecs, fmt.Sprintf("%s:%s/tcp",frontend, backend))
+		}
+		for backend, frontend := range container.NetworkSettings.PortMapping["Udp"] {
+			portSpecs = append(portSpecs, fmt.Sprintf("%s:%s/udp",frontend, backend))
+		}
 	}
+
 	container.NetworkSettings.PortMapping = make(map[string]PortMapping)
 	container.NetworkSettings.PortMapping["Tcp"] = make(PortMapping)
 	container.NetworkSettings.PortMapping["Udp"] = make(PortMapping)
-	for _, spec := range container.Config.PortSpecs {
+	for _, spec := range portSpecs {
 		nat, err := iface.AllocatePort(spec)
 		if err != nil {
 			iface.Release()

+ 16 - 1
network.go

@@ -635,10 +635,25 @@ func (manager *NetworkManager) Allocate() (*NetworkInterface, error) {
 		return &NetworkInterface{disabled: true}, nil
 	}
 
-	ip, err := manager.ipAllocator.Acquire()
+	var ip net.IP
+	var err error
+
+	ip, err = manager.ipAllocator.Acquire()
 	if err != nil {
 		return nil, err
 	}
+	// avoid duplicate IP 
+	ipNum := ipToInt(ip)
+	firstIP := manager.ipAllocator.network.IP.To4().Mask(manager.ipAllocator.network.Mask)
+	firstIPNum := ipToInt(firstIP) + 1
+
+	if firstIPNum == ipNum {
+		ip, err = manager.ipAllocator.Acquire()
+		if err != nil {
+			return nil, err
+		}
+	}
+
 	iface := &NetworkInterface{
 		IPNet:   net.IPNet{IP: ip, Mask: manager.bridgeNetwork.Mask},
 		Gateway: manager.bridgeNetwork.IP,