Explorar el Código

Merge pull request #2445 from kdomanski/ipv6-addr-in-hosts

etchosts: include the container's IPv6 address if available
elangovan sivanandam hace 5 años
padre
commit
f55f6f82ed

+ 19 - 5
libnetwork/endpoint.go

@@ -498,11 +498,14 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) (err error) {
 	}
 
 	if doUpdateHostsFile(n, sb) {
-		address := ""
-		if ip := ep.getFirstInterfaceAddress(); ip != nil {
-			address = ip.String()
+		var addresses []string
+		if ip := ep.getFirstInterfaceIPv4Address(); ip != nil {
+			addresses = append(addresses, ip.String())
 		}
-		if err = sb.updateHostsFile(address); err != nil {
+		if ip := ep.getFirstInterfaceIPv6Address(); ip != nil {
+			addresses = append(addresses, ip.String())
+		}
+		if err = sb.updateHostsFile(addresses); err != nil {
 			return err
 		}
 	}
@@ -912,7 +915,7 @@ func (ep *endpoint) getSandbox() (*sandbox, bool) {
 	return ps, ok
 }
 
-func (ep *endpoint) getFirstInterfaceAddress() net.IP {
+func (ep *endpoint) getFirstInterfaceIPv4Address() net.IP {
 	ep.Lock()
 	defer ep.Unlock()
 
@@ -923,6 +926,17 @@ func (ep *endpoint) getFirstInterfaceAddress() net.IP {
 	return nil
 }
 
+func (ep *endpoint) getFirstInterfaceIPv6Address() net.IP {
+	ep.Lock()
+	defer ep.Unlock()
+
+	if ep.iface.addrv6 != nil {
+		return ep.iface.addrv6.IP
+	}
+
+	return nil
+}
+
 // EndpointOptionGeneric function returns an option setter for a Generic option defined
 // in a Dictionary of Key-Value pair
 func EndpointOptionGeneric(generic map[string]interface{}) EndpointOption {

+ 76 - 0
libnetwork/endpoint_test.go

@@ -0,0 +1,76 @@
+// +build !windows
+
+package libnetwork
+
+import (
+	"io/ioutil"
+	"os"
+	"testing"
+
+	"github.com/docker/libnetwork/ipamapi"
+	"github.com/docker/libnetwork/osl"
+	"github.com/docker/libnetwork/testutils"
+)
+
+func TestHostsEntries(t *testing.T) {
+	if !testutils.IsRunningInContainer() {
+		defer testutils.SetupTestOSContext(t)()
+	}
+
+	expectedHostsFile := `127.0.0.1	localhost
+::1	localhost ip6-localhost ip6-loopback
+fe00::0	ip6-localnet
+ff00::0	ip6-mcastprefix
+ff02::1	ip6-allnodes
+ff02::2	ip6-allrouters
+192.168.222.2	somehost.example.com somehost
+fe90::2	somehost.example.com somehost
+`
+
+	opts := []NetworkOption{NetworkOptionEnableIPv6(true), NetworkOptionIpam(ipamapi.DefaultIPAM, "",
+		[]*IpamConf{{PreferredPool: "192.168.222.0/24", Gateway: "192.168.222.1"}},
+		[]*IpamConf{{PreferredPool: "fe90::/64", Gateway: "fe90::1"}},
+		nil)}
+
+	c, nws := getTestEnv(t, opts)
+	ctrlr := c.(*controller)
+
+	hostsFile, err := ioutil.TempFile("", "")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.Remove(hostsFile.Name())
+
+	sbx, err := ctrlr.NewSandbox("sandbox1", OptionHostsPath(hostsFile.Name()), OptionHostname("somehost.example.com"))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	ep1, err := nws[0].CreateEndpoint("ep1")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if err := ep1.Join(sbx, JoinOptionPriority(ep1, 1)); err != nil {
+		t.Fatal(err)
+	}
+
+	data, err := ioutil.ReadFile(hostsFile.Name())
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if string(data) != expectedHostsFile {
+		t.Fatalf("expected the hosts file to read:\n%q\nbut instead got the following:\n%q\n", expectedHostsFile, string(data))
+	}
+
+	if err := sbx.Delete(); err != nil {
+		t.Fatal(err)
+	}
+
+	if len(ctrlr.sandboxes) != 0 {
+		t.Fatalf("controller sandboxes is not empty. len = %d", len(ctrlr.sandboxes))
+	}
+
+	osl.GC()
+}

+ 6 - 3
libnetwork/sandbox_dns_unix.go

@@ -98,8 +98,8 @@ func (sb *sandbox) buildHostsFile() error {
 	return etchosts.Build(sb.config.hostsPath, "", sb.config.hostName, sb.config.domainName, extraContent)
 }
 
-func (sb *sandbox) updateHostsFile(ifaceIP string) error {
-	if ifaceIP == "" {
+func (sb *sandbox) updateHostsFile(ifaceIPs []string) error {
+	if ifaceIPs == nil || len(ifaceIPs) == 0 {
 		return nil
 	}
 
@@ -120,7 +120,10 @@ func (sb *sandbox) updateHostsFile(ifaceIP string) error {
 		mhost = fmt.Sprintf("%s %s", fqdn, parts[0])
 	}
 
-	extraContent := []etchosts.Record{{Hosts: mhost, IP: ifaceIP}}
+	var extraContent []etchosts.Record
+	for _, ip := range ifaceIPs {
+		extraContent = append(extraContent, etchosts.Record{Hosts: mhost, IP: ip})
+	}
 
 	sb.addHostsEntries(extraContent)
 	return nil

+ 1 - 1
libnetwork/sandbox_dns_windows.go

@@ -18,7 +18,7 @@ func (sb *sandbox) setupResolutionFiles() error {
 func (sb *sandbox) restorePath() {
 }
 
-func (sb *sandbox) updateHostsFile(ifaceIP string) error {
+func (sb *sandbox) updateHostsFile(ifaceIP []string) error {
 	return nil
 }