Browse Source

Do not overwrite the /etc/hosts file on Join

Currently on every endpoint Join the /etc/hosts
file is getting overwritten. This blows the already
existing service records. Modify the `updateHostsFile`
function to build the hosts file only on the first
endpoint join and for subsequent joins just update
the existing /etc/hosts file with the additional
network specific service records.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
Jana Radhakrishnan 9 years ago
parent
commit
24f1845a18
1 changed files with 39 additions and 15 deletions
  1. 39 15
      libnetwork/sandbox.go

+ 39 - 15
libnetwork/sandbox.go

@@ -54,16 +54,15 @@ func (sb *sandbox) processOptions(options ...SandboxOption) {
 type epHeap []*endpoint
 
 type sandbox struct {
-	id          string
-	containerID string
-	config      containerConfig
-	osSbox      osl.Sandbox
-	controller  *controller
-	refCnt      int
-	endpoints   epHeap
-	epPriority  map[string]int
-	//hostsPath      string
-	//resolvConfPath string
+	id            string
+	containerID   string
+	config        containerConfig
+	osSbox        osl.Sandbox
+	controller    *controller
+	refCnt        int
+	hostsOnce     sync.Once
+	endpoints     epHeap
+	epPriority    map[string]int
 	joinLeaveDone chan struct{}
 	sync.Mutex
 }
@@ -460,22 +459,47 @@ func (sb *sandbox) buildHostsFile() error {
 }
 
 func (sb *sandbox) updateHostsFile(ifaceIP string, svcRecords []etchosts.Record) error {
+	var err error
+
 	if sb.config.originHostsPath != "" {
 		return nil
 	}
 
-	// Rebuild the hosts file accounting for the passed interface IP and service records
-	extraContent := make([]etchosts.Record, 0, len(sb.config.extraHosts)+len(svcRecords))
+	max := func(a, b int) int {
+		if a < b {
+			return b
+		}
 
-	for _, extraHost := range sb.config.extraHosts {
-		extraContent = append(extraContent, etchosts.Record{Hosts: extraHost.name, IP: extraHost.IP})
+		return a
 	}
 
+	extraContent := make([]etchosts.Record, 0,
+		max(len(sb.config.extraHosts), len(svcRecords)))
+
+	sb.hostsOnce.Do(func() {
+		// Rebuild the hosts file accounting for the passed
+		// interface IP and service records
+
+		for _, extraHost := range sb.config.extraHosts {
+			extraContent = append(extraContent,
+				etchosts.Record{Hosts: extraHost.name, IP: extraHost.IP})
+		}
+
+		err = etchosts.Build(sb.config.hostsPath, ifaceIP,
+			sb.config.hostName, sb.config.domainName, extraContent)
+	})
+
+	if err != nil {
+		return err
+	}
+
+	extraContent = extraContent[:0]
 	for _, svc := range svcRecords {
 		extraContent = append(extraContent, svc)
 	}
 
-	return etchosts.Build(sb.config.hostsPath, ifaceIP, sb.config.hostName, sb.config.domainName, extraContent)
+	sb.addHostsEntries(extraContent)
+	return nil
 }
 
 func (sb *sandbox) addHostsEntries(recs []etchosts.Record) {