Check /etc/resolv.conf every time for 127.* content
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package daemon |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "bytes" |
|
| 4 | 5 |
"encoding/json" |
| 5 | 6 |
"errors" |
| 6 | 7 |
"fmt" |
| ... | ... |
@@ -917,22 +918,34 @@ func (container *Container) setupContainerDns() error {
|
| 917 | 917 |
return err |
| 918 | 918 |
} |
| 919 | 919 |
|
| 920 |
- if config.NetworkMode != "host" && (len(config.Dns) > 0 || len(daemon.config.Dns) > 0 || len(config.DnsSearch) > 0 || len(daemon.config.DnsSearch) > 0) {
|
|
| 921 |
- var ( |
|
| 922 |
- dns = resolvconf.GetNameservers(resolvConf) |
|
| 923 |
- dnsSearch = resolvconf.GetSearchDomains(resolvConf) |
|
| 924 |
- ) |
|
| 925 |
- if len(config.Dns) > 0 {
|
|
| 926 |
- dns = config.Dns |
|
| 927 |
- } else if len(daemon.config.Dns) > 0 {
|
|
| 928 |
- dns = daemon.config.Dns |
|
| 920 |
+ if config.NetworkMode != "host" {
|
|
| 921 |
+ // check configurations for any container/daemon dns settings |
|
| 922 |
+ if len(config.Dns) > 0 || len(daemon.config.Dns) > 0 || len(config.DnsSearch) > 0 || len(daemon.config.DnsSearch) > 0 {
|
|
| 923 |
+ var ( |
|
| 924 |
+ dns = resolvconf.GetNameservers(resolvConf) |
|
| 925 |
+ dnsSearch = resolvconf.GetSearchDomains(resolvConf) |
|
| 926 |
+ ) |
|
| 927 |
+ if len(config.Dns) > 0 {
|
|
| 928 |
+ dns = config.Dns |
|
| 929 |
+ } else if len(daemon.config.Dns) > 0 {
|
|
| 930 |
+ dns = daemon.config.Dns |
|
| 931 |
+ } |
|
| 932 |
+ if len(config.DnsSearch) > 0 {
|
|
| 933 |
+ dnsSearch = config.DnsSearch |
|
| 934 |
+ } else if len(daemon.config.DnsSearch) > 0 {
|
|
| 935 |
+ dnsSearch = daemon.config.DnsSearch |
|
| 936 |
+ } |
|
| 937 |
+ return resolvconf.Build(container.ResolvConfPath, dns, dnsSearch) |
|
| 929 | 938 |
} |
| 930 |
- if len(config.DnsSearch) > 0 {
|
|
| 931 |
- dnsSearch = config.DnsSearch |
|
| 932 |
- } else if len(daemon.config.DnsSearch) > 0 {
|
|
| 933 |
- dnsSearch = daemon.config.DnsSearch |
|
| 939 |
+ |
|
| 940 |
+ // replace any localhost/127.* nameservers |
|
| 941 |
+ resolvConf = utils.RemoveLocalDns(resolvConf) |
|
| 942 |
+ // if the resulting resolvConf is empty, use DefaultDns |
|
| 943 |
+ if !bytes.Contains(resolvConf, []byte("nameserver")) {
|
|
| 944 |
+ log.Infof("No non localhost DNS resolver found in resolv.conf and containers can't use it. Using default external servers : %v", DefaultDns)
|
|
| 945 |
+ // prefix the default dns options with nameserver |
|
| 946 |
+ resolvConf = append(resolvConf, []byte("\nnameserver "+strings.Join(DefaultDns, "\nnameserver "))...)
|
|
| 934 | 947 |
} |
| 935 |
- return resolvconf.Build(container.ResolvConfPath, dns, dnsSearch) |
|
| 936 | 948 |
} |
| 937 | 949 |
return ioutil.WriteFile(container.ResolvConfPath, resolvConf, 0644) |
| 938 | 950 |
} |
| ... | ... |
@@ -1,7 +1,6 @@ |
| 1 | 1 |
package daemon |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "bytes" |
|
| 5 | 4 |
"fmt" |
| 6 | 5 |
"io" |
| 7 | 6 |
"io/ioutil" |
| ... | ... |
@@ -32,7 +31,6 @@ import ( |
| 32 | 32 |
"github.com/docker/docker/pkg/ioutils" |
| 33 | 33 |
"github.com/docker/docker/pkg/log" |
| 34 | 34 |
"github.com/docker/docker/pkg/namesgenerator" |
| 35 |
- "github.com/docker/docker/pkg/networkfs/resolvconf" |
|
| 36 | 35 |
"github.com/docker/docker/pkg/parsers" |
| 37 | 36 |
"github.com/docker/docker/pkg/parsers/kernel" |
| 38 | 37 |
"github.com/docker/docker/pkg/sysinfo" |
| ... | ... |
@@ -923,9 +921,6 @@ func NewDaemonFromDirectory(config *Config, eng *engine.Engine) (*Daemon, error) |
| 923 | 923 |
eng: eng, |
| 924 | 924 |
trustStore: t, |
| 925 | 925 |
} |
| 926 |
- if err := daemon.checkLocaldns(); err != nil {
|
|
| 927 |
- return nil, err |
|
| 928 |
- } |
|
| 929 | 926 |
if err := daemon.restore(); err != nil {
|
| 930 | 927 |
return nil, err |
| 931 | 928 |
} |
| ... | ... |
@@ -1085,20 +1080,6 @@ func (daemon *Daemon) ContainerGraph() *graphdb.Database {
|
| 1085 | 1085 |
return daemon.containerGraph |
| 1086 | 1086 |
} |
| 1087 | 1087 |
|
| 1088 |
-func (daemon *Daemon) checkLocaldns() error {
|
|
| 1089 |
- resolvConf, err := resolvconf.Get() |
|
| 1090 |
- if err != nil {
|
|
| 1091 |
- return err |
|
| 1092 |
- } |
|
| 1093 |
- resolvConf = utils.RemoveLocalDns(resolvConf) |
|
| 1094 |
- |
|
| 1095 |
- if len(daemon.config.Dns) == 0 && !bytes.Contains(resolvConf, []byte("nameserver")) {
|
|
| 1096 |
- log.Infof("No non localhost DNS resolver found in resolv.conf and containers can't use it. Using default external servers : %v", DefaultDns)
|
|
| 1097 |
- daemon.config.Dns = DefaultDns |
|
| 1098 |
- } |
|
| 1099 |
- return nil |
|
| 1100 |
-} |
|
| 1101 |
- |
|
| 1102 | 1088 |
func (daemon *Daemon) ImageGetCached(imgID string, config *runconfig.Config) (*image.Image, error) {
|
| 1103 | 1089 |
// Retrieve all images |
| 1104 | 1090 |
images, err := daemon.Graph().Map() |
| ... | ... |
@@ -751,7 +751,7 @@ func TestRunEnvironment(t *testing.T) {
|
| 751 | 751 |
} |
| 752 | 752 |
sort.Strings(goodEnv) |
| 753 | 753 |
if len(goodEnv) != len(actualEnv) {
|
| 754 |
- t.Fatalf("Wrong environment: should be %d variables, not: '%s'\n", len(goodEnv), strings.Join(actualEnv, ", "))
|
|
| 754 |
+ t.Fatalf("Wrong environment: should be %d variables, not: %q\n", len(goodEnv), strings.Join(actualEnv, ", "))
|
|
| 755 | 755 |
} |
| 756 | 756 |
for i := range goodEnv {
|
| 757 | 757 |
if actualEnv[i] != goodEnv[i] {
|
| ... | ... |
@@ -1168,7 +1168,7 @@ func TestRunModeHostname(t *testing.T) {
|
| 1168 | 1168 |
} |
| 1169 | 1169 |
|
| 1170 | 1170 |
if actual := strings.Trim(out, "\r\n"); actual != "testhostname" {
|
| 1171 |
- t.Fatalf("expected 'testhostname', but says: '%s'", actual)
|
|
| 1171 |
+ t.Fatalf("expected 'testhostname', but says: %q", actual)
|
|
| 1172 | 1172 |
} |
| 1173 | 1173 |
|
| 1174 | 1174 |
cmd = exec.Command(dockerBinary, "run", "--net=host", "busybox", "cat", "/etc/hostname") |
| ... | ... |
@@ -1182,7 +1182,7 @@ func TestRunModeHostname(t *testing.T) {
|
| 1182 | 1182 |
t.Fatal(err) |
| 1183 | 1183 |
} |
| 1184 | 1184 |
if actual := strings.Trim(out, "\r\n"); actual != hostname {
|
| 1185 |
- t.Fatalf("expected '%s', but says: '%s'", hostname, actual)
|
|
| 1185 |
+ t.Fatalf("expected %q, but says: '%s'", hostname, actual)
|
|
| 1186 | 1186 |
} |
| 1187 | 1187 |
|
| 1188 | 1188 |
deleteAllContainers() |
| ... | ... |
@@ -1196,7 +1196,7 @@ func TestRunRootWorkdir(t *testing.T) {
|
| 1196 | 1196 |
t.Fatal(s, err) |
| 1197 | 1197 |
} |
| 1198 | 1198 |
if s != "/\n" {
|
| 1199 |
- t.Fatalf("pwd returned '%s' (expected /\\n)", s)
|
|
| 1199 |
+ t.Fatalf("pwd returned %q (expected /\\n)", s)
|
|
| 1200 | 1200 |
} |
| 1201 | 1201 |
|
| 1202 | 1202 |
deleteAllContainers() |
| ... | ... |
@@ -1266,20 +1266,39 @@ func TestRunWithVolumesIsRecursive(t *testing.T) {
|
| 1266 | 1266 |
} |
| 1267 | 1267 |
|
| 1268 | 1268 |
func TestRunDnsDefaultOptions(t *testing.T) {
|
| 1269 |
+ // ci server has default resolv.conf |
|
| 1270 |
+ // so rewrite it for the test |
|
| 1271 |
+ origResolvConf, err := ioutil.ReadFile("/etc/resolv.conf")
|
|
| 1272 |
+ if os.IsNotExist(err) {
|
|
| 1273 |
+ t.Fatalf("/etc/resolv.conf does not exist")
|
|
| 1274 |
+ } |
|
| 1275 |
+ |
|
| 1276 |
+ // test with file |
|
| 1277 |
+ tmpResolvConf := []byte("nameserver 127.0.0.1")
|
|
| 1278 |
+ if err := ioutil.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil {
|
|
| 1279 |
+ t.Fatal(err) |
|
| 1280 |
+ } |
|
| 1281 |
+ // put the old resolvconf back |
|
| 1282 |
+ defer func() {
|
|
| 1283 |
+ if err := ioutil.WriteFile("/etc/resolv.conf", origResolvConf, 0644); err != nil {
|
|
| 1284 |
+ t.Fatal(err) |
|
| 1285 |
+ } |
|
| 1286 |
+ }() |
|
| 1287 |
+ |
|
| 1269 | 1288 |
cmd := exec.Command(dockerBinary, "run", "busybox", "cat", "/etc/resolv.conf") |
| 1270 | 1289 |
|
| 1271 | 1290 |
actual, _, err := runCommandWithOutput(cmd) |
| 1272 | 1291 |
if err != nil {
|
| 1273 |
- t.Fatal(err, actual) |
|
| 1292 |
+ t.Error(err, actual) |
|
| 1293 |
+ return |
|
| 1274 | 1294 |
} |
| 1275 | 1295 |
|
| 1276 |
- resolvConf, err := ioutil.ReadFile("/etc/resolv.conf")
|
|
| 1277 |
- if os.IsNotExist(err) {
|
|
| 1278 |
- t.Fatalf("/etc/resolv.conf does not exist")
|
|
| 1279 |
- } |
|
| 1280 |
- |
|
| 1281 |
- if actual != string(resolvConf) {
|
|
| 1282 |
- t.Fatalf("expected resolv.conf is not the same of actual")
|
|
| 1296 |
+ // check that the actual defaults are there |
|
| 1297 |
+ // if we ever change the defaults from google dns, this will break |
|
| 1298 |
+ expected := "\nnameserver 8.8.8.8\nnameserver 8.8.4.4" |
|
| 1299 |
+ if actual != expected {
|
|
| 1300 |
+ t.Errorf("expected resolv.conf be: %q, but was: %q", expected, actual)
|
|
| 1301 |
+ return |
|
| 1283 | 1302 |
} |
| 1284 | 1303 |
|
| 1285 | 1304 |
deleteAllContainers() |
| ... | ... |
@@ -1297,7 +1316,7 @@ func TestRunDnsOptions(t *testing.T) {
|
| 1297 | 1297 |
|
| 1298 | 1298 |
actual := strings.Replace(strings.Trim(out, "\r\n"), "\n", " ", -1) |
| 1299 | 1299 |
if actual != "nameserver 127.0.0.1 search mydomain" {
|
| 1300 |
- t.Fatalf("expected 'nameserver 127.0.0.1 search mydomain', but says: '%s'", actual)
|
|
| 1300 |
+ t.Fatalf("expected 'nameserver 127.0.0.1 search mydomain', but says: %q", actual)
|
|
| 1301 | 1301 |
} |
| 1302 | 1302 |
|
| 1303 | 1303 |
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) {
|
| 1309 | 1309 |
|
| 1310 | 1310 |
actual = strings.Replace(strings.Trim(strings.Trim(out, "\r\n"), " "), "\n", " ", -1) |
| 1311 | 1311 |
if actual != "nameserver 127.0.0.1" {
|
| 1312 |
- t.Fatalf("expected 'nameserver 127.0.0.1', but says: '%s'", actual)
|
|
| 1312 |
+ t.Fatalf("expected 'nameserver 127.0.0.1', but says: %q", actual)
|
|
| 1313 | 1313 |
} |
| 1314 | 1314 |
|
| 1315 | 1315 |
logDone("run - dns options")
|
| 1316 | 1316 |
} |
| 1317 | 1317 |
|
| 1318 | 1318 |
func TestRunDnsOptionsBasedOnHostResolvConf(t *testing.T) {
|
| 1319 |
- resolvConf, err := ioutil.ReadFile("/etc/resolv.conf")
|
|
| 1319 |
+ var out string |
|
| 1320 |
+ |
|
| 1321 |
+ origResolvConf, err := ioutil.ReadFile("/etc/resolv.conf")
|
|
| 1320 | 1322 |
if os.IsNotExist(err) {
|
| 1321 | 1323 |
t.Fatalf("/etc/resolv.conf does not exist")
|
| 1322 | 1324 |
} |
| 1323 | 1325 |
|
| 1324 |
- hostNamservers := resolvconf.GetNameservers(resolvConf) |
|
| 1325 |
- hostSearch := resolvconf.GetSearchDomains(resolvConf) |
|
| 1326 |
+ hostNamservers := resolvconf.GetNameservers(origResolvConf) |
|
| 1327 |
+ hostSearch := resolvconf.GetSearchDomains(origResolvConf) |
|
| 1326 | 1328 |
|
| 1327 | 1329 |
cmd := exec.Command(dockerBinary, "run", "--dns=127.0.0.1", "busybox", "cat", "/etc/resolv.conf") |
| 1328 | 1330 |
|
| 1329 |
- out, _, err := runCommandWithOutput(cmd) |
|
| 1330 |
- if err != nil {
|
|
| 1331 |
+ if out, _, err = runCommandWithOutput(cmd); err != nil {
|
|
| 1331 | 1332 |
t.Fatal(err, out) |
| 1332 | 1333 |
} |
| 1333 | 1334 |
|
| 1334 | 1335 |
if actualNameservers := resolvconf.GetNameservers([]byte(out)); string(actualNameservers[0]) != "127.0.0.1" {
|
| 1335 |
- t.Fatalf("expected '127.0.0.1', but says: '%s'", string(actualNameservers[0]))
|
|
| 1336 |
+ t.Fatalf("expected '127.0.0.1', but says: %q", string(actualNameservers[0]))
|
|
| 1336 | 1337 |
} |
| 1337 | 1338 |
|
| 1338 | 1339 |
actualSearch := resolvconf.GetSearchDomains([]byte(out)) |
| 1339 | 1340 |
if len(actualSearch) != len(hostSearch) {
|
| 1340 |
- t.Fatalf("expected '%s' search domain(s), but it has: '%s'", len(hostSearch), len(actualSearch))
|
|
| 1341 |
+ t.Fatalf("expected %q search domain(s), but it has: '%s'", len(hostSearch), len(actualSearch))
|
|
| 1341 | 1342 |
} |
| 1342 | 1343 |
for i := range actualSearch {
|
| 1343 | 1344 |
if actualSearch[i] != hostSearch[i] {
|
| 1344 |
- t.Fatalf("expected '%s' domain, but says: '%s'", actualSearch[i], hostSearch[i])
|
|
| 1345 |
+ t.Fatalf("expected %q domain, but says: '%s'", actualSearch[i], hostSearch[i])
|
|
| 1345 | 1346 |
} |
| 1346 | 1347 |
} |
| 1347 | 1348 |
|
| 1348 | 1349 |
cmd = exec.Command(dockerBinary, "run", "--dns-search=mydomain", "busybox", "cat", "/etc/resolv.conf") |
| 1349 | 1350 |
|
| 1350 |
- out, _, err = runCommandWithOutput(cmd) |
|
| 1351 |
- if err != nil {
|
|
| 1351 |
+ if out, _, err = runCommandWithOutput(cmd); err != nil {
|
|
| 1352 | 1352 |
t.Fatal(err, out) |
| 1353 | 1353 |
} |
| 1354 | 1354 |
|
| 1355 | 1355 |
actualNameservers := resolvconf.GetNameservers([]byte(out)) |
| 1356 | 1356 |
if len(actualNameservers) != len(hostNamservers) {
|
| 1357 |
- t.Fatalf("expected '%s' nameserver(s), but it has: '%s'", len(hostNamservers), len(actualNameservers))
|
|
| 1357 |
+ t.Fatalf("expected %q nameserver(s), but it has: '%s'", len(hostNamservers), len(actualNameservers))
|
|
| 1358 | 1358 |
} |
| 1359 | 1359 |
for i := range actualNameservers {
|
| 1360 | 1360 |
if actualNameservers[i] != hostNamservers[i] {
|
| 1361 |
- t.Fatalf("expected '%s' nameserver, but says: '%s'", actualNameservers[i], hostNamservers[i])
|
|
| 1361 |
+ t.Fatalf("expected %q nameserver, but says: '%s'", actualNameservers[i], hostNamservers[i])
|
|
| 1362 | 1362 |
} |
| 1363 | 1363 |
} |
| 1364 | 1364 |
|
| 1365 | 1365 |
if actualSearch = resolvconf.GetSearchDomains([]byte(out)); string(actualSearch[0]) != "mydomain" {
|
| 1366 |
- t.Fatalf("expected 'mydomain', but says: '%s'", string(actualSearch[0]))
|
|
| 1366 |
+ t.Fatalf("expected 'mydomain', but says: %q", string(actualSearch[0]))
|
|
| 1367 |
+ } |
|
| 1368 |
+ |
|
| 1369 |
+ // test with file |
|
| 1370 |
+ tmpResolvConf := []byte("search example.com\nnameserver 12.34.56.78\nnameserver 127.0.0.1")
|
|
| 1371 |
+ if err := ioutil.WriteFile("/etc/resolv.conf", tmpResolvConf, 0644); err != nil {
|
|
| 1372 |
+ t.Fatal(err) |
|
| 1373 |
+ } |
|
| 1374 |
+ // put the old resolvconf back |
|
| 1375 |
+ defer func() {
|
|
| 1376 |
+ if err := ioutil.WriteFile("/etc/resolv.conf", origResolvConf, 0644); err != nil {
|
|
| 1377 |
+ t.Fatal(err) |
|
| 1378 |
+ } |
|
| 1379 |
+ }() |
|
| 1380 |
+ |
|
| 1381 |
+ resolvConf, err := ioutil.ReadFile("/etc/resolv.conf")
|
|
| 1382 |
+ if os.IsNotExist(err) {
|
|
| 1383 |
+ t.Fatalf("/etc/resolv.conf does not exist")
|
|
| 1384 |
+ } |
|
| 1385 |
+ |
|
| 1386 |
+ hostNamservers = resolvconf.GetNameservers(resolvConf) |
|
| 1387 |
+ hostSearch = resolvconf.GetSearchDomains(resolvConf) |
|
| 1388 |
+ |
|
| 1389 |
+ cmd = exec.Command(dockerBinary, "run", "busybox", "cat", "/etc/resolv.conf") |
|
| 1390 |
+ |
|
| 1391 |
+ if out, _, err = runCommandWithOutput(cmd); err != nil {
|
|
| 1392 |
+ t.Fatal(err, out) |
|
| 1393 |
+ } |
|
| 1394 |
+ |
|
| 1395 |
+ if actualNameservers = resolvconf.GetNameservers([]byte(out)); string(actualNameservers[0]) != "12.34.56.78" || len(actualNameservers) != 1 {
|
|
| 1396 |
+ t.Fatalf("expected '12.34.56.78', but has: %v", actualNameservers)
|
|
| 1397 |
+ } |
|
| 1398 |
+ |
|
| 1399 |
+ actualSearch = resolvconf.GetSearchDomains([]byte(out)) |
|
| 1400 |
+ if len(actualSearch) != len(hostSearch) {
|
|
| 1401 |
+ t.Fatalf("expected %q search domain(s), but it has: %q", len(hostSearch), len(actualSearch))
|
|
| 1402 |
+ } |
|
| 1403 |
+ for i := range actualSearch {
|
|
| 1404 |
+ if actualSearch[i] != hostSearch[i] {
|
|
| 1405 |
+ t.Fatalf("expected %q domain, but says: '%s'", actualSearch[i], hostSearch[i])
|
|
| 1406 |
+ } |
|
| 1367 | 1407 |
} |
| 1368 | 1408 |
|
| 1369 | 1409 |
deleteAllContainers() |
| ... | ... |
@@ -1382,7 +1441,7 @@ func TestRunAddHost(t *testing.T) {
|
| 1382 | 1382 |
|
| 1383 | 1383 |
actual := strings.Trim(out, "\r\n") |
| 1384 | 1384 |
if actual != "86.75.30.9\textra" {
|
| 1385 |
- t.Fatalf("expected '86.75.30.9\textra', but says: '%s'", actual)
|
|
| 1385 |
+ t.Fatalf("expected '86.75.30.9\textra', but says: %q", actual)
|
|
| 1386 | 1386 |
} |
| 1387 | 1387 |
|
| 1388 | 1388 |
logDone("run - add-host option")
|
| ... | ... |
@@ -1989,7 +2048,7 @@ func TestRunCidFileCleanupIfEmpty(t *testing.T) {
|
| 1989 | 1989 |
} |
| 1990 | 1990 |
|
| 1991 | 1991 |
if _, err := os.Stat(tmpCidFile); err == nil {
|
| 1992 |
- t.Fatalf("empty CIDFile '%s' should've been deleted", tmpCidFile)
|
|
| 1992 |
+ t.Fatalf("empty CIDFile %q should've been deleted", tmpCidFile)
|
|
| 1993 | 1993 |
} |
| 1994 | 1994 |
deleteAllContainers() |
| 1995 | 1995 |
logDone("run - cleanup empty cidfile on fail")
|
| ... | ... |
@@ -2017,7 +2076,7 @@ func TestRunCidFileCheckIDLength(t *testing.T) {
|
| 2017 | 2017 |
} |
| 2018 | 2018 |
cid := string(buffer) |
| 2019 | 2019 |
if len(cid) != 64 {
|
| 2020 |
- t.Fatalf("--cidfile should be a long id, not '%s'", id)
|
|
| 2020 |
+ t.Fatalf("--cidfile should be a long id, not %q", id)
|
|
| 2021 | 2021 |
} |
| 2022 | 2022 |
if cid != id {
|
| 2023 | 2023 |
t.Fatalf("cid must be equal to %s, got %s", id, cid)
|