소스 검색

Merge pull request #10254 from LK4D4/fix_etchosts_rewriting

Fix etchosts rewriting
Jessie Frazelle 10 년 전
부모
커밋
f1bc0376b8
2개의 변경된 파일65개의 추가작업 그리고 11개의 파일을 삭제
  1. 7 10
      daemon/container.go
  2. 58 1
      integration-cli/docker_cli_links_test.go

+ 7 - 10
daemon/container.go

@@ -1108,19 +1108,16 @@ func (container *Container) updateResolvConf(updatedResolvConf []byte, newResolv
 }
 
 func (container *Container) updateParentsHosts() error {
-	parents, err := container.daemon.Parents(container.Name)
-	if err != nil {
-		return err
-	}
-	for _, cid := range parents {
-		if cid == "0" {
+	refs := container.daemon.ContainerGraph().RefPaths(container.ID)
+	for _, ref := range refs {
+		if ref.ParentID == "0" {
 			continue
 		}
-
-		c := container.daemon.Get(cid)
+		c := container.daemon.Get(ref.ParentID)
 		if c != nil && !container.daemon.config.DisableNetwork && container.hostConfig.NetworkMode.IsPrivate() {
-			if err := etchosts.Update(c.HostsPath, container.NetworkSettings.IPAddress, container.Name[1:]); err != nil {
-				log.Errorf("Failed to update /etc/hosts in parent container: %v", err)
+			log.Debugf("Update /etc/hosts of %s for alias %s with ip %s", c.ID, ref.Name, container.NetworkSettings.IPAddress)
+			if err := etchosts.Update(c.HostsPath, container.NetworkSettings.IPAddress, ref.Name); err != nil {
+				log.Errorf("Failed to update /etc/hosts in parent container %s for alias %s: %v", c.ID, ref.Name, err)
 			}
 		}
 	}

+ 58 - 1
integration-cli/docker_cli_links_test.go

@@ -1,14 +1,17 @@
 package main
 
 import (
-	"github.com/docker/docker/pkg/iptables"
+	"fmt"
 	"io/ioutil"
 	"os"
 	"os/exec"
 	"reflect"
+	"regexp"
 	"strings"
 	"testing"
 	"time"
+
+	"github.com/docker/docker/pkg/iptables"
 )
 
 func TestLinksEtcHostsRegularFile(t *testing.T) {
@@ -276,3 +279,57 @@ func TestLinksNetworkHostContainer(t *testing.T) {
 
 	logDone("link - error thrown when linking to container with --net host")
 }
+
+func TestLinksUpdateOnRestart(t *testing.T) {
+	defer deleteAllContainers()
+
+	if out, err := exec.Command(dockerBinary, "run", "-d", "--name", "one", "busybox", "top").CombinedOutput(); err != nil {
+		t.Fatal(err, string(out))
+	}
+	out, err := exec.Command(dockerBinary, "run", "-d", "--name", "two", "--link", "one:onetwo", "--link", "one:one", "busybox", "top").CombinedOutput()
+	if err != nil {
+		t.Fatal(err, string(out))
+	}
+	id := strings.TrimSpace(string(out))
+
+	realIP, err := inspectField("one", "NetworkSettings.IPAddress")
+	if err != nil {
+		t.Fatal(err)
+	}
+	content, err := readContainerFile(id, "hosts")
+	if err != nil {
+		t.Fatal(err, string(content))
+	}
+	getIP := func(hosts []byte, hostname string) string {
+		re := regexp.MustCompile(fmt.Sprintf(`(\S*)\t%s`, regexp.QuoteMeta(hostname)))
+		matches := re.FindSubmatch(hosts)
+		if matches == nil {
+			t.Fatalf("Hostname %s have no matches in hosts", hostname)
+		}
+		return string(matches[1])
+	}
+	if ip := getIP(content, "one"); ip != realIP {
+		t.Fatalf("For 'one' alias expected IP: %s, got: %s", realIP, ip)
+	}
+	if ip := getIP(content, "onetwo"); ip != realIP {
+		t.Fatalf("For 'onetwo' alias expected IP: %s, got: %s", realIP, ip)
+	}
+	if out, err := exec.Command(dockerBinary, "restart", "one").CombinedOutput(); err != nil {
+		t.Fatal(err, string(out))
+	}
+	realIP, err = inspectField("one", "NetworkSettings.IPAddress")
+	if err != nil {
+		t.Fatal(err)
+	}
+	content, err = readContainerFile(id, "hosts")
+	if err != nil {
+		t.Fatal(err, string(content))
+	}
+	if ip := getIP(content, "one"); ip != realIP {
+		t.Fatalf("For 'one' alias expected IP: %s, got: %s", realIP, ip)
+	}
+	if ip := getIP(content, "onetwo"); ip != realIP {
+		t.Fatalf("For 'onetwo' alias expected IP: %s, got: %s", realIP, ip)
+	}
+	logDone("link - ensure containers hosts files are updated on restart")
+}