Merge pull request #8457 from jfrazelle/pr_8455
Check /etc/resolv.conf every time for 127.* content
This commit is contained in:
commit
4eb812e042
|
@ -1,6 +1,7 @@
|
||||||
package daemon
|
package daemon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -917,7 +918,9 @@ func (container *Container) setupContainerDns() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.NetworkMode != "host" && (len(config.Dns) > 0 || len(daemon.config.Dns) > 0 || len(config.DnsSearch) > 0 || len(daemon.config.DnsSearch) > 0) {
|
if config.NetworkMode != "host" {
|
||||||
|
// check configurations for any container/daemon dns settings
|
||||||
|
if len(config.Dns) > 0 || len(daemon.config.Dns) > 0 || len(config.DnsSearch) > 0 || len(daemon.config.DnsSearch) > 0 {
|
||||||
var (
|
var (
|
||||||
dns = resolvconf.GetNameservers(resolvConf)
|
dns = resolvconf.GetNameservers(resolvConf)
|
||||||
dnsSearch = resolvconf.GetSearchDomains(resolvConf)
|
dnsSearch = resolvconf.GetSearchDomains(resolvConf)
|
||||||
|
@ -934,6 +937,16 @@ func (container *Container) setupContainerDns() error {
|
||||||
}
|
}
|
||||||
return resolvconf.Build(container.ResolvConfPath, dns, dnsSearch)
|
return resolvconf.Build(container.ResolvConfPath, dns, dnsSearch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// replace any localhost/127.* nameservers
|
||||||
|
resolvConf = utils.RemoveLocalDns(resolvConf)
|
||||||
|
// if the resulting resolvConf is empty, use DefaultDns
|
||||||
|
if !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)
|
||||||
|
// prefix the default dns options with nameserver
|
||||||
|
resolvConf = append(resolvConf, []byte("\nnameserver "+strings.Join(DefaultDns, "\nnameserver "))...)
|
||||||
|
}
|
||||||
|
}
|
||||||
return ioutil.WriteFile(container.ResolvConfPath, resolvConf, 0644)
|
return ioutil.WriteFile(container.ResolvConfPath, resolvConf, 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package daemon
|
package daemon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -32,7 +31,6 @@ import (
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
"github.com/docker/docker/pkg/log"
|
"github.com/docker/docker/pkg/log"
|
||||||
"github.com/docker/docker/pkg/namesgenerator"
|
"github.com/docker/docker/pkg/namesgenerator"
|
||||||
"github.com/docker/docker/pkg/networkfs/resolvconf"
|
|
||||||
"github.com/docker/docker/pkg/parsers"
|
"github.com/docker/docker/pkg/parsers"
|
||||||
"github.com/docker/docker/pkg/parsers/kernel"
|
"github.com/docker/docker/pkg/parsers/kernel"
|
||||||
"github.com/docker/docker/pkg/sysinfo"
|
"github.com/docker/docker/pkg/sysinfo"
|
||||||
|
@ -923,9 +921,6 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error)
|
||||||
eng: eng,
|
eng: eng,
|
||||||
trustStore: t,
|
trustStore: t,
|
||||||
}
|
}
|
||||||
if err := daemon.checkLocaldns(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := daemon.restore(); err != nil {
|
if err := daemon.restore(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -1085,20 +1080,6 @@ func (daemon *Daemon) ContainerGraph() *graphdb.Database {
|
||||||
return daemon.containerGraph
|
return daemon.containerGraph
|
||||||
}
|
}
|
||||||
|
|
||||||
func (daemon *Daemon) checkLocaldns() error {
|
|
||||||
resolvConf, err := resolvconf.Get()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
func (daemon *Daemon) ImageGetCached(imgID string, config *runconfig.Config) (*image.Image, error) {
|
func (daemon *Daemon) ImageGetCached(imgID string, config *runconfig.Config) (*image.Image, error) {
|
||||||
// Retrieve all images
|
// Retrieve all images
|
||||||
images, err := daemon.Graph().Map()
|
images, err := daemon.Graph().Map()
|
||||||
|
|
|
@ -751,7 +751,7 @@ func TestRunEnvironment(t *testing.T) {
|
||||||
}
|
}
|
||||||
sort.Strings(goodEnv)
|
sort.Strings(goodEnv)
|
||||||
if len(goodEnv) != len(actualEnv) {
|
if len(goodEnv) != len(actualEnv) {
|
||||||
t.Fatalf("Wrong environment: should be %d variables, not: '%s'\n", len(goodEnv), strings.Join(actualEnv, ", "))
|
t.Fatalf("Wrong environment: should be %d variables, not: %q\n", len(goodEnv), strings.Join(actualEnv, ", "))
|
||||||
}
|
}
|
||||||
for i := range goodEnv {
|
for i := range goodEnv {
|
||||||
if actualEnv[i] != goodEnv[i] {
|
if actualEnv[i] != goodEnv[i] {
|
||||||
|
@ -1168,7 +1168,7 @@ func TestRunModeHostname(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if actual := strings.Trim(out, "\r\n"); actual != "testhostname" {
|
if actual := strings.Trim(out, "\r\n"); actual != "testhostname" {
|
||||||
t.Fatalf("expected 'testhostname', but says: '%s'", actual)
|
t.Fatalf("expected 'testhostname', but says: %q", actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = exec.Command(dockerBinary, "run", "--net=host", "busybox", "cat", "/etc/hostname")
|
cmd = exec.Command(dockerBinary, "run", "--net=host", "busybox", "cat", "/etc/hostname")
|
||||||
|
@ -1182,7 +1182,7 @@ func TestRunModeHostname(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if actual := strings.Trim(out, "\r\n"); actual != hostname {
|
if actual := strings.Trim(out, "\r\n"); actual != hostname {
|
||||||
t.Fatalf("expected '%s', but says: '%s'", hostname, actual)
|
t.Fatalf("expected %q, but says: '%s'", hostname, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteAllContainers()
|
deleteAllContainers()
|
||||||
|
@ -1196,7 +1196,7 @@ func TestRunRootWorkdir(t *testing.T) {
|
||||||
t.Fatal(s, err)
|
t.Fatal(s, err)
|
||||||
}
|
}
|
||||||
if s != "/\n" {
|
if s != "/\n" {
|
||||||
t.Fatalf("pwd returned '%s' (expected /\\n)", s)
|
t.Fatalf("pwd returned %q (expected /\\n)", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteAllContainers()
|
deleteAllContainers()
|
||||||
|
@ -1266,20 +1266,39 @@ func TestRunWithVolumesIsRecursive(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunDnsDefaultOptions(t *testing.T) {
|
func TestRunDnsDefaultOptions(t *testing.T) {
|
||||||
cmd := exec.Command(dockerBinary, "run", "busybox", "cat", "/etc/resolv.conf")
|
// ci server has default resolv.conf
|
||||||
|
// so rewrite it for the test
|
||||||
actual, _, err := runCommandWithOutput(cmd)
|
origResolvConf, err := ioutil.ReadFile("/etc/resolv.conf")
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err, actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvConf, err := ioutil.ReadFile("/etc/resolv.conf")
|
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
t.Fatalf("/etc/resolv.conf does not exist")
|
t.Fatalf("/etc/resolv.conf does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
if actual != string(resolvConf) {
|
// test with file
|
||||||
t.Fatalf("expected resolv.conf is not the same of actual")
|
tmpResolvConf := []byte("nameserver 127.0.0.1")
|
||||||
|
if err := ioutil.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
// put the old resolvconf back
|
||||||
|
defer func() {
|
||||||
|
if err := ioutil.WriteFile("/etc/resolv.conf", origResolvConf, 0644); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
cmd := exec.Command(dockerBinary, "run", "busybox", "cat", "/etc/resolv.conf")
|
||||||
|
|
||||||
|
actual, _, err := runCommandWithOutput(cmd)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err, actual)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that the actual defaults are there
|
||||||
|
// if we ever change the defaults from google dns, this will break
|
||||||
|
expected := "\nnameserver 8.8.8.8\nnameserver 8.8.4.4"
|
||||||
|
if actual != expected {
|
||||||
|
t.Errorf("expected resolv.conf be: %q, but was: %q", expected, actual)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteAllContainers()
|
deleteAllContainers()
|
||||||
|
@ -1297,7 +1316,7 @@ func TestRunDnsOptions(t *testing.T) {
|
||||||
|
|
||||||
actual := strings.Replace(strings.Trim(out, "\r\n"), "\n", " ", -1)
|
actual := strings.Replace(strings.Trim(out, "\r\n"), "\n", " ", -1)
|
||||||
if actual != "nameserver 127.0.0.1 search mydomain" {
|
if actual != "nameserver 127.0.0.1 search mydomain" {
|
||||||
t.Fatalf("expected 'nameserver 127.0.0.1 search mydomain', but says: '%s'", actual)
|
t.Fatalf("expected 'nameserver 127.0.0.1 search mydomain', but says: %q", actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = exec.Command(dockerBinary, "run", "--dns=127.0.0.1", "--dns-search=.", "busybox", "cat", "/etc/resolv.conf")
|
cmd = exec.Command(dockerBinary, "run", "--dns=127.0.0.1", "--dns-search=.", "busybox", "cat", "/etc/resolv.conf")
|
||||||
|
@ -1309,61 +1328,101 @@ func TestRunDnsOptions(t *testing.T) {
|
||||||
|
|
||||||
actual = strings.Replace(strings.Trim(strings.Trim(out, "\r\n"), " "), "\n", " ", -1)
|
actual = strings.Replace(strings.Trim(strings.Trim(out, "\r\n"), " "), "\n", " ", -1)
|
||||||
if actual != "nameserver 127.0.0.1" {
|
if actual != "nameserver 127.0.0.1" {
|
||||||
t.Fatalf("expected 'nameserver 127.0.0.1', but says: '%s'", actual)
|
t.Fatalf("expected 'nameserver 127.0.0.1', but says: %q", actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
logDone("run - dns options")
|
logDone("run - dns options")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunDnsOptionsBasedOnHostResolvConf(t *testing.T) {
|
func TestRunDnsOptionsBasedOnHostResolvConf(t *testing.T) {
|
||||||
resolvConf, err := ioutil.ReadFile("/etc/resolv.conf")
|
var out string
|
||||||
|
|
||||||
|
origResolvConf, err := ioutil.ReadFile("/etc/resolv.conf")
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
t.Fatalf("/etc/resolv.conf does not exist")
|
t.Fatalf("/etc/resolv.conf does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
hostNamservers := resolvconf.GetNameservers(resolvConf)
|
hostNamservers := resolvconf.GetNameservers(origResolvConf)
|
||||||
hostSearch := resolvconf.GetSearchDomains(resolvConf)
|
hostSearch := resolvconf.GetSearchDomains(origResolvConf)
|
||||||
|
|
||||||
cmd := exec.Command(dockerBinary, "run", "--dns=127.0.0.1", "busybox", "cat", "/etc/resolv.conf")
|
cmd := exec.Command(dockerBinary, "run", "--dns=127.0.0.1", "busybox", "cat", "/etc/resolv.conf")
|
||||||
|
|
||||||
out, _, err := runCommandWithOutput(cmd)
|
if out, _, err = runCommandWithOutput(cmd); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err, out)
|
t.Fatal(err, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
if actualNameservers := resolvconf.GetNameservers([]byte(out)); string(actualNameservers[0]) != "127.0.0.1" {
|
if actualNameservers := resolvconf.GetNameservers([]byte(out)); string(actualNameservers[0]) != "127.0.0.1" {
|
||||||
t.Fatalf("expected '127.0.0.1', but says: '%s'", string(actualNameservers[0]))
|
t.Fatalf("expected '127.0.0.1', but says: %q", string(actualNameservers[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
actualSearch := resolvconf.GetSearchDomains([]byte(out))
|
actualSearch := resolvconf.GetSearchDomains([]byte(out))
|
||||||
if len(actualSearch) != len(hostSearch) {
|
if len(actualSearch) != len(hostSearch) {
|
||||||
t.Fatalf("expected '%s' search domain(s), but it has: '%s'", len(hostSearch), len(actualSearch))
|
t.Fatalf("expected %q search domain(s), but it has: '%s'", len(hostSearch), len(actualSearch))
|
||||||
}
|
}
|
||||||
for i := range actualSearch {
|
for i := range actualSearch {
|
||||||
if actualSearch[i] != hostSearch[i] {
|
if actualSearch[i] != hostSearch[i] {
|
||||||
t.Fatalf("expected '%s' domain, but says: '%s'", actualSearch[i], hostSearch[i])
|
t.Fatalf("expected %q domain, but says: '%s'", actualSearch[i], hostSearch[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = exec.Command(dockerBinary, "run", "--dns-search=mydomain", "busybox", "cat", "/etc/resolv.conf")
|
cmd = exec.Command(dockerBinary, "run", "--dns-search=mydomain", "busybox", "cat", "/etc/resolv.conf")
|
||||||
|
|
||||||
out, _, err = runCommandWithOutput(cmd)
|
if out, _, err = runCommandWithOutput(cmd); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err, out)
|
t.Fatal(err, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
actualNameservers := resolvconf.GetNameservers([]byte(out))
|
actualNameservers := resolvconf.GetNameservers([]byte(out))
|
||||||
if len(actualNameservers) != len(hostNamservers) {
|
if len(actualNameservers) != len(hostNamservers) {
|
||||||
t.Fatalf("expected '%s' nameserver(s), but it has: '%s'", len(hostNamservers), len(actualNameservers))
|
t.Fatalf("expected %q nameserver(s), but it has: '%s'", len(hostNamservers), len(actualNameservers))
|
||||||
}
|
}
|
||||||
for i := range actualNameservers {
|
for i := range actualNameservers {
|
||||||
if actualNameservers[i] != hostNamservers[i] {
|
if actualNameservers[i] != hostNamservers[i] {
|
||||||
t.Fatalf("expected '%s' nameserver, but says: '%s'", actualNameservers[i], hostNamservers[i])
|
t.Fatalf("expected %q nameserver, but says: '%s'", actualNameservers[i], hostNamservers[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if actualSearch = resolvconf.GetSearchDomains([]byte(out)); string(actualSearch[0]) != "mydomain" {
|
if actualSearch = resolvconf.GetSearchDomains([]byte(out)); string(actualSearch[0]) != "mydomain" {
|
||||||
t.Fatalf("expected 'mydomain', but says: '%s'", string(actualSearch[0]))
|
t.Fatalf("expected 'mydomain', but says: %q", string(actualSearch[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// test with file
|
||||||
|
tmpResolvConf := []byte("search example.com\nnameserver 12.34.56.78\nnameserver 127.0.0.1")
|
||||||
|
if err := ioutil.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
// put the old resolvconf back
|
||||||
|
defer func() {
|
||||||
|
if err := ioutil.WriteFile("/etc/resolv.conf", origResolvConf, 0644); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
resolvConf, err := ioutil.ReadFile("/etc/resolv.conf")
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
t.Fatalf("/etc/resolv.conf does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
hostNamservers = resolvconf.GetNameservers(resolvConf)
|
||||||
|
hostSearch = resolvconf.GetSearchDomains(resolvConf)
|
||||||
|
|
||||||
|
cmd = exec.Command(dockerBinary, "run", "busybox", "cat", "/etc/resolv.conf")
|
||||||
|
|
||||||
|
if out, _, err = runCommandWithOutput(cmd); err != nil {
|
||||||
|
t.Fatal(err, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
if actualNameservers = resolvconf.GetNameservers([]byte(out)); string(actualNameservers[0]) != "12.34.56.78" || len(actualNameservers) != 1 {
|
||||||
|
t.Fatalf("expected '12.34.56.78', but has: %v", actualNameservers)
|
||||||
|
}
|
||||||
|
|
||||||
|
actualSearch = resolvconf.GetSearchDomains([]byte(out))
|
||||||
|
if len(actualSearch) != len(hostSearch) {
|
||||||
|
t.Fatalf("expected %q search domain(s), but it has: %q", len(hostSearch), len(actualSearch))
|
||||||
|
}
|
||||||
|
for i := range actualSearch {
|
||||||
|
if actualSearch[i] != hostSearch[i] {
|
||||||
|
t.Fatalf("expected %q domain, but says: '%s'", actualSearch[i], hostSearch[i])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteAllContainers()
|
deleteAllContainers()
|
||||||
|
@ -1382,7 +1441,7 @@ func TestRunAddHost(t *testing.T) {
|
||||||
|
|
||||||
actual := strings.Trim(out, "\r\n")
|
actual := strings.Trim(out, "\r\n")
|
||||||
if actual != "86.75.30.9\textra" {
|
if actual != "86.75.30.9\textra" {
|
||||||
t.Fatalf("expected '86.75.30.9\textra', but says: '%s'", actual)
|
t.Fatalf("expected '86.75.30.9\textra', but says: %q", actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
logDone("run - add-host option")
|
logDone("run - add-host option")
|
||||||
|
@ -1989,7 +2048,7 @@ func TestRunCidFileCleanupIfEmpty(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := os.Stat(tmpCidFile); err == nil {
|
if _, err := os.Stat(tmpCidFile); err == nil {
|
||||||
t.Fatalf("empty CIDFile '%s' should've been deleted", tmpCidFile)
|
t.Fatalf("empty CIDFile %q should've been deleted", tmpCidFile)
|
||||||
}
|
}
|
||||||
deleteAllContainers()
|
deleteAllContainers()
|
||||||
logDone("run - cleanup empty cidfile on fail")
|
logDone("run - cleanup empty cidfile on fail")
|
||||||
|
@ -2017,7 +2076,7 @@ func TestRunCidFileCheckIDLength(t *testing.T) {
|
||||||
}
|
}
|
||||||
cid := string(buffer)
|
cid := string(buffer)
|
||||||
if len(cid) != 64 {
|
if len(cid) != 64 {
|
||||||
t.Fatalf("--cidfile should be a long id, not '%s'", id)
|
t.Fatalf("--cidfile should be a long id, not %q", id)
|
||||||
}
|
}
|
||||||
if cid != id {
|
if cid != id {
|
||||||
t.Fatalf("cid must be equal to %s, got %s", id, cid)
|
t.Fatalf("cid must be equal to %s, got %s", id, cid)
|
||||||
|
|
Loading…
Reference in New Issue