From 65640994fda8e1667de3642d8f4daf76dd3de302 Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Mon, 15 Sep 2014 15:43:21 -0400 Subject: [PATCH 1/2] Remove nameserver 127.0.0.1 line rather then dumping resolv.conf We have a bug report complaining about docker dumping the contents of the hosts resolv.conf if it container 127.0.0.1. They asked that instead of dropping the file altogether, that we just remove the line. This patch removes the 127.0.0.1 lines, if they exist and then checks if any nameserver lines exist. Docker-DCO-1.1-Signed-off-by: Dan Walsh (github: rhatdan) --- daemon/daemon.go | 1 + daemon/utils_test.go | 31 +++++++++++++++++++++++++++++++ utils/utils.go | 11 +++++++++++ 3 files changed, 43 insertions(+) diff --git a/daemon/daemon.go b/daemon/daemon.go index bf78f1067..7beb3182c 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -1044,6 +1044,7 @@ func (daemon *Daemon) checkLocaldns() error { if err != nil { return err } + resolvConf = utils.RemoveLocalDns(resolvConf) if len(daemon.config.Dns) == 0 && utils.CheckLocalDns(resolvConf) { log.Infof("Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : %v", DefaultDns) daemon.config.Dns = DefaultDns diff --git a/daemon/utils_test.go b/daemon/utils_test.go index 1f3175b99..6ee75c8ec 100644 --- a/daemon/utils_test.go +++ b/daemon/utils_test.go @@ -27,3 +27,34 @@ func TestMergeLxcConfig(t *testing.T) { t.Fatalf("expected %s got %s", expected, cpuset) } } + +func TestRemoveLocalDns(t *testing.T) { + ns0 := "nameserver 10.16.60.14\nnameserver 10.16.60.21\n" + + if result := utils.RemoveLocalDns([]byte(ns0)); result != nil { + if ns0 != string(result) { + t.Fatalf("Failed No Localhost: expected \n<%s> got \n<%s>", ns0, string(result)) + } + } + + ns1 := "nameserver 10.16.60.14\nnameserver 10.16.60.21\nnameserver 127.0.0.1\n" + if result := utils.RemoveLocalDns([]byte(ns1)); result != nil { + if ns0 != string(result) { + t.Fatalf("Failed Localhost: expected \n<%s> got \n<%s>", ns0, string(result)) + } + } + + ns1 = "nameserver 10.16.60.14\nnameserver 127.0.0.1\nnameserver 10.16.60.21\n" + if result := utils.RemoveLocalDns([]byte(ns1)); result != nil { + if ns0 != string(result) { + t.Fatalf("Failed Localhost: expected \n<%s> got \n<%s>", ns0, string(result)) + } + } + + ns1 = "nameserver 127.0.1.1\nnameserver 10.16.60.14\nnameserver 10.16.60.21\n" + if result := utils.RemoveLocalDns([]byte(ns1)); result != nil { + if ns0 != string(result) { + t.Fatalf("Failed Localhost: expected \n<%s> got \n<%s>", ns0, string(result)) + } + } +} diff --git a/utils/utils.go b/utils/utils.go index eb2f31cec..478521455 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -13,6 +13,7 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "runtime" "strconv" "strings" @@ -332,6 +333,16 @@ func CheckLocalDns(resolvConf []byte) bool { return true } +var ( + localHostRx = regexp.MustCompile(`(?m)^nameserver 127[^\n]+\n*`) +) + +// RemoveLocalDns looks into the /etc/resolv.conf, +// and removes any local nameserver entries. +func RemoveLocalDns(resolvConf []byte) []byte { + return localHostRx.ReplaceAll(resolvConf, []byte{}) +} + // GetLines parses input into lines and strips away comments. func GetLines(input []byte, commentMarker []byte) [][]byte { lines := bytes.Split(input, []byte("\n")) From a297d6ab8c08a13503fd004ec1ad7ee9e23bd22a Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Wed, 24 Sep 2014 14:19:55 -0400 Subject: [PATCH 2/2] Replace utils.CheckLocalDns with bytes.Contains line Since RemoveLocalDns patch will remove all localhost entries from resolv.conf we no longer need anything more then !bytes.Contains(resolvConf, []byte("nameserver") To check for no nameserver entry in dns config. Docker-DCO-1.1-Signed-off-by: Dan Walsh (github: rhatdan) --- daemon/daemon.go | 6 ++-- docs/sources/contributing/devenvironment.md | 2 -- utils/utils.go | 35 --------------------- utils/utils_test.go | 29 ----------------- 4 files changed, 4 insertions(+), 68 deletions(-) diff --git a/daemon/daemon.go b/daemon/daemon.go index 7beb3182c..8f8cff728 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -1,6 +1,7 @@ package daemon import ( + "bytes" "fmt" "io" "io/ioutil" @@ -1045,8 +1046,9 @@ func (daemon *Daemon) checkLocaldns() error { return err } resolvConf = utils.RemoveLocalDns(resolvConf) - if len(daemon.config.Dns) == 0 && utils.CheckLocalDns(resolvConf) { - log.Infof("Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : %v", DefaultDns) + + if len(daemon.config.Dns) == 0 && !bytes.Contains(resolvConf, []byte("nameserver")) { + log.Infof("No non localhost DNS resolver found in resolv.conf and containers can't use it. Using default external servers : %v", DefaultDns) daemon.config.Dns = DefaultDns } return nil diff --git a/docs/sources/contributing/devenvironment.md b/docs/sources/contributing/devenvironment.md index 90ca11b88..ee120a79c 100644 --- a/docs/sources/contributing/devenvironment.md +++ b/docs/sources/contributing/devenvironment.md @@ -101,8 +101,6 @@ something like this --- PASS: TestParseRepositoryTag (0.00 seconds) === RUN TestGetResolvConf --- PASS: TestGetResolvConf (0.00 seconds) - === RUN TestCheckLocalDns - --- PASS: TestCheckLocalDns (0.00 seconds) === RUN TestParseRelease --- PASS: TestParseRelease (0.00 seconds) === RUN TestDependencyGraphCircular diff --git a/utils/utils.go b/utils/utils.go index 478521455..d2fd1ae70 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -313,26 +313,6 @@ func IsGIT(str string) bool { return strings.HasPrefix(str, "git://") || strings.HasPrefix(str, "github.com/") || strings.HasPrefix(str, "git@github.com:") || (strings.HasSuffix(str, ".git") && IsURL(str)) } -// CheckLocalDns looks into the /etc/resolv.conf, -// it returns true if there is a local nameserver or if there is no nameserver. -func CheckLocalDns(resolvConf []byte) bool { - for _, line := range GetLines(resolvConf, []byte("#")) { - if !bytes.Contains(line, []byte("nameserver")) { - continue - } - for _, ip := range [][]byte{ - []byte("127.0.0.1"), - []byte("127.0.1.1"), - } { - if bytes.Contains(line, ip) { - return true - } - } - return false - } - return true -} - var ( localHostRx = regexp.MustCompile(`(?m)^nameserver 127[^\n]+\n*`) ) @@ -343,21 +323,6 @@ func RemoveLocalDns(resolvConf []byte) []byte { return localHostRx.ReplaceAll(resolvConf, []byte{}) } -// GetLines parses input into lines and strips away comments. -func GetLines(input []byte, commentMarker []byte) [][]byte { - lines := bytes.Split(input, []byte("\n")) - var output [][]byte - for _, currentLine := range lines { - var commentIndex = bytes.Index(currentLine, commentMarker) - if commentIndex == -1 { - output = append(output, currentLine) - } else { - output = append(output, currentLine[:commentIndex]) - } - } - return output -} - // An StatusError reports an unsuccessful exit by a command. type StatusError struct { Status string diff --git a/utils/utils_test.go b/utils/utils_test.go index 7990faa8b..ce304482b 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -5,35 +5,6 @@ import ( "testing" ) -func TestCheckLocalDns(t *testing.T) { - for resolv, result := range map[string]bool{`# Dynamic -nameserver 10.0.2.3 -search docker.com`: false, - `# Dynamic -#nameserver 127.0.0.1 -nameserver 10.0.2.3 -search docker.com`: false, - `# Dynamic -nameserver 10.0.2.3 #not used 127.0.1.1 -search docker.com`: false, - `# Dynamic -#nameserver 10.0.2.3 -#search docker.com`: true, - `# Dynamic -nameserver 127.0.0.1 -search docker.com`: true, - `# Dynamic -nameserver 127.0.1.1 -search docker.com`: true, - `# Dynamic -`: true, - ``: true, - } { - if CheckLocalDns([]byte(resolv)) != result { - t.Fatalf("Wrong local dns detection: {%s} should be %v", resolv, result) - } - } -} func TestReplaceAndAppendEnvVars(t *testing.T) { var ( d = []string{"HOME=/"}