build: buildkit now also uses systemd's resolv.conf
Signed-off-by: Tibor Vass <tibor@docker.com>
This commit is contained in:
parent
2e58093662
commit
8ff4ec98cf
8 changed files with 55 additions and 182 deletions
|
@ -9,18 +9,13 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/daemon/config"
|
"github.com/docker/docker/daemon/config"
|
||||||
"github.com/docker/docker/internal/procfs"
|
|
||||||
"github.com/docker/docker/pkg/fileutils"
|
"github.com/docker/docker/pkg/fileutils"
|
||||||
"github.com/docker/docker/pkg/mount"
|
"github.com/docker/docker/pkg/mount"
|
||||||
|
"github.com/docker/libnetwork/resolvconf"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
defaultResolvConf = "/etc/resolv.conf"
|
|
||||||
alternateResolvConf = "/run/systemd/resolve/resolv.conf"
|
|
||||||
)
|
|
||||||
|
|
||||||
// On Linux, plugins use a static path for storing execution state,
|
// On Linux, plugins use a static path for storing execution state,
|
||||||
// instead of deriving path from daemon's exec-root. This is because
|
// instead of deriving path from daemon's exec-root. This is because
|
||||||
// plugin socket files are created here and they cannot exceed max
|
// plugin socket files are created here and they cannot exceed max
|
||||||
|
@ -148,20 +143,5 @@ func setupResolvConf(config *config.Config) {
|
||||||
if config.ResolvConf != "" {
|
if config.ResolvConf != "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
config.ResolvConf = resolvconf.Path()
|
||||||
config.ResolvConf = defaultResolvConf
|
|
||||||
pids, err := procfs.PidOf("systemd-resolved")
|
|
||||||
if err != nil {
|
|
||||||
logrus.Errorf("unable to check systemd-resolved status: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(pids) > 0 && pids[0] > 0 {
|
|
||||||
_, err := os.Stat(alternateResolvConf)
|
|
||||||
if err == nil {
|
|
||||||
logrus.Infof("systemd-resolved is running, so using resolvconf: %s", alternateResolvConf)
|
|
||||||
config.ResolvConf = alternateResolvConf
|
|
||||||
return
|
|
||||||
}
|
|
||||||
logrus.Infof("systemd-resolved is running, but %s is not present, fallback to %s", alternateResolvConf, defaultResolvConf)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
package procfs
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2015 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"unicode"
|
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PidOf finds process(es) with a specified name (regexp match)
|
|
||||||
// and return their pid(s)
|
|
||||||
func PidOf(name string) ([]int, error) {
|
|
||||||
if len(name) == 0 {
|
|
||||||
return []int{}, fmt.Errorf("name should not be empty")
|
|
||||||
}
|
|
||||||
re, err := regexp.Compile("(^|/)" + name + "$")
|
|
||||||
if err != nil {
|
|
||||||
return []int{}, err
|
|
||||||
}
|
|
||||||
return getPids(re), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPids(re *regexp.Regexp) []int {
|
|
||||||
pids := []int{}
|
|
||||||
|
|
||||||
dirFD, err := os.Open("/proc")
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
defer dirFD.Close()
|
|
||||||
|
|
||||||
for {
|
|
||||||
// Read a small number at a time in case there are many entries, we don't want to
|
|
||||||
// allocate a lot here.
|
|
||||||
ls, err := dirFD.Readdir(10)
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, entry := range ls {
|
|
||||||
if !entry.IsDir() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the directory is not a number (i.e. not a PID), skip it
|
|
||||||
pid, err := strconv.Atoi(entry.Name())
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
cmdline, err := ioutil.ReadFile(filepath.Join("/proc", entry.Name(), "cmdline"))
|
|
||||||
if err != nil {
|
|
||||||
logrus.Infof("Error reading file %s: %+v", filepath.Join("/proc", entry.Name(), "cmdline"), err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// The bytes we read have '\0' as a separator for the command line
|
|
||||||
parts := bytes.SplitN(cmdline, []byte{0}, 2)
|
|
||||||
if len(parts) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Split the command line itself we are interested in just the first part
|
|
||||||
exe := strings.FieldsFunc(string(parts[0]), func(c rune) bool {
|
|
||||||
return unicode.IsSpace(c) || c == ':'
|
|
||||||
})
|
|
||||||
if len(exe) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Check if the name of the executable is what we are looking for
|
|
||||||
if re.MatchString(exe[0]) {
|
|
||||||
// Grab the PID from the directory path
|
|
||||||
pids = append(pids, pid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pids
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package procfs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"gotest.tools/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPidOf(t *testing.T) {
|
|
||||||
pids, err := PidOf(filepath.Base(os.Args[0]))
|
|
||||||
assert.NilError(t, err)
|
|
||||||
assert.Check(t, len(pids) == 1)
|
|
||||||
assert.DeepEqual(t, pids[0], os.Getpid())
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkGetPids(b *testing.B) {
|
|
||||||
if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
|
|
||||||
b.Skipf("not supported on GOOS=%s", runtime.GOOS)
|
|
||||||
}
|
|
||||||
|
|
||||||
re, err := regexp.Compile("(^|/)" + filepath.Base(os.Args[0]) + "$")
|
|
||||||
assert.Check(b, err == nil)
|
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
pids := getPids(re)
|
|
||||||
|
|
||||||
b.StopTimer()
|
|
||||||
assert.Check(b, len(pids) > 0)
|
|
||||||
assert.Check(b, pids[0] == os.Getpid())
|
|
||||||
b.StartTimer()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -27,7 +27,7 @@ github.com/imdario/mergo 7c29201646fa3de8506f70121347
|
||||||
golang.org/x/sync e225da77a7e68af35c70ccbf71af2b83e6acac3c
|
golang.org/x/sync e225da77a7e68af35c70ccbf71af2b83e6acac3c
|
||||||
|
|
||||||
# buildkit
|
# buildkit
|
||||||
github.com/moby/buildkit 37d53758a68d9f5cede1806dbb2da7c3caa8d5bc
|
github.com/moby/buildkit 1f89ec125f84c097bdf3a063be622c4238dba5f8
|
||||||
github.com/tonistiigi/fsutil 3bbb99cdbd76619ab717299830c60f6f2a533a6b
|
github.com/tonistiigi/fsutil 3bbb99cdbd76619ab717299830c60f6f2a533a6b
|
||||||
github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
|
github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
|
||||||
github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
|
github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
|
||||||
|
@ -39,7 +39,7 @@ github.com/gofrs/flock 7f43ea2e6a643ad441fc12d0ecc0
|
||||||
# libnetwork
|
# libnetwork
|
||||||
|
|
||||||
# When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy.installer accordingly
|
# When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy.installer accordingly
|
||||||
github.com/docker/libnetwork 5ac07abef4eee176423fdc1b870d435258e2d381
|
github.com/docker/libnetwork fc5a7d91d54cc98f64fc28f9e288b46a0bee756c
|
||||||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||||
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
|
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
|
||||||
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
||||||
|
|
20
vendor/github.com/docker/libnetwork/controller.go
generated
vendored
20
vendor/github.com/docker/libnetwork/controller.go
generated
vendored
|
@ -339,7 +339,6 @@ func (c *controller) clusterAgentInit() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case cluster.EventNodeLeave:
|
case cluster.EventNodeLeave:
|
||||||
keysAvailable = false
|
|
||||||
c.agentOperationStart()
|
c.agentOperationStart()
|
||||||
c.Lock()
|
c.Lock()
|
||||||
c.keys = nil
|
c.keys = nil
|
||||||
|
@ -706,11 +705,17 @@ const overlayDSROptionString = "dsr"
|
||||||
// NewNetwork creates a new network of the specified network type. The options
|
// NewNetwork creates a new network of the specified network type. The options
|
||||||
// are network specific and modeled in a generic way.
|
// are network specific and modeled in a generic way.
|
||||||
func (c *controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) {
|
func (c *controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) {
|
||||||
|
var (
|
||||||
|
cap *driverapi.Capability
|
||||||
|
err error
|
||||||
|
t *network
|
||||||
|
)
|
||||||
|
|
||||||
if id != "" {
|
if id != "" {
|
||||||
c.networkLocker.Lock(id)
|
c.networkLocker.Lock(id)
|
||||||
defer c.networkLocker.Unlock(id)
|
defer c.networkLocker.Unlock(id)
|
||||||
|
|
||||||
if _, err := c.NetworkByID(id); err == nil {
|
if _, err = c.NetworkByID(id); err == nil {
|
||||||
return nil, NetworkNameError(id)
|
return nil, NetworkNameError(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -739,15 +744,10 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
|
||||||
}
|
}
|
||||||
|
|
||||||
network.processOptions(options...)
|
network.processOptions(options...)
|
||||||
if err := network.validateConfiguration(); err != nil {
|
if err = network.validateConfiguration(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
cap *driverapi.Capability
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reset network types, force local scope and skip allocation and
|
// Reset network types, force local scope and skip allocation and
|
||||||
// plumbing for configuration networks. Reset of the config-only
|
// plumbing for configuration networks. Reset of the config-only
|
||||||
// network drivers is needed so that this special network is not
|
// network drivers is needed so that this special network is not
|
||||||
|
@ -794,11 +794,11 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
|
||||||
// From this point on, we need the network specific configuration,
|
// From this point on, we need the network specific configuration,
|
||||||
// which may come from a configuration-only network
|
// which may come from a configuration-only network
|
||||||
if network.configFrom != "" {
|
if network.configFrom != "" {
|
||||||
t, err := c.getConfigNetwork(network.configFrom)
|
t, err = c.getConfigNetwork(network.configFrom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.NotFoundErrorf("configuration network %q does not exist", network.configFrom)
|
return nil, types.NotFoundErrorf("configuration network %q does not exist", network.configFrom)
|
||||||
}
|
}
|
||||||
if err := t.applyConfigurationTo(network); err != nil {
|
if err = t.applyConfigurationTo(network); err != nil {
|
||||||
return nil, types.InternalErrorf("Failed to apply configuration: %v", err)
|
return nil, types.InternalErrorf("Failed to apply configuration: %v", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|
42
vendor/github.com/docker/libnetwork/resolvconf/resolvconf.go
generated
vendored
42
vendor/github.com/docker/libnetwork/resolvconf/resolvconf.go
generated
vendored
|
@ -15,10 +15,44 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DefaultResolvConf points to the default file used for dns configuration on a linux machine
|
// defaultPath is the default path to the resolv.conf that contains information to resolve DNS. See Path().
|
||||||
DefaultResolvConf = "/etc/resolv.conf"
|
defaultPath = "/etc/resolv.conf"
|
||||||
|
// alternatePath is a path different from defaultPath, that may be used to resolve DNS. See Path().
|
||||||
|
alternatePath = "/run/systemd/resolve/resolv.conf"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
detectSystemdResolvConfOnce sync.Once
|
||||||
|
pathAfterSystemdDetection = defaultPath
|
||||||
|
)
|
||||||
|
|
||||||
|
// Path returns the path to the resolv.conf file that libnetwork should use.
|
||||||
|
//
|
||||||
|
// When /etc/resolv.conf contains 127.0.0.53 as the only nameserver, then
|
||||||
|
// it is assumed systemd-resolved manages DNS. Because inside the container 127.0.0.53
|
||||||
|
// is not a valid DNS server, Path() returns /run/systemd/resolve/resolv.conf
|
||||||
|
// which is the resolv.conf that systemd-resolved generates and manages.
|
||||||
|
// Otherwise Path() returns /etc/resolv.conf.
|
||||||
|
//
|
||||||
|
// Errors are silenced as they will inevitably resurface at future open/read calls.
|
||||||
|
//
|
||||||
|
// More information at https://www.freedesktop.org/software/systemd/man/systemd-resolved.service.html#/etc/resolv.conf
|
||||||
|
func Path() string {
|
||||||
|
detectSystemdResolvConfOnce.Do(func() {
|
||||||
|
candidateResolvConf, err := ioutil.ReadFile(defaultPath)
|
||||||
|
if err != nil {
|
||||||
|
// silencing error as it will resurface at next calls trying to read defaultPath
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ns := GetNameservers(candidateResolvConf, types.IP)
|
||||||
|
if len(ns) == 1 && ns[0] == "127.0.0.53" {
|
||||||
|
pathAfterSystemdDetection = alternatePath
|
||||||
|
logrus.Infof("detected 127.0.0.53 nameserver, assuming systemd-resolved, so using resolv.conf: %s", alternatePath)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return pathAfterSystemdDetection
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Note: the default IPv4 & IPv6 resolvers are set to Google's Public DNS
|
// 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"}
|
defaultIPv4Dns = []string{"nameserver 8.8.8.8", "nameserver 8.8.4.4"}
|
||||||
|
@ -55,7 +89,7 @@ type File struct {
|
||||||
|
|
||||||
// Get returns the contents of /etc/resolv.conf and its hash
|
// Get returns the contents of /etc/resolv.conf and its hash
|
||||||
func Get() (*File, error) {
|
func Get() (*File, error) {
|
||||||
return GetSpecific(DefaultResolvConf)
|
return GetSpecific(Path())
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSpecific returns the contents of the user specified resolv.conf file and its hash
|
// GetSpecific returns the contents of the user specified resolv.conf file and its hash
|
||||||
|
@ -78,7 +112,7 @@ func GetIfChanged() (*File, error) {
|
||||||
lastModified.Lock()
|
lastModified.Lock()
|
||||||
defer lastModified.Unlock()
|
defer lastModified.Unlock()
|
||||||
|
|
||||||
resolv, err := ioutil.ReadFile("/etc/resolv.conf")
|
resolv, err := ioutil.ReadFile(Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
4
vendor/github.com/docker/libnetwork/sandbox_dns_unix.go
generated
vendored
4
vendor/github.com/docker/libnetwork/sandbox_dns_unix.go
generated
vendored
|
@ -213,8 +213,8 @@ func (sb *sandbox) setupDNS() error {
|
||||||
|
|
||||||
originResolvConfPath := sb.config.originResolvConfPath
|
originResolvConfPath := sb.config.originResolvConfPath
|
||||||
if originResolvConfPath == "" {
|
if originResolvConfPath == "" {
|
||||||
// if not specified fallback to default /etc/resolv.conf
|
// fallback if not specified
|
||||||
originResolvConfPath = resolvconf.DefaultResolvConf
|
originResolvConfPath = resolvconf.Path()
|
||||||
}
|
}
|
||||||
currRC, err := resolvconf.GetSpecific(originResolvConfPath)
|
currRC, err := resolvconf.GetSpecific(originResolvConfPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
2
vendor/github.com/moby/buildkit/executor/oci/resolvconf.go
generated
vendored
2
vendor/github.com/moby/buildkit/executor/oci/resolvconf.go
generated
vendored
|
@ -29,7 +29,7 @@ func GetResolvConf(ctx context.Context, stateDir string) (string, error) {
|
||||||
generate = true
|
generate = true
|
||||||
}
|
}
|
||||||
if !generate {
|
if !generate {
|
||||||
fiMain, err := os.Stat("/etc/resolv.conf")
|
fiMain, err := os.Stat(resolvconf.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in a new issue