diff --git a/daemon/daemon.go b/daemon/daemon.go index bf78f1067..8f8cff728 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -1,6 +1,7 @@ package daemon import ( + "bytes" "fmt" "io" "io/ioutil" @@ -1044,8 +1045,10 @@ func (daemon *Daemon) checkLocaldns() error { if err != nil { return err } - 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) + resolvConf = utils.RemoveLocalDns(resolvConf) + + 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/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/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 eb2f31cec..d2fd1ae70 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -13,6 +13,7 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "runtime" "strconv" "strings" @@ -312,39 +313,14 @@ 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*`) +) -// 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 +// RemoveLocalDns looks into the /etc/resolv.conf, +// and removes any local nameserver entries. +func RemoveLocalDns(resolvConf []byte) []byte { + return localHostRx.ReplaceAll(resolvConf, []byte{}) } // An StatusError reports an unsuccessful exit by a command. 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=/"}