func TestDnsOptionsBasedOnHostResolvConf(t *testing.T) {
	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", "--dns=127.0.0.1", "busybox", "cat", "/etc/resolv.conf")

	out, _, err := runCommandWithOutput(cmd)
	if err != nil {
		t.Fatal(err, out)
	}

	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]))
	}

	actualSearch := resolvconf.GetSearchDomains([]byte(out))
	if len(actualSearch) != len(hostSearch) {
		t.Fatalf("expected '%s' search domain(s), but it has: '%s'", len(hostSearch), len(actualSearch))
	}
	for i := range actualSearch {
		if actualSearch[i] != hostSearch[i] {
			t.Fatalf("expected '%s' domain, but says: '%s'", actualSearch[i], hostSearch[i])
		}
	}

	cmd = exec.Command(dockerBinary, "run", "--dns-search=mydomain", "busybox", "cat", "/etc/resolv.conf")

	out, _, err = runCommandWithOutput(cmd)
	if err != nil {
		t.Fatal(err, out)
	}

	actualNameservers := resolvconf.GetNameservers([]byte(out))
	if len(actualNameservers) != len(hostNamservers) {
		t.Fatalf("expected '%s' nameserver(s), but it has: '%s'", len(hostNamservers), len(actualNameservers))
	}
	for i := range actualNameservers {
		if actualNameservers[i] != hostNamservers[i] {
			t.Fatalf("expected '%s' nameserver, but says: '%s'", actualNameservers[i], hostNamservers[i])
		}
	}

	if actualSearch = resolvconf.GetSearchDomains([]byte(out)); string(actualSearch[0]) != "mydomain" {
		t.Fatalf("expected 'mydomain', but says: '%s'", string(actualSearch[0]))
	}

	deleteAllContainers()

	logDone("run - dns options based on host resolv.conf")
}
Example #2
0
func (container *Container) setupContainerDns() error {
	if container.ResolvConfPath != "" {
		return nil
	}

	var (
		config = container.hostConfig
		daemon = container.daemon
	)

	if config.NetworkMode == "host" {
		container.ResolvConfPath = "/etc/resolv.conf"
		return nil
	}

	resolvConf, err := resolvconf.Get()
	if err != nil {
		return err
	}

	// If custom dns exists, then create a resolv.conf for the container
	if len(config.Dns) > 0 || len(daemon.config.Dns) > 0 || len(config.DnsSearch) > 0 || len(daemon.config.DnsSearch) > 0 {
		var (
			dns       = resolvconf.GetNameservers(resolvConf)
			dnsSearch = resolvconf.GetSearchDomains(resolvConf)
		)
		if len(config.Dns) > 0 {
			dns = config.Dns
		} else if len(daemon.config.Dns) > 0 {
			dns = daemon.config.Dns
		}
		if len(config.DnsSearch) > 0 {
			dnsSearch = config.DnsSearch
		} else if len(daemon.config.DnsSearch) > 0 {
			dnsSearch = daemon.config.DnsSearch
		}

		resolvConfPath, err := container.getRootResourcePath("resolv.conf")
		if err != nil {
			return err
		}
		container.ResolvConfPath = resolvConfPath

		return resolvconf.Build(container.ResolvConfPath, dns, dnsSearch)
	} else {
		container.ResolvConfPath = "/etc/resolv.conf"
	}
	return nil
}