浏览代码

Merge pull request #42755 from thaJeztah/move_resolvconf_consts

libnetwork: make resolvconf more self-contained
Sebastiaan van Stijn 3 年之前
父节点
当前提交
5ea3e12b63

+ 4 - 5
integration-cli/docker_cli_run_test.go

@@ -28,7 +28,6 @@ import (
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/libnetwork/resolvconf"
 	"github.com/docker/docker/libnetwork/resolvconf"
-	"github.com/docker/docker/libnetwork/types"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/testutil"
 	"github.com/docker/docker/testutil"
@@ -1326,13 +1325,13 @@ func (s *DockerSuite) TestRunDNSOptionsBasedOnHostResolvConf(c *testing.T) {
 		c.Fatalf("/etc/resolv.conf does not exist")
 		c.Fatalf("/etc/resolv.conf does not exist")
 	}
 	}
 
 
-	hostNameservers := resolvconf.GetNameservers(origResolvConf, types.IP)
+	hostNameservers := resolvconf.GetNameservers(origResolvConf, resolvconf.IP)
 	hostSearch := resolvconf.GetSearchDomains(origResolvConf)
 	hostSearch := resolvconf.GetSearchDomains(origResolvConf)
 
 
 	var out string
 	var out string
 	out, _ = dockerCmd(c, "run", "--dns=127.0.0.1", "busybox", "cat", "/etc/resolv.conf")
 	out, _ = dockerCmd(c, "run", "--dns=127.0.0.1", "busybox", "cat", "/etc/resolv.conf")
 
 
-	if actualNameservers := resolvconf.GetNameservers([]byte(out), types.IP); actualNameservers[0] != "127.0.0.1" {
+	if actualNameservers := resolvconf.GetNameservers([]byte(out), resolvconf.IP); actualNameservers[0] != "127.0.0.1" {
 		c.Fatalf("expected '127.0.0.1', but says: %q", actualNameservers[0])
 		c.Fatalf("expected '127.0.0.1', but says: %q", actualNameservers[0])
 	}
 	}
 
 
@@ -1348,7 +1347,7 @@ func (s *DockerSuite) TestRunDNSOptionsBasedOnHostResolvConf(c *testing.T) {
 
 
 	out, _ = dockerCmd(c, "run", "--dns-search=mydomain", "busybox", "cat", "/etc/resolv.conf")
 	out, _ = dockerCmd(c, "run", "--dns-search=mydomain", "busybox", "cat", "/etc/resolv.conf")
 
 
-	actualNameservers := resolvconf.GetNameservers([]byte(out), types.IP)
+	actualNameservers := resolvconf.GetNameservers([]byte(out), resolvconf.IP)
 	if len(actualNameservers) != len(hostNameservers) {
 	if len(actualNameservers) != len(hostNameservers) {
 		c.Fatalf("expected %q nameserver(s), but it has: %q", len(hostNameservers), len(actualNameservers))
 		c.Fatalf("expected %q nameserver(s), but it has: %q", len(hostNameservers), len(actualNameservers))
 	}
 	}
@@ -1382,7 +1381,7 @@ func (s *DockerSuite) TestRunDNSOptionsBasedOnHostResolvConf(c *testing.T) {
 	hostSearch = resolvconf.GetSearchDomains(resolvConf)
 	hostSearch = resolvconf.GetSearchDomains(resolvConf)
 
 
 	out, _ = dockerCmd(c, "run", "busybox", "cat", "/etc/resolv.conf")
 	out, _ = dockerCmd(c, "run", "busybox", "cat", "/etc/resolv.conf")
-	if actualNameservers = resolvconf.GetNameservers([]byte(out), types.IP); actualNameservers[0] != "12.34.56.78" || len(actualNameservers) != 1 {
+	if actualNameservers = resolvconf.GetNameservers([]byte(out), resolvconf.IP); actualNameservers[0] != "12.34.56.78" || len(actualNameservers) != 1 {
 		c.Fatalf("expected '12.34.56.78', but has: %v", actualNameservers)
 		c.Fatalf("expected '12.34.56.78', but has: %v", actualNameservers)
 	}
 	}
 
 

+ 0 - 1
libnetwork/resolvconf/README.md

@@ -1 +0,0 @@
-Package resolvconf provides utility code to query and update DNS configuration in /etc/resolv.conf

+ 0 - 26
libnetwork/resolvconf/dns/resolvconf.go

@@ -1,26 +0,0 @@
-package dns
-
-import (
-	"regexp"
-)
-
-// IPLocalhost is a regex pattern for IPv4 or IPv6 loopback range.
-const IPLocalhost = `((127\.([0-9]{1,3}\.){2}[0-9]{1,3})|(::1)$)`
-
-// IPv4Localhost is a regex pattern for IPv4 localhost address range.
-const IPv4Localhost = `(127\.([0-9]{1,3}\.){2}[0-9]{1,3})`
-
-var localhostIPRegexp = regexp.MustCompile(IPLocalhost)
-var localhostIPv4Regexp = regexp.MustCompile(IPv4Localhost)
-
-// IsLocalhost returns true if ip matches the localhost IP regular expression.
-// Used for determining if nameserver settings are being passed which are
-// localhost addresses
-func IsLocalhost(ip string) bool {
-	return localhostIPRegexp.MatchString(ip)
-}
-
-// IsIPv4Localhost returns true if ip matches the IPv4 localhost regular expression.
-func IsIPv4Localhost(ip string) bool {
-	return localhostIPv4Regexp.MatchString(ip)
-}

+ 30 - 20
libnetwork/resolvconf/resolvconf.go

@@ -8,9 +8,6 @@ import (
 	"strings"
 	"strings"
 	"sync"
 	"sync"
 
 
-	"github.com/docker/docker/libnetwork/resolvconf/dns"
-	"github.com/docker/docker/libnetwork/types"
-	"github.com/docker/docker/pkg/ioutils"
 	"github.com/sirupsen/logrus"
 	"github.com/sirupsen/logrus"
 )
 )
 
 
@@ -21,6 +18,13 @@ const (
 	alternatePath = "/run/systemd/resolve/resolv.conf"
 	alternatePath = "/run/systemd/resolve/resolv.conf"
 )
 )
 
 
+// constants for the IP address type
+const (
+	IP = iota // IPv4 and IPv6
+	IPv4
+	IPv6
+)
+
 var (
 var (
 	detectSystemdResolvConfOnce sync.Once
 	detectSystemdResolvConfOnce sync.Once
 	pathAfterSystemdDetection   = defaultPath
 	pathAfterSystemdDetection   = defaultPath
@@ -44,7 +48,7 @@ func Path() string {
 			// silencing error as it will resurface at next calls trying to read defaultPath
 			// silencing error as it will resurface at next calls trying to read defaultPath
 			return
 			return
 		}
 		}
-		ns := GetNameservers(candidateResolvConf, types.IP)
+		ns := GetNameservers(candidateResolvConf, IP)
 		if len(ns) == 1 && ns[0] == "127.0.0.53" {
 		if len(ns) == 1 && ns[0] == "127.0.0.53" {
 			pathAfterSystemdDetection = alternatePath
 			pathAfterSystemdDetection = alternatePath
 			logrus.Infof("detected 127.0.0.53 nameserver, assuming systemd-resolved, so using resolv.conf: %s", alternatePath)
 			logrus.Infof("detected 127.0.0.53 nameserver, assuming systemd-resolved, so using resolv.conf: %s", alternatePath)
@@ -53,20 +57,26 @@ func Path() string {
 	return pathAfterSystemdDetection
 	return pathAfterSystemdDetection
 }
 }
 
 
-var (
-	// Note: the default IPv4 & IPv6 resolvers are set to Google's Public DNS
-	defaultIPv4Dns = []string{"nameserver 8.8.8.8", "nameserver 8.8.4.4"}
-	defaultIPv6Dns = []string{"nameserver 2001:4860:4860::8888", "nameserver 2001:4860:4860::8844"}
-	ipv4NumBlock   = `(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)`
-	ipv4Address    = `(` + ipv4NumBlock + `\.){3}` + ipv4NumBlock
+const (
+	// ipLocalhost is a regex pattern for IPv4 or IPv6 loopback range.
+	ipLocalhost  = `((127\.([0-9]{1,3}\.){2}[0-9]{1,3})|(::1)$)`
+	ipv4NumBlock = `(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)`
+	ipv4Address  = `(` + ipv4NumBlock + `\.){3}` + ipv4NumBlock
+
 	// This is not an IPv6 address verifier as it will accept a super-set of IPv6, and also
 	// This is not an IPv6 address verifier as it will accept a super-set of IPv6, and also
 	// will *not match* IPv4-Embedded IPv6 Addresses (RFC6052), but that and other variants
 	// will *not match* IPv4-Embedded IPv6 Addresses (RFC6052), but that and other variants
 	// -- e.g. other link-local types -- either won't work in containers or are unnecessary.
 	// -- e.g. other link-local types -- either won't work in containers or are unnecessary.
 	// For readability and sufficiency for Docker purposes this seemed more reasonable than a
 	// For readability and sufficiency for Docker purposes this seemed more reasonable than a
 	// 1000+ character regexp with exact and complete IPv6 validation
 	// 1000+ character regexp with exact and complete IPv6 validation
 	ipv6Address = `([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{0,4})(%\w+)?`
 	ipv6Address = `([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{0,4})(%\w+)?`
+)
+
+var (
+	// Note: the default IPv4 & IPv6 resolvers are set to Google's Public DNS
+	defaultIPv4Dns = []string{"nameserver 8.8.8.8", "nameserver 8.8.4.4"}
+	defaultIPv6Dns = []string{"nameserver 2001:4860:4860::8888", "nameserver 2001:4860:4860::8844"}
 
 
-	localhostNSRegexp = regexp.MustCompile(`(?m)^nameserver\s+` + dns.IPLocalhost + `\s*\n*`)
+	localhostNSRegexp = regexp.MustCompile(`(?m)^nameserver\s+` + ipLocalhost + `\s*\n*`)
 	nsIPv6Regexp      = regexp.MustCompile(`(?m)^nameserver\s+` + ipv6Address + `\s*\n*`)
 	nsIPv6Regexp      = regexp.MustCompile(`(?m)^nameserver\s+` + ipv6Address + `\s*\n*`)
 	nsRegexp          = regexp.MustCompile(`^\s*nameserver\s*((` + ipv4Address + `)|(` + ipv6Address + `))\s*$`)
 	nsRegexp          = regexp.MustCompile(`^\s*nameserver\s*((` + ipv4Address + `)|(` + ipv6Address + `))\s*$`)
 	nsIPv6Regexpmatch = regexp.MustCompile(`^\s*nameserver\s*((` + ipv6Address + `))\s*$`)
 	nsIPv6Regexpmatch = regexp.MustCompile(`^\s*nameserver\s*((` + ipv6Address + `))\s*$`)
@@ -98,7 +108,7 @@ func GetSpecific(path string) (*File, error) {
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	hash, err := ioutils.HashData(bytes.NewReader(resolv))
+	hash, err := hashData(bytes.NewReader(resolv))
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -116,7 +126,7 @@ func GetIfChanged() (*File, error) {
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	newHash, err := ioutils.HashData(bytes.NewReader(resolv))
+	newHash, err := hashData(bytes.NewReader(resolv))
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -153,7 +163,7 @@ func FilterResolvDNS(resolvConf []byte, ipv6Enabled bool) (*File, error) {
 	}
 	}
 	// if the resulting resolvConf has no more nameservers defined, add appropriate
 	// if the resulting resolvConf has no more nameservers defined, add appropriate
 	// default DNS servers for IPv4 and (optionally) IPv6
 	// default DNS servers for IPv4 and (optionally) IPv6
-	if len(GetNameservers(cleanedResolvConf, types.IP)) == 0 {
+	if len(GetNameservers(cleanedResolvConf, IP)) == 0 {
 		logrus.Infof("No non-localhost DNS nameservers are left in resolv.conf. Using default external servers: %v", defaultIPv4Dns)
 		logrus.Infof("No non-localhost DNS nameservers are left in resolv.conf. Using default external servers: %v", defaultIPv4Dns)
 		dns := defaultIPv4Dns
 		dns := defaultIPv4Dns
 		if ipv6Enabled {
 		if ipv6Enabled {
@@ -162,7 +172,7 @@ func FilterResolvDNS(resolvConf []byte, ipv6Enabled bool) (*File, error) {
 		}
 		}
 		cleanedResolvConf = append(cleanedResolvConf, []byte("\n"+strings.Join(dns, "\n"))...)
 		cleanedResolvConf = append(cleanedResolvConf, []byte("\n"+strings.Join(dns, "\n"))...)
 	}
 	}
-	hash, err := ioutils.HashData(bytes.NewReader(cleanedResolvConf))
+	hash, err := hashData(bytes.NewReader(cleanedResolvConf))
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -189,11 +199,11 @@ func GetNameservers(resolvConf []byte, kind int) []string {
 	nameservers := []string{}
 	nameservers := []string{}
 	for _, line := range getLines(resolvConf, []byte("#")) {
 	for _, line := range getLines(resolvConf, []byte("#")) {
 		var ns [][]byte
 		var ns [][]byte
-		if kind == types.IP {
+		if kind == IP {
 			ns = nsRegexp.FindSubmatch(line)
 			ns = nsRegexp.FindSubmatch(line)
-		} else if kind == types.IPv4 {
+		} else if kind == IPv4 {
 			ns = nsIPv4Regexpmatch.FindSubmatch(line)
 			ns = nsIPv4Regexpmatch.FindSubmatch(line)
-		} else if kind == types.IPv6 {
+		} else if kind == IPv6 {
 			ns = nsIPv6Regexpmatch.FindSubmatch(line)
 			ns = nsIPv6Regexpmatch.FindSubmatch(line)
 		}
 		}
 		if len(ns) > 0 {
 		if len(ns) > 0 {
@@ -208,7 +218,7 @@ func GetNameservers(resolvConf []byte, kind int) []string {
 // This function's output is intended for net.ParseCIDR
 // This function's output is intended for net.ParseCIDR
 func GetNameserversAsCIDR(resolvConf []byte) []string {
 func GetNameserversAsCIDR(resolvConf []byte) []string {
 	nameservers := []string{}
 	nameservers := []string{}
-	for _, nameserver := range GetNameservers(resolvConf, types.IP) {
+	for _, nameserver := range GetNameservers(resolvConf, IP) {
 		var address string
 		var address string
 		// If IPv6, strip zone if present
 		// If IPv6, strip zone if present
 		if strings.Contains(nameserver, ":") {
 		if strings.Contains(nameserver, ":") {
@@ -276,7 +286,7 @@ func Build(path string, dns, dnsSearch, dnsOptions []string) (*File, error) {
 		}
 		}
 	}
 	}
 
 
-	hash, err := ioutils.HashData(bytes.NewReader(content.Bytes()))
+	hash, err := hashData(bytes.NewReader(content.Bytes()))
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}

+ 2 - 5
libnetwork/resolvconf/resolvconf_linux_test.go

@@ -5,9 +5,6 @@ import (
 	"io/ioutil"
 	"io/ioutil"
 	"os"
 	"os"
 	"testing"
 	"testing"
-
-	"github.com/docker/docker/libnetwork/types"
-	"github.com/docker/docker/pkg/ioutils"
 )
 )
 
 
 func TestGet(t *testing.T) {
 func TestGet(t *testing.T) {
@@ -22,7 +19,7 @@ func TestGet(t *testing.T) {
 	if string(resolvConfUtils.Content) != string(resolvConfSystem) {
 	if string(resolvConfUtils.Content) != string(resolvConfSystem) {
 		t.Fatalf("/etc/resolv.conf and GetResolvConf have different content.")
 		t.Fatalf("/etc/resolv.conf and GetResolvConf have different content.")
 	}
 	}
-	hashSystem, err := ioutils.HashData(bytes.NewReader(resolvConfSystem))
+	hashSystem, err := hashData(bytes.NewReader(resolvConfSystem))
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
@@ -48,7 +45,7 @@ nameserver 1.2.3.4
 		`search example.com
 		`search example.com
 nameserver 1.2.3.4 # not 4.3.2.1`: {"1.2.3.4"},
 nameserver 1.2.3.4 # not 4.3.2.1`: {"1.2.3.4"},
 	} {
 	} {
-		test := GetNameservers([]byte(resolv), types.IP)
+		test := GetNameservers([]byte(resolv), IP)
 		if !strSlicesEqual(test, result) {
 		if !strSlicesEqual(test, result) {
 			t.Fatalf("Wrong nameserver string {%s} should be %v. Input: %s", test, result, resolv)
 			t.Fatalf("Wrong nameserver string {%s} should be %v. Input: %s", test, result, resolv)
 		}
 		}

+ 16 - 0
libnetwork/resolvconf/utils.go

@@ -0,0 +1,16 @@
+package resolvconf
+
+import (
+	"crypto/sha256"
+	"encoding/hex"
+	"io"
+)
+
+// hashData returns the sha256 sum of src.
+func hashData(src io.Reader) (string, error) {
+	h := sha256.New()
+	if _, err := io.Copy(h, src); err != nil {
+		return "", err
+	}
+	return "sha256:" + hex.EncodeToString(h.Sum(nil)), nil
+}

+ 18 - 0
libnetwork/resolvconf/utils_test.go

@@ -0,0 +1,18 @@
+package resolvconf
+
+import (
+	"strings"
+	"testing"
+)
+
+func TestHashData(t *testing.T) {
+	reader := strings.NewReader("hash-me")
+	actual, err := hashData(reader)
+	if err != nil {
+		t.Fatal(err)
+	}
+	expected := "sha256:4d11186aed035cc624d553e10db358492c84a7cd6b9670d92123c144930450aa"
+	if actual != expected {
+		t.Fatalf("Expecting %s, got %s", expected, actual)
+	}
+}

+ 20 - 8
libnetwork/sandbox_dns_unix.go

@@ -5,6 +5,7 @@ package libnetwork
 import (
 import (
 	"fmt"
 	"fmt"
 	"io/ioutil"
 	"io/ioutil"
+	"net"
 	"os"
 	"os"
 	"path"
 	"path"
 	"path/filepath"
 	"path/filepath"
@@ -13,7 +14,6 @@ import (
 
 
 	"github.com/docker/docker/libnetwork/etchosts"
 	"github.com/docker/docker/libnetwork/etchosts"
 	"github.com/docker/docker/libnetwork/resolvconf"
 	"github.com/docker/docker/libnetwork/resolvconf"
-	"github.com/docker/docker/libnetwork/resolvconf/dns"
 	"github.com/docker/docker/libnetwork/types"
 	"github.com/docker/docker/libnetwork/types"
 	"github.com/sirupsen/logrus"
 	"github.com/sirupsen/logrus"
 )
 )
@@ -171,8 +171,8 @@ func (sb *sandbox) setExternalResolvers(content []byte, addrType int, checkLoopb
 	servers := resolvconf.GetNameservers(content, addrType)
 	servers := resolvconf.GetNameservers(content, addrType)
 	for _, ip := range servers {
 	for _, ip := range servers {
 		hostLoopback := false
 		hostLoopback := false
-		if checkLoopback {
-			hostLoopback = dns.IsIPv4Localhost(ip)
+		if checkLoopback && isIPv4Loopback(ip) {
+			hostLoopback = true
 		}
 		}
 		sb.extDNS = append(sb.extDNS, extDNSEntry{
 		sb.extDNS = append(sb.extDNS, extDNSEntry{
 			IPStr:        ip,
 			IPStr:        ip,
@@ -181,6 +181,18 @@ func (sb *sandbox) setExternalResolvers(content []byte, addrType int, checkLoopb
 	}
 	}
 }
 }
 
 
+// isIPv4Loopback checks if the given IP address is an IPv4 loopback address.
+// It's based on the logic in Go's net.IP.IsLoopback(), but only the IPv4 part:
+// https://github.com/golang/go/blob/go1.16.6/src/net/ip.go#L120-L126
+func isIPv4Loopback(ipAddress string) bool {
+	if ip := net.ParseIP(ipAddress); ip != nil {
+		if ip4 := ip.To4(); ip4 != nil {
+			return ip4[0] == 127
+		}
+	}
+	return false
+}
+
 func (sb *sandbox) setupDNS() error {
 func (sb *sandbox) setupDNS() error {
 	var newRC *resolvconf.File
 	var newRC *resolvconf.File
 
 
@@ -233,7 +245,7 @@ func (sb *sandbox) setupDNS() error {
 	if len(sb.config.dnsList) > 0 || len(sb.config.dnsSearchList) > 0 || len(sb.config.dnsOptionsList) > 0 {
 	if len(sb.config.dnsList) > 0 || len(sb.config.dnsSearchList) > 0 || len(sb.config.dnsOptionsList) > 0 {
 		var (
 		var (
 			err            error
 			err            error
-			dnsList        = resolvconf.GetNameservers(currRC.Content, types.IP)
+			dnsList        = resolvconf.GetNameservers(currRC.Content, resolvconf.IP)
 			dnsSearchList  = resolvconf.GetSearchDomains(currRC.Content)
 			dnsSearchList  = resolvconf.GetSearchDomains(currRC.Content)
 			dnsOptionsList = resolvconf.GetOptions(currRC.Content)
 			dnsOptionsList = resolvconf.GetOptions(currRC.Content)
 		)
 		)
@@ -253,13 +265,13 @@ func (sb *sandbox) setupDNS() error {
 		// After building the resolv.conf from the user config save the
 		// After building the resolv.conf from the user config save the
 		// external resolvers in the sandbox. Note that --dns 127.0.0.x
 		// external resolvers in the sandbox. Note that --dns 127.0.0.x
 		// config refers to the loopback in the container namespace
 		// config refers to the loopback in the container namespace
-		sb.setExternalResolvers(newRC.Content, types.IPv4, false)
+		sb.setExternalResolvers(newRC.Content, resolvconf.IPv4, false)
 	} else {
 	} else {
 		// If the host resolv.conf file has 127.0.0.x container should
 		// If the host resolv.conf file has 127.0.0.x container should
 		// use the host resolver for queries. This is supported by the
 		// use the host resolver for queries. This is supported by the
 		// docker embedded DNS server. Hence save the external resolvers
 		// docker embedded DNS server. Hence save the external resolvers
 		// before filtering it out.
 		// before filtering it out.
-		sb.setExternalResolvers(currRC.Content, types.IPv4, true)
+		sb.setExternalResolvers(currRC.Content, resolvconf.IPv4, true)
 
 
 		// Replace any localhost/127.* (at this point we have no info about ipv6, pass it as true)
 		// Replace any localhost/127.* (at this point we have no info about ipv6, pass it as true)
 		if newRC, err = resolvconf.FilterResolvDNS(currRC.Content, true); err != nil {
 		if newRC, err = resolvconf.FilterResolvDNS(currRC.Content, true); err != nil {
@@ -358,7 +370,7 @@ func (sb *sandbox) rebuildDNS() error {
 	}
 	}
 
 
 	if len(sb.extDNS) == 0 {
 	if len(sb.extDNS) == 0 {
-		sb.setExternalResolvers(currRC.Content, types.IPv4, false)
+		sb.setExternalResolvers(currRC.Content, resolvconf.IPv4, false)
 	}
 	}
 	var (
 	var (
 		dnsList        = []string{sb.resolver.NameServer()}
 		dnsList        = []string{sb.resolver.NameServer()}
@@ -367,7 +379,7 @@ func (sb *sandbox) rebuildDNS() error {
 	)
 	)
 
 
 	// external v6 DNS servers has to be listed in resolv.conf
 	// external v6 DNS servers has to be listed in resolv.conf
-	dnsList = append(dnsList, resolvconf.GetNameservers(currRC.Content, types.IPv6)...)
+	dnsList = append(dnsList, resolvconf.GetNameservers(currRC.Content, resolvconf.IPv6)...)
 
 
 	// If the user config and embedded DNS server both have ndots option set,
 	// If the user config and embedded DNS server both have ndots option set,
 	// remember the user's config so that unqualified names not in the docker
 	// remember the user's config so that unqualified names not in the docker

+ 1 - 0
libnetwork/types/types.go

@@ -12,6 +12,7 @@ import (
 )
 )
 
 
 // constants for the IP address type
 // constants for the IP address type
+// Deprecated: use the consts defined in github.com/docker/docker/libnetwork/resolvconf
 const (
 const (
 	IP = iota // IPv4 and IPv6
 	IP = iota // IPv4 and IPv6
 	IPv4
 	IPv4

+ 5 - 11
pkg/ioutils/readers.go

@@ -2,9 +2,12 @@ package ioutils // import "github.com/docker/docker/pkg/ioutils"
 
 
 import (
 import (
 	"context"
 	"context"
-	"crypto/sha256"
-	"encoding/hex"
 	"io"
 	"io"
+
+	// make sure crypto.SHA256, crypto.sha512 and crypto.SHA384 are registered
+	// TODO remove once https://github.com/opencontainers/go-digest/pull/64 is merged.
+	_ "crypto/sha256"
+	_ "crypto/sha512"
 )
 )
 
 
 // ReadCloserWrapper wraps an io.Reader, and implements an io.ReadCloser
 // ReadCloserWrapper wraps an io.Reader, and implements an io.ReadCloser
@@ -49,15 +52,6 @@ func NewReaderErrWrapper(r io.Reader, closer func()) io.Reader {
 	}
 	}
 }
 }
 
 
-// HashData returns the sha256 sum of src.
-func HashData(src io.Reader) (string, error) {
-	h := sha256.New()
-	if _, err := io.Copy(h, src); err != nil {
-		return "", err
-	}
-	return "sha256:" + hex.EncodeToString(h.Sum(nil)), nil
-}
-
 // OnEOFReader wraps an io.ReadCloser and a function
 // OnEOFReader wraps an io.ReadCloser and a function
 // the function will run at the end of file or close the file.
 // the function will run at the end of file or close the file.
 type OnEOFReader struct {
 type OnEOFReader struct {

+ 0 - 12
pkg/ioutils/readers_test.go

@@ -58,18 +58,6 @@ func TestReaderErrWrapperRead(t *testing.T) {
 	}
 	}
 }
 }
 
 
-func TestHashData(t *testing.T) {
-	reader := strings.NewReader("hash-me")
-	actual, err := HashData(reader)
-	if err != nil {
-		t.Fatal(err)
-	}
-	expected := "sha256:4d11186aed035cc624d553e10db358492c84a7cd6b9670d92123c144930450aa"
-	if actual != expected {
-		t.Fatalf("Expecting %s, got %s", expected, actual)
-	}
-}
-
 type perpetualReader struct{}
 type perpetualReader struct{}
 
 
 func (p *perpetualReader) Read(buf []byte) (n int, err error) {
 func (p *perpetualReader) Read(buf []byte) (n int, err error) {