Browse Source

Honor driver side resolv.conf file

For the moment in 1.7.1 since we provide a resolv.conf set api
to the driver honor that so that for host driver we can use the
the host's /etc/resolv.conf file as is rather than putting the
contents through a filtering logic.

It should be noted that the driver side capability to set the
resolv.conf file is most likely going to go away in the future
but this should be fine for 1.7.1

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
Jana Radhakrishnan 10 năm trước cách đây
mục cha
commit
70429527b0

+ 5 - 1
libnetwork/drivers/host/host.go

@@ -57,7 +57,11 @@ func (d *driver) EndpointOperInfo(nid, eid types.UUID) (map[string]interface{},
 
 
 // Join method is invoked when a Sandbox is attached to an endpoint.
 // Join method is invoked when a Sandbox is attached to an endpoint.
 func (d *driver) Join(nid, eid types.UUID, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
 func (d *driver) Join(nid, eid types.UUID, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
-	return (jinfo.SetHostsPath("/etc/hosts"))
+	if err := jinfo.SetHostsPath("/etc/hosts"); err != nil {
+		return err
+	}
+
+	return jinfo.SetResolvConfPath("/etc/resolv.conf")
 }
 }
 
 
 // Leave method is invoked when a Sandbox detaches from an endpoint.
 // Leave method is invoked when a Sandbox detaches from an endpoint.

+ 18 - 0
libnetwork/endpoint.go

@@ -811,9 +811,19 @@ func (ep *endpoint) updateDNS(resolvConf []byte) error {
 	return os.Rename(tmpResolvFile.Name(), container.config.resolvConfPath)
 	return os.Rename(tmpResolvFile.Name(), container.config.resolvConfPath)
 }
 }
 
 
+func copyFile(src, dst string) error {
+	sBytes, err := ioutil.ReadFile(src)
+	if err != nil {
+		return err
+	}
+
+	return ioutil.WriteFile(dst, sBytes, 0644)
+}
+
 func (ep *endpoint) setupDNS() error {
 func (ep *endpoint) setupDNS() error {
 	ep.Lock()
 	ep.Lock()
 	container := ep.container
 	container := ep.container
+	joinInfo := ep.joinInfo
 	ep.Unlock()
 	ep.Unlock()
 
 
 	if container == nil {
 	if container == nil {
@@ -830,6 +840,14 @@ func (ep *endpoint) setupDNS() error {
 		return err
 		return err
 	}
 	}
 
 
+	if joinInfo.resolvConfPath != "" {
+		if err := copyFile(joinInfo.resolvConfPath, container.config.resolvConfPath); err != nil {
+			return fmt.Errorf("could not copy source resolv.conf file %s to %s: %v", joinInfo.resolvConfPath, container.config.resolvConfPath, err)
+		}
+
+		return nil
+	}
+
 	resolvConf, err := resolvconf.Get()
 	resolvConf, err := resolvconf.Get()
 	if err != nil {
 	if err != nil {
 		return err
 		return err

+ 68 - 0
libnetwork/libnetwork_test.go

@@ -1564,6 +1564,74 @@ func TestEnableIPv6(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestResolvConfHost(t *testing.T) {
+	if !netutils.IsRunningInContainer() {
+		defer netutils.SetupTestNetNS(t)()
+	}
+
+	tmpResolvConf := []byte("search localhost.net\nnameserver 127.0.0.1\nnameserver 2001:4860:4860::8888")
+
+	//take a copy of resolv.conf for restoring after test completes
+	resolvConfSystem, err := ioutil.ReadFile("/etc/resolv.conf")
+	if err != nil {
+		t.Fatal(err)
+	}
+	//cleanup
+	defer func() {
+		if err := ioutil.WriteFile("/etc/resolv.conf", resolvConfSystem, 0644); err != nil {
+			t.Fatal(err)
+		}
+	}()
+
+	n, err := controller.NetworkByName("testhost")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	ep1, err := n.CreateEndpoint("ep1", nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if err := ioutil.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil {
+		t.Fatal(err)
+	}
+
+	resolvConfPath := "/tmp/libnetwork_test/resolv.conf"
+	defer os.Remove(resolvConfPath)
+
+	err = ep1.Join(containerID,
+		libnetwork.JoinOptionResolvConfPath(resolvConfPath))
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer func() {
+		err = ep1.Leave(containerID)
+		if err != nil {
+			t.Fatal(err)
+		}
+	}()
+
+	finfo, err := os.Stat(resolvConfPath)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	fmode := (os.FileMode)(0644)
+	if finfo.Mode() != fmode {
+		t.Fatalf("Expected file mode %s, got %s", fmode.String(), finfo.Mode().String())
+	}
+
+	content, err := ioutil.ReadFile(resolvConfPath)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if !bytes.Equal(content, tmpResolvConf) {
+		t.Fatalf("Expected %s, Got %s", string(tmpResolvConf), string(content))
+	}
+}
+
 func TestResolvConf(t *testing.T) {
 func TestResolvConf(t *testing.T) {
 	if !netutils.IsRunningInContainer() {
 	if !netutils.IsRunningInContainer() {
 		defer netutils.SetupTestNetNS(t)()
 		defer netutils.SetupTestNetNS(t)()