Merge pull request #2835 from thaJeztah/bump_docker

vendor: update docker/docker and moby/sys
This commit is contained in:
Sebastiaan van Stijn 2020-11-12 21:07:43 +01:00 committed by GitHub
commit a7150fce23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 468 additions and 228 deletions

View File

@ -13,7 +13,7 @@ github.com/creack/pty 2a38352e8b4d7ab6c336eef107e4
github.com/davecgh/go-spew 8991bc29aa16c548c550c7ff78260e27b9ab7c73 # v1.1.1 github.com/davecgh/go-spew 8991bc29aa16c548c550c7ff78260e27b9ab7c73 # v1.1.1
github.com/docker/compose-on-kubernetes 78e6a00beda64ac8ccb9fec787e601fe2ce0d5bb # v0.5.0-alpha1 github.com/docker/compose-on-kubernetes 78e6a00beda64ac8ccb9fec787e601fe2ce0d5bb # v0.5.0-alpha1
github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580 github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
github.com/docker/docker c2cc352355d4c26be60be8ea3a1acfddc20fdfd3 github.com/docker/docker af34b94a78a194ae9bce48a200241d08c05b7187
github.com/docker/docker-credential-helpers 54f0238b6bf101fc3ad3b34114cb5520beb562f5 # v0.6.3 github.com/docker/docker-credential-helpers 54f0238b6bf101fc3ad3b34114cb5520beb562f5 # v0.6.3
github.com/docker/go d30aec9fd63c35133f8f79c3412ad91a3b08be06 # Contains a customized version of canonical/json and is used by Notary. The package is periodically rebased on current Go versions. github.com/docker/go d30aec9fd63c35133f8f79c3412ad91a3b08be06 # Contains a customized version of canonical/json and is used by Notary. The package is periodically rebased on current Go versions.
github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0 github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0
@ -47,7 +47,7 @@ github.com/Microsoft/hcsshim 5bc557dd210ff2caf615e6e22d39
github.com/miekg/pkcs11 210dc1e16747c5ba98a03bcbcf728c38086ea357 # v1.0.3 github.com/miekg/pkcs11 210dc1e16747c5ba98a03bcbcf728c38086ea357 # v1.0.3
github.com/mitchellh/mapstructure d16e9488127408e67948eb43b6d3fbb9f222da10 # v1.3.2 github.com/mitchellh/mapstructure d16e9488127408e67948eb43b6d3fbb9f222da10 # v1.3.2
github.com/moby/buildkit 4d1f260e8490ec438ab66e08bb105577aca0ce06 github.com/moby/buildkit 4d1f260e8490ec438ab66e08bb105577aca0ce06
github.com/moby/sys 6154f11e6840c0d6b0dbb23f4125a6134b3013c9 # mountinfo/v0.1.3 github.com/moby/sys 1bc8673b57550ddf85262eb0fed0aac651a37dab # symlink/v0.1.0 (latest tag, either mount/vXXX, mountinfo/vXXX or symlink/vXXX)
github.com/moby/term 7f0af18e79f2784809e9cef63d0df5aa2c79d76e github.com/moby/term 7f0af18e79f2784809e9cef63d0df5aa2c79d76e
github.com/modern-go/concurrent bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94 # 1.0.3 github.com/modern-go/concurrent bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94 # 1.0.3
github.com/modern-go/reflect2 4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd # 1.0.1 github.com/modern-go/reflect2 4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd # 1.0.1

View File

@ -113,7 +113,7 @@ type TmpfsOptions struct {
// TODO(stevvooe): There are several more tmpfs flags, specified in the // TODO(stevvooe): There are several more tmpfs flags, specified in the
// daemon, that are accepted. Only the most basic are added for now. // daemon, that are accepted. Only the most basic are added for now.
// //
// From docker/docker/pkg/mount/flags.go: // From https://github.com/moby/sys/blob/mount/v0.1.1/mount/flags.go#L47-L56
// //
// var validFlags = map[string]bool{ // var validFlags = map[string]bool{
// "": true, // "": true,

View File

@ -9,7 +9,7 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/docker/docker/pkg/symlink" "github.com/moby/sys/symlink"
"github.com/pkg/errors" "github.com/pkg/errors"
) )

View File

@ -1,4 +1,4 @@
// +build !windows // +build !darwin,!windows
package system // import "github.com/docker/docker/pkg/system" package system // import "github.com/docker/docker/pkg/system"

View File

@ -77,22 +77,21 @@ func (err fallbackError) Error() string {
// endpoint will be pinged to get authorization challenges. These challenges // endpoint will be pinged to get authorization challenges. These challenges
// will be used to authenticate against the registry to validate credentials. // will be used to authenticate against the registry to validate credentials.
func loginV2(authConfig *types.AuthConfig, endpoint APIEndpoint, userAgent string) (string, string, error) { func loginV2(authConfig *types.AuthConfig, endpoint APIEndpoint, userAgent string) (string, string, error) {
logrus.Debugf("attempting v2 login to registry endpoint %s", strings.TrimRight(endpoint.URL.String(), "/")+"/v2/") var (
endpointStr = strings.TrimRight(endpoint.URL.String(), "/") + "/v2/"
modifiers = Headers(userAgent, nil)
authTransport = transport.NewTransport(NewTransport(endpoint.TLSConfig), modifiers...)
credentialAuthConfig = *authConfig
creds = loginCredentialStore{authConfig: &credentialAuthConfig}
)
modifiers := Headers(userAgent, nil) logrus.Debugf("attempting v2 login to registry endpoint %s", endpointStr)
authTransport := transport.NewTransport(NewTransport(endpoint.TLSConfig), modifiers...)
credentialAuthConfig := *authConfig
creds := loginCredentialStore{
authConfig: &credentialAuthConfig,
}
loginClient, foundV2, err := v2AuthHTTPClient(endpoint.URL, authTransport, modifiers, creds, nil) loginClient, foundV2, err := v2AuthHTTPClient(endpoint.URL, authTransport, modifiers, creds, nil)
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
endpointStr := strings.TrimRight(endpoint.URL.String(), "/") + "/v2/"
req, err := http.NewRequest(http.MethodGet, endpointStr, nil) req, err := http.NewRequest(http.MethodGet, endpointStr, nil)
if err != nil { if err != nil {
if !foundV2 { if !foundV2 {

View File

@ -9,14 +9,20 @@ github.com/Microsoft/opengcs a10967154e143a36014584a6f664
github.com/moby/locker 281af2d563954745bea9d1487c965f24d30742fe # v1.0.1 github.com/moby/locker 281af2d563954745bea9d1487c965f24d30742fe # v1.0.1
github.com/moby/term 7f0af18e79f2784809e9cef63d0df5aa2c79d76e github.com/moby/term 7f0af18e79f2784809e9cef63d0df5aa2c79d76e
# Note that this dependency uses submodules, providing the github.com/moby/sys/mount,
# github.com/moby/sys/mountinfo, and github.com/moby/sys/symlink modules. Our vendoring
# tool (vndr) currently does not support submodules / vendoring sub-paths, so we vendor
# the top-level moby/sys repository (which contains both) and pick the most recent tag,
# which could be either `mountinfo/vX.Y.Z`, `mount/vX.Y.Z`, or `symlink/vX.Y.Z`.
github.com/moby/sys 1bc8673b57550ddf85262eb0fed0aac651a37dab # symlink/v0.1.0
github.com/creack/pty 3a6a957789163cacdfe0e291617a1c8e80612c11 # v1.1.9 github.com/creack/pty 3a6a957789163cacdfe0e291617a1c8e80612c11 # v1.1.9
github.com/sirupsen/logrus 6699a89a232f3db797f2e280639854bbc4b89725 # v1.7.0 github.com/sirupsen/logrus 6699a89a232f3db797f2e280639854bbc4b89725 # v1.7.0
github.com/tchap/go-patricia a7f0089c6f496e8e70402f61733606daa326cac5 # v2.3.0 github.com/tchap/go-patricia a7f0089c6f496e8e70402f61733606daa326cac5 # v2.3.0
golang.org/x/net ab34263943818b32f575efc978a3d24e80b04bd7 golang.org/x/net ab34263943818b32f575efc978a3d24e80b04bd7
golang.org/x/sys aee5d888a86055dc6ab0342f9cdc7b53aaeaec62 golang.org/x/sys eeed37f84f13f52d35e095e8023ba65671ff86a1
github.com/docker/go-units 519db1ee28dcc9fd2474ae59fca29a810482bfb1 # v0.4.0 github.com/docker/go-units 519db1ee28dcc9fd2474ae59fca29a810482bfb1 # v0.4.0
github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0 github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0
github.com/moby/sys 6154f11e6840c0d6b0dbb23f4125a6134b3013c9 # mountinfo/v0.1.3
golang.org/x/text 23ae387dee1f90d29a23c0e87ee0b46038fbed0e # v0.3.3 golang.org/x/text 23ae387dee1f90d29a23c0e87ee0b46038fbed0e # v0.3.3
gotest.tools/v3 bb0d8a963040ea5048dcef1a14d8f8b58a33d4b3 # v3.0.2 gotest.tools/v3 bb0d8a963040ea5048dcef1a14d8f8b58a33d4b3 # v3.0.2
github.com/google/go-cmp 3af367b6b30c263d47e8895973edcca9a49cf029 # v0.2.0 github.com/google/go-cmp 3af367b6b30c263d47e8895973edcca9a49cf029 # v0.2.0
@ -40,7 +46,7 @@ github.com/grpc-ecosystem/go-grpc-middleware 3c51f7f332123e8be5a157c0802a
# 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 d0951081b35fa4216fc4f0064bf065beeb55a74b github.com/docker/libnetwork d511c60c5c23e6753631244f271a1ec6097254a5
github.com/docker/go-events e31b211e4f1cd09aa76fe4ac244571fab96ae47f github.com/docker/go-events e31b211e4f1cd09aa76fe4ac244571fab96ae47f
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
@ -161,7 +167,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus c225b8c3b01faf2899099b768856
github.com/cespare/xxhash/v2 d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1 github.com/cespare/xxhash/v2 d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1
# cli # cli
github.com/spf13/cobra a684a6d7f5e37385d954dd3b5a14fc6912c6ab9d # v1.0.0 github.com/spf13/cobra 86f8bfd7fef868a174e1b606783bd7f5c82ddf8f # v1.1.1
github.com/spf13/pflag 2e9d26c8c37aae03e3f9d4e90b7116f5accb7cab # v1.0.5 github.com/spf13/pflag 2e9d26c8c37aae03e3f9d4e90b7116f5accb7cab # v1.0.5
github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 # v1.0.0 github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 # v1.0.0
github.com/morikuni/aec 39771216ff4c63d11f5e604076f9c45e8be1067b # v1.0.0 github.com/morikuni/aec 39771216ff4c63d11f5e604076f9c45e8be1067b # v1.0.0

4
vendor/github.com/moby/sys/mount/doc.go generated vendored Normal file
View File

@ -0,0 +1,4 @@
// Package mount provides a set of functions to mount and unmount mounts.
//
// Currently it supports Linux. For historical reasons, there is also some support for FreeBSD.
package mount

View File

@ -1,28 +1,25 @@
// +build freebsd,cgo // +build freebsd openbsd
package mount package mount
/* import "golang.org/x/sys/unix"
#include <sys/mount.h>
*/
import "C"
const ( const (
// RDONLY will mount the filesystem as read-only. // RDONLY will mount the filesystem as read-only.
RDONLY = C.MNT_RDONLY RDONLY = unix.MNT_RDONLY
// NOSUID will not allow set-user-identifier or set-group-identifier bits to // NOSUID will not allow set-user-identifier or set-group-identifier bits to
// take effect. // take effect.
NOSUID = C.MNT_NOSUID NOSUID = unix.MNT_NOSUID
// NOEXEC will not allow execution of any binaries on the mounted file system. // NOEXEC will not allow execution of any binaries on the mounted file system.
NOEXEC = C.MNT_NOEXEC NOEXEC = unix.MNT_NOEXEC
// SYNCHRONOUS will allow any I/O to the file system to be done synchronously. // SYNCHRONOUS will allow any I/O to the file system to be done synchronously.
SYNCHRONOUS = C.MNT_SYNCHRONOUS SYNCHRONOUS = unix.MNT_SYNCHRONOUS
// NOATIME will not update the file access time when reading from a file. // NOATIME will not update the file access time when reading from a file.
NOATIME = C.MNT_NOATIME NOATIME = unix.MNT_NOATIME
) )
// These flags are unsupported. // These flags are unsupported.

View File

@ -1,3 +1,5 @@
// +build !darwin,!windows
package mount package mount
import ( import (

View File

@ -1,30 +0,0 @@
// +build !linux,!freebsd freebsd,!cgo
package mount
// These flags are unsupported.
const (
BIND = 0
DIRSYNC = 0
MANDLOCK = 0
NOATIME = 0
NODEV = 0
NODIRATIME = 0
NOEXEC = 0
NOSUID = 0
UNBINDABLE = 0
RUNBINDABLE = 0
PRIVATE = 0
RPRIVATE = 0
SHARED = 0
RSHARED = 0
SLAVE = 0
RSLAVE = 0
RBIND = 0
RELATIME = 0
REMOUNT = 0
STRICTATIME = 0
SYNCHRONOUS = 0
RDONLY = 0
mntDetach = 0
)

View File

@ -3,6 +3,6 @@ module github.com/moby/sys/mount
go 1.14 go 1.14
require ( require (
github.com/moby/sys/mountinfo v0.1.0 github.com/moby/sys/mountinfo v0.3.1
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae golang.org/x/sys v0.0.0-20200922070232-aee5d888a860
) )

View File

@ -1,56 +0,0 @@
// +build go1.13
package mount
import (
"fmt"
"sort"
"github.com/moby/sys/mountinfo"
)
// Mount will mount filesystem according to the specified configuration.
// Options must be specified like the mount or fstab unix commands:
// "opt1=val1,opt2=val2". See flags.go for supported option flags.
func Mount(device, target, mType, options string) error {
flag, data := parseOptions(options)
return mount(device, target, mType, uintptr(flag), data)
}
// Unmount lazily unmounts a filesystem on supported platforms, otherwise
// does a normal unmount.
func Unmount(target string) error {
return unmount(target, mntDetach)
}
// RecursiveUnmount unmounts the target and all mounts underneath, starting with
// the deepsest mount first.
func RecursiveUnmount(target string) error {
mounts, err := mountinfo.GetMounts(mountinfo.PrefixFilter(target))
if err != nil {
return err
}
// Make the deepest mount be first
sort.Slice(mounts, func(i, j int) bool {
return len(mounts[i].Mountpoint) > len(mounts[j].Mountpoint)
})
var suberr error
for i, m := range mounts {
err = unmount(m.Mountpoint, mntDetach)
if err != nil {
if i == len(mounts)-1 { // last mount
return fmt.Errorf("%w (possible cause: %s)", err, suberr)
}
// This is a submount, we can ignore the error for now,
// the final unmount will fail if this is a real problem.
// With that in mind, the _first_ failed unmount error
// might be the real error cause, so let's keep it.
if suberr == nil {
suberr = err
}
}
}
return nil
}

87
vendor/github.com/moby/sys/mount/mount_unix.go generated vendored Normal file
View File

@ -0,0 +1,87 @@
// +build !darwin,!windows
package mount
import (
"fmt"
"sort"
"github.com/moby/sys/mountinfo"
"golang.org/x/sys/unix"
)
// Mount will mount filesystem according to the specified configuration.
// Options must be specified like the mount or fstab unix commands:
// "opt1=val1,opt2=val2". See flags.go for supported option flags.
func Mount(device, target, mType, options string) error {
flag, data := parseOptions(options)
return mount(device, target, mType, uintptr(flag), data)
}
// Unmount lazily unmounts a filesystem on supported platforms, otherwise does
// a normal unmount. If target is not a mount point, no error is returned.
func Unmount(target string) error {
err := unix.Unmount(target, mntDetach)
if err == nil || err == unix.EINVAL {
// Ignore "not mounted" error here. Note the same error
// can be returned if flags are invalid, so this code
// assumes that the flags value is always correct.
return nil
}
return &mountError{
op: "umount",
target: target,
flags: uintptr(mntDetach),
err: err,
}
}
// RecursiveUnmount unmounts the target and all mounts underneath, starting
// with the deepest mount first. The argument does not have to be a mount
// point itself.
func RecursiveUnmount(target string) error {
// Fast path, works if target is a mount point that can be unmounted.
// On Linux, mntDetach flag ensures a recursive unmount. For other
// platforms, if there are submounts, we'll get EBUSY (and fall back
// to the slow path). NOTE we do not ignore EINVAL here as target might
// not be a mount point itself (but there can be mounts underneath).
if err := unix.Unmount(target, mntDetach); err == nil {
return nil
}
// Slow path: get all submounts, sort, unmount one by one.
mounts, err := mountinfo.GetMounts(mountinfo.PrefixFilter(target))
if err != nil {
return err
}
// Make the deepest mount be first
sort.Slice(mounts, func(i, j int) bool {
return len(mounts[i].Mountpoint) > len(mounts[j].Mountpoint)
})
var (
suberr error
lastMount = len(mounts) - 1
)
for i, m := range mounts {
err = Unmount(m.Mountpoint)
if err != nil {
if i == lastMount {
if suberr != nil {
return fmt.Errorf("%w (possible cause: %s)", err, suberr)
}
return err
}
// This is a submount, we can ignore the error for now,
// the final unmount will fail if this is a real problem.
// With that in mind, the _first_ failed unmount error
// might be the real error cause, so let's keep it.
if suberr == nil {
suberr = err
}
}
}
return nil
}

View File

@ -1,3 +1,5 @@
// +build freebsd,cgo openbsd,cgo
package mount package mount
/* /*

View File

@ -1,7 +1,7 @@
// +build !linux,!freebsd freebsd,!cgo // +build !linux,!freebsd,!openbsd,!windows freebsd,!cgo openbsd,!cgo
package mount package mount
func mount(device, target, mType string, flag uintptr, data string) error { func mount(device, target, mType string, flag uintptr, data string) error {
panic("Not implemented") panic("cgo required on freebsd and openbsd")
} }

View File

@ -1,22 +0,0 @@
// +build !windows
package mount
import "golang.org/x/sys/unix"
func unmount(target string, flags int) error {
err := unix.Unmount(target, flags)
if err == nil || err == unix.EINVAL {
// Ignore "not mounted" error here. Note the same error
// can be returned if flags are invalid, so this code
// assumes that the flags value is always correct.
return nil
}
return &mountError{
op: "umount",
target: target,
flags: uintptr(flags),
err: err,
}
}

View File

@ -1,7 +0,0 @@
// +build windows
package mount
func unmount(target string, flag int) error {
panic("Not implemented")
}

44
vendor/github.com/moby/sys/mountinfo/doc.go generated vendored Normal file
View File

@ -0,0 +1,44 @@
// Package mountinfo provides a set of functions to retrieve information about OS mounts.
//
// Currently it supports Linux. For historical reasons, there is also some support for FreeBSD and OpenBSD,
// and a shallow implementation for Windows, but in general this is Linux-only package, so
// the rest of the document only applies to Linux, unless explicitly specified otherwise.
//
// In Linux, information about mounts seen by the current process is available from
// /proc/self/mountinfo. Note that due to mount namespaces, different processes can
// see different mounts. A per-process mountinfo table is available from /proc/<PID>/mountinfo,
// where <PID> is a numerical process identifier.
//
// In general, /proc is not a very efficient interface, and mountinfo is not an exception.
// For example, there is no way to get information about a specific mount point (i.e. it
// is all-or-nothing). This package tries to hide the /proc ineffectiveness by using
// parse filters while reading mountinfo. A filter can skip some entries, or stop
// processing the rest of the file once the needed information is found.
//
// For mountinfo filters that accept path as an argument, the path must be absolute,
// having all symlinks resolved, and being cleaned (i.e. no extra slashes or dots).
// One way to achieve all of the above is to employ filepath.Abs followed by
// filepath.EvalSymlinks (the latter calls filepath.Clean on the result so
// there is no need to explicitly call filepath.Clean).
//
// NOTE that in many cases there is no need to consult mountinfo at all. Here are some
// of the cases where mountinfo should not be parsed:
//
// 1. Before performing a mount. Usually, this is not needed, but if required (say to
// prevent over-mounts), to check whether a directory is mounted, call os.Lstat
// on it and its parent directory, and compare their st.Sys().(*syscall.Stat_t).Dev
// fields -- if they differ, then the directory is the mount point. NOTE this does
// not work for bind mounts. Optionally, the filesystem type can also be checked
// by calling unix.Statfs and checking the Type field (i.e. filesystem type).
//
// 2. After performing a mount. If there is no error returned, the mount succeeded;
// checking the mount table for a new mount is redundant and expensive.
//
// 3. Before performing an unmount. It is more efficient to do an unmount and ignore
// a specific error (EINVAL) which tells the directory is not mounted.
//
// 4. After performing an unmount. If there is no error returned, the unmount succeeded.
//
// 5. To find the mount point root of a specific directory. You can perform os.Stat()
// on the directory and traverse up until the Dev field of a parent directory differs.
package mountinfo

View File

@ -1,3 +1,5 @@
module github.com/moby/sys/mountinfo module github.com/moby/sys/mountinfo
go 1.14 go 1.14
require golang.org/x/sys v0.0.0-20200909081042-eff7692f9009

58
vendor/github.com/moby/sys/mountinfo/mounted_linux.go generated vendored Normal file
View File

@ -0,0 +1,58 @@
package mountinfo
import (
"os"
"path/filepath"
"golang.org/x/sys/unix"
)
// mountedByOpenat2 is a method of detecting a mount that works for all kinds
// of mounts (incl. bind mounts), but requires a recent (v5.6+) linux kernel.
func mountedByOpenat2(path string) (bool, error) {
dir, last := filepath.Split(path)
dirfd, err := unix.Openat2(unix.AT_FDCWD, dir, &unix.OpenHow{
Flags: unix.O_PATH | unix.O_CLOEXEC,
})
if err != nil {
if err == unix.ENOENT { // not a mount
return false, nil
}
return false, &os.PathError{Op: "openat2", Path: dir, Err: err}
}
fd, err := unix.Openat2(dirfd, last, &unix.OpenHow{
Flags: unix.O_PATH | unix.O_CLOEXEC | unix.O_NOFOLLOW,
Resolve: unix.RESOLVE_NO_XDEV,
})
_ = unix.Close(dirfd)
switch err {
case nil: // definitely not a mount
_ = unix.Close(fd)
return false, nil
case unix.EXDEV: // definitely a mount
return true, nil
case unix.ENOENT: // not a mount
return false, nil
}
// not sure
return false, &os.PathError{Op: "openat2", Path: path, Err: err}
}
func mounted(path string) (bool, error) {
// Try a fast path, using openat2() with RESOLVE_NO_XDEV.
mounted, err := mountedByOpenat2(path)
if err == nil {
return mounted, nil
}
// Another fast path: compare st.st_dev fields.
mounted, err = mountedByStat(path)
// This does not work for bind mounts, so false negative
// is possible, therefore only trust if return is true.
if mounted && err == nil {
return mounted, nil
}
// Fallback to parsing mountinfo
return mountedByMountinfo(path)
}

66
vendor/github.com/moby/sys/mountinfo/mounted_unix.go generated vendored Normal file
View File

@ -0,0 +1,66 @@
// +build linux freebsd,cgo openbsd,cgo
package mountinfo
import (
"errors"
"fmt"
"os"
"path/filepath"
"golang.org/x/sys/unix"
)
func mountedByStat(path string) (bool, error) {
var st unix.Stat_t
if err := unix.Lstat(path, &st); err != nil {
if err == unix.ENOENT {
// Treat ENOENT as "not mounted".
return false, nil
}
return false, &os.PathError{Op: "stat", Path: path, Err: err}
}
dev := st.Dev
parent := filepath.Dir(path)
if err := unix.Lstat(parent, &st); err != nil {
return false, &os.PathError{Op: "stat", Path: parent, Err: err}
}
if dev != st.Dev {
// Device differs from that of parent,
// so definitely a mount point.
return true, nil
}
// NB: this does not detect bind mounts on Linux.
return false, nil
}
func normalizePath(path string) (realPath string, err error) {
if realPath, err = filepath.Abs(path); err != nil {
return "", fmt.Errorf("unable to get absolute path for %q: %w", path, err)
}
if realPath, err = filepath.EvalSymlinks(realPath); err != nil {
return "", fmt.Errorf("failed to canonicalise path for %q: %w", path, err)
}
if _, err := os.Stat(realPath); err != nil {
return "", fmt.Errorf("failed to stat target of %q: %w", path, err)
}
return realPath, nil
}
func mountedByMountinfo(path string) (bool, error) {
path, err := normalizePath(path)
if err != nil {
if errors.Is(err, unix.ENOENT) {
// treat ENOENT as "not mounted"
return false, nil
}
return false, err
}
entries, err := GetMounts(SingleEntryFilter(path))
if err != nil {
return false, err
}
return len(entries) > 0, nil
}

View File

@ -1,6 +1,8 @@
package mountinfo package mountinfo
import "io" import (
"os"
)
// GetMounts retrieves a list of mounts for the current running process, // GetMounts retrieves a list of mounts for the current running process,
// with an optional filter applied (use nil for no filter). // with an optional filter applied (use nil for no filter).
@ -8,23 +10,17 @@ func GetMounts(f FilterFunc) ([]*Info, error) {
return parseMountTable(f) return parseMountTable(f)
} }
// GetMountsFromReader retrieves a list of mounts from the // Mounted determines if a specified path is a mount point.
// reader provided, with an optional filter applied (use nil //
// for no filter). This can be useful in tests or benchmarks // The argument must be an absolute path, with all symlinks resolved, and clean.
// that provide a fake mountinfo data. // One way to ensure it is to process the path using filepath.Abs followed by
func GetMountsFromReader(reader io.Reader, f FilterFunc) ([]*Info, error) { // filepath.EvalSymlinks before calling this function.
return parseInfoFile(reader, f) func Mounted(path string) (bool, error) {
} // root is always mounted
if path == string(os.PathSeparator) {
// Mounted determines if a specified mountpoint has been mounted. return true, nil
// On Linux it looks at /proc/self/mountinfo.
func Mounted(mountpoint string) (bool, error) {
entries, err := GetMounts(SingleEntryFilter(mountpoint))
if err != nil {
return false, err
} }
return mounted(path)
return len(entries) > 0, nil
} }
// Info reveals information about a particular mounted filesystem. This // Info reveals information about a particular mounted filesystem. This
@ -50,18 +46,18 @@ type Info struct {
// Mountpoint indicates the mount point relative to the process's root. // Mountpoint indicates the mount point relative to the process's root.
Mountpoint string Mountpoint string
// Opts represents mount-specific options. // Options represents mount-specific options.
Opts string Options string
// Optional represents optional fields. // Optional represents optional fields.
Optional string Optional string
// Fstype indicates the type of filesystem, such as EXT3. // FSType indicates the type of filesystem, such as EXT3.
Fstype string FSType string
// Source indicates filesystem specific information or "none". // Source indicates filesystem specific information or "none".
Source string Source string
// VfsOpts represents per super block options. // VFSOptions represents per super block options.
VfsOpts string VFSOptions string
} }

View File

@ -1,3 +1,5 @@
// +build freebsd,cgo openbsd,cgo
package mountinfo package mountinfo
/* /*
@ -33,7 +35,7 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) {
var mountinfo Info var mountinfo Info
var skip, stop bool var skip, stop bool
mountinfo.Mountpoint = C.GoString(&entry.f_mntonname[0]) mountinfo.Mountpoint = C.GoString(&entry.f_mntonname[0])
mountinfo.Fstype = C.GoString(&entry.f_fstypename[0]) mountinfo.FSType = C.GoString(&entry.f_fstypename[0])
mountinfo.Source = C.GoString(&entry.f_mntfromname[0]) mountinfo.Source = C.GoString(&entry.f_mntfromname[0])
if filter != nil { if filter != nil {
@ -51,3 +53,15 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) {
} }
return out, nil return out, nil
} }
func mounted(path string) (bool, error) {
// Fast path: compare st.st_dev fields.
// This should always work for FreeBSD and OpenBSD.
mounted, err := mountedByStat(path)
if err == nil {
return mounted, nil
}
// Fallback to parsing mountinfo
return mountedByMountinfo(path)
}

View File

@ -6,16 +6,16 @@ import "strings"
// used to filter out mountinfo entries we're not interested in, // used to filter out mountinfo entries we're not interested in,
// and/or stop further processing if we found what we wanted. // and/or stop further processing if we found what we wanted.
// //
// It takes a pointer to the Info struct (not fully populated, // It takes a pointer to the Info struct (fully populated with all available
// currently only Mountpoint, Fstype, Source, and (on Linux) // fields on the GOOS platform), and returns two booleans:
// VfsOpts are filled in), and returns two booleans:
// //
// - skip: true if the entry should be skipped // skip: true if the entry should be skipped;
// - stop: true if parsing should be stopped after the entry //
// stop: true if parsing should be stopped after the entry.
type FilterFunc func(*Info) (skip, stop bool) type FilterFunc func(*Info) (skip, stop bool)
// PrefixFilter discards all entries whose mount points // PrefixFilter discards all entries whose mount points
// do not start with a specific prefix // do not start with a specific prefix.
func PrefixFilter(prefix string) FilterFunc { func PrefixFilter(prefix string) FilterFunc {
return func(m *Info) (bool, bool) { return func(m *Info) (bool, bool) {
skip := !strings.HasPrefix(m.Mountpoint, prefix) skip := !strings.HasPrefix(m.Mountpoint, prefix)
@ -23,7 +23,7 @@ func PrefixFilter(prefix string) FilterFunc {
} }
} }
// SingleEntryFilter looks for a specific entry // SingleEntryFilter looks for a specific entry.
func SingleEntryFilter(mp string) FilterFunc { func SingleEntryFilter(mp string) FilterFunc {
return func(m *Info) (bool, bool) { return func(m *Info) (bool, bool) {
if m.Mountpoint == mp { if m.Mountpoint == mp {
@ -36,8 +36,8 @@ func SingleEntryFilter(mp string) FilterFunc {
// ParentsFilter returns all entries whose mount points // ParentsFilter returns all entries whose mount points
// can be parents of a path specified, discarding others. // can be parents of a path specified, discarding others.
// //
// For example, given `/var/lib/docker/something`, entries // For example, given /var/lib/docker/something, entries
// like `/var/lib/docker`, `/var` and `/` are returned. // like /var/lib/docker, /var and / are returned.
func ParentsFilter(path string) FilterFunc { func ParentsFilter(path string) FilterFunc {
return func(m *Info) (bool, bool) { return func(m *Info) (bool, bool) {
skip := !strings.HasPrefix(path, m.Mountpoint) skip := !strings.HasPrefix(path, m.Mountpoint)
@ -45,12 +45,12 @@ func ParentsFilter(path string) FilterFunc {
} }
} }
// FstypeFilter returns all entries that match provided fstype(s). // FSTypeFilter returns all entries that match provided fstype(s).
func FstypeFilter(fstype ...string) FilterFunc { func FSTypeFilter(fstype ...string) FilterFunc {
return func(m *Info) (bool, bool) { return func(m *Info) (bool, bool) {
for _, t := range fstype { for _, t := range fstype {
if m.Fstype == t { if m.FSType == t {
return false, false // don't skeep, keep going return false, false // don't skip, keep going
} }
} }
return true, false // skip, keep going return true, false // skip, keep going

View File

@ -1,5 +1,3 @@
// +build go1.13
package mountinfo package mountinfo
import ( import (
@ -11,14 +9,18 @@ import (
"strings" "strings"
) )
func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) { // GetMountsFromReader retrieves a list of mounts from the
// reader provided, with an optional filter applied (use nil
// for no filter). This can be useful in tests or benchmarks
// that provide a fake mountinfo data.
//
// This function is Linux-specific.
func GetMountsFromReader(r io.Reader, filter FilterFunc) ([]*Info, error) {
s := bufio.NewScanner(r) s := bufio.NewScanner(r)
out := []*Info{} out := []*Info{}
var err error
for s.Scan() { for s.Scan() {
if err = s.Err(); err != nil { var err error
return nil, err
}
/* /*
See http://man7.org/linux/man-pages/man5/proc.5.html See http://man7.org/linux/man-pages/man5/proc.5.html
@ -70,26 +72,19 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) {
p := &Info{} p := &Info{}
// Fill in the fields that a filter might check p.Mountpoint, err = unescape(fields[4])
p.Mountpoint, err = strconv.Unquote(`"` + fields[4] + `"`)
if err != nil { if err != nil {
return nil, fmt.Errorf("Parsing '%s' failed: unable to unquote mount point field: %w", fields[4], err) return nil, fmt.Errorf("Parsing '%s' failed: mount point: %w", fields[4], err)
} }
p.Fstype = fields[sepIdx+1] p.FSType, err = unescape(fields[sepIdx+1])
p.Source = fields[sepIdx+2] if err != nil {
p.VfsOpts = fields[sepIdx+3] return nil, fmt.Errorf("Parsing '%s' failed: fstype: %w", fields[sepIdx+1], err)
// Run a filter soon so we can skip parsing/adding entries
// the caller is not interested in
var skip, stop bool
if filter != nil {
skip, stop = filter(p)
if skip {
continue
} }
p.Source, err = unescape(fields[sepIdx+2])
if err != nil {
return nil, fmt.Errorf("Parsing '%s' failed: source: %w", fields[sepIdx+2], err)
} }
p.VFSOptions = fields[sepIdx+3]
// Fill in the rest of the fields
// ignore any numbers parsing errors, as there should not be any // ignore any numbers parsing errors, as there should not be any
p.ID, _ = strconv.Atoi(fields[0]) p.ID, _ = strconv.Atoi(fields[0])
@ -101,12 +96,12 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) {
p.Major, _ = strconv.Atoi(mm[0]) p.Major, _ = strconv.Atoi(mm[0])
p.Minor, _ = strconv.Atoi(mm[1]) p.Minor, _ = strconv.Atoi(mm[1])
p.Root, err = strconv.Unquote(`"` + fields[3] + `"`) p.Root, err = unescape(fields[3])
if err != nil { if err != nil {
return nil, fmt.Errorf("Parsing '%s' failed: unable to unquote root field: %w", fields[3], err) return nil, fmt.Errorf("Parsing '%s' failed: root: %w", fields[3], err)
} }
p.Opts = fields[5] p.Options = fields[5]
// zero or more optional fields // zero or more optional fields
switch { switch {
@ -118,11 +113,23 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) {
p.Optional = strings.Join(fields[6:sepIdx-1], " ") p.Optional = strings.Join(fields[6:sepIdx-1], " ")
} }
// Run the filter after parsing all of the fields.
var skip, stop bool
if filter != nil {
skip, stop = filter(p)
if skip {
continue
}
}
out = append(out, p) out = append(out, p)
if stop { if stop {
break break
} }
} }
if err := s.Err(); err != nil {
return nil, err
}
return out, nil return out, nil
} }
@ -135,12 +142,17 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) {
} }
defer f.Close() defer f.Close()
return parseInfoFile(f, filter) return GetMountsFromReader(f, filter)
} }
// PidMountInfo collects the mounts for a specific process ID. If the process // PidMountInfo retrieves the list of mounts from a given process' mount
// ID is unknown, it is better to use `GetMounts` which will inspect // namespace. Unless there is a need to get mounts from a mount namespace
// "/proc/self/mountinfo" instead. // different from that of a calling process, use GetMounts.
//
// This function is Linux-specific.
//
// Deprecated: this will be removed before v1; use GetMountsFromReader with
// opened /proc/<pid>/mountinfo as an argument instead.
func PidMountInfo(pid int) ([]*Info, error) { func PidMountInfo(pid int) ([]*Info, error) {
f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid)) f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid))
if err != nil { if err != nil {
@ -148,5 +160,63 @@ func PidMountInfo(pid int) ([]*Info, error) {
} }
defer f.Close() defer f.Close()
return parseInfoFile(f, nil) return GetMountsFromReader(f, nil)
}
// A few specific characters in mountinfo path entries (root and mountpoint)
// are escaped using a backslash followed by a character's ascii code in octal.
//
// space -- as \040
// tab (aka \t) -- as \011
// newline (aka \n) -- as \012
// backslash (aka \\) -- as \134
//
// This function converts path from mountinfo back, i.e. it unescapes the above sequences.
func unescape(path string) (string, error) {
// try to avoid copying
if strings.IndexByte(path, '\\') == -1 {
return path, nil
}
// The following code is UTF-8 transparent as it only looks for some
// specific characters (backslash and 0..7) with values < utf8.RuneSelf,
// and everything else is passed through as is.
buf := make([]byte, len(path))
bufLen := 0
for i := 0; i < len(path); i++ {
if path[i] != '\\' {
buf[bufLen] = path[i]
bufLen++
continue
}
s := path[i:]
if len(s) < 4 {
// too short
return "", fmt.Errorf("bad escape sequence %q: too short", s)
}
c := s[1]
switch c {
case '0', '1', '2', '3', '4', '5', '6', '7':
v := c - '0'
for j := 2; j < 4; j++ { // one digit already; two more
if s[j] < '0' || s[j] > '7' {
return "", fmt.Errorf("bad escape sequence %q: not a digit", s[:3])
}
x := s[j] - '0'
v = (v << 3) | x
}
if v > 255 {
return "", fmt.Errorf("bad escape sequence %q: out of range" + s[:3])
}
buf[bufLen] = v
bufLen++
i += 3
continue
default:
return "", fmt.Errorf("bad escape sequence %q: not a digit" + s[:3])
}
}
return string(buf[:bufLen]), nil
} }

View File

@ -1,17 +1,18 @@
// +build !windows,!linux,!freebsd freebsd,!cgo // +build !windows,!linux,!freebsd,!openbsd freebsd,!cgo openbsd,!cgo
package mountinfo package mountinfo
import ( import (
"fmt" "fmt"
"io"
"runtime" "runtime"
) )
var errNotImplemented = fmt.Errorf("not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
func parseMountTable(_ FilterFunc) ([]*Info, error) { func parseMountTable(_ FilterFunc) ([]*Info, error) {
return nil, fmt.Errorf("mount.parseMountTable is not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) return nil, errNotImplemented
} }
func parseInfoFile(_ io.Reader, f FilterFunc) ([]*Info, error) { func mounted(path string) (bool, error) {
return parseMountTable(f) return false, errNotImplemented
} }

View File

@ -1,12 +1,10 @@
package mountinfo package mountinfo
import "io"
func parseMountTable(_ FilterFunc) ([]*Info, error) { func parseMountTable(_ FilterFunc) ([]*Info, error) {
// Do NOT return an error! // Do NOT return an error!
return nil, nil return nil, nil
} }
func parseInfoFile(_ io.Reader, f FilterFunc) ([]*Info, error) { func mounted(_ string) (bool, error) {
return parseMountTable(f) return false, nil
} }

4
vendor/github.com/moby/sys/symlink/doc.go generated vendored Normal file
View File

@ -0,0 +1,4 @@
// Package symlink implements EvalSymlinksInScope which is an extension of
// filepath.EvalSymlinks, as well as a Windows long-path aware version of
// filepath.EvalSymlinks from the Go standard library (https://golang.org/pkg/path/filepath).
package symlink

View File

@ -4,7 +4,7 @@
// This code is a modified version of path/filepath/symlink.go from the Go standard library. // This code is a modified version of path/filepath/symlink.go from the Go standard library.
package symlink // import "github.com/docker/docker/pkg/symlink" package symlink
import ( import (
"bytes" "bytes"

View File

@ -1,6 +1,6 @@
// +build !windows // +build !windows
package symlink // import "github.com/docker/docker/pkg/symlink" package symlink
import ( import (
"path/filepath" "path/filepath"

View File

@ -1,4 +1,4 @@
package symlink // import "github.com/docker/docker/pkg/symlink" package symlink
import ( import (
"bytes" "bytes"

5
vendor/github.com/moby/sys/symlink/go.mod generated vendored Normal file
View File

@ -0,0 +1,5 @@
module github.com/moby/sys/symlink
go 1.13
require golang.org/x/sys v0.0.0-20200922070232-aee5d888a860