mirror of
https://github.com/containers/podman.git
synced 2025-06-18 15:39:08 +08:00
Update vendor of storage,common
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
2
go.mod
2
go.mod
@ -17,7 +17,7 @@ require (
|
||||
github.com/containers/image/v5 v5.21.1-0.20220405081457-d1b64686e1d0
|
||||
github.com/containers/ocicrypt v1.1.3
|
||||
github.com/containers/psgo v1.7.2
|
||||
github.com/containers/storage v1.39.1-0.20220412073713-ea4008e14877
|
||||
github.com/containers/storage v1.39.1-0.20220414183333-eea4e0f5f1f9
|
||||
github.com/coreos/go-systemd/v22 v22.3.2
|
||||
github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3
|
||||
github.com/cyphar/filepath-securejoin v0.2.3
|
||||
|
10
go.sum
10
go.sum
@ -325,8 +325,9 @@ github.com/containerd/stargz-snapshotter/estargz v0.9.0/go.mod h1:aE5PCyhFMwR8sb
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.10.1/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.0/go.mod h1:/KsZXsJRllMbTKFfG0miFQWViQKdI9+9aSXs+HN0+ac=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.1/go.mod h1:6VoPcf4M1wvnogWxqc4TqBWWErCS+R+ucnPZId2VbpQ=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.3 h1:k2kN16Px6LYuv++qFqK+JTcYqc8bEVxzGpf8/gFBL5M=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.3/go.mod h1:7vRJIcImfY8bpifnMjt+HTJoQxASq7T28MYbP15/Nf0=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.4 h1:LjrYUZpyOhiSaU7hHrdR82/RBoxfGWSaC0VeSSMXqnk=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.4/go.mod h1:7vRJIcImfY8bpifnMjt+HTJoQxASq7T28MYbP15/Nf0=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
|
||||
@ -379,8 +380,8 @@ github.com/containers/storage v1.38.2/go.mod h1:INP0RPLHWBxx+pTsO5uiHlDUGHDFvWZP
|
||||
github.com/containers/storage v1.38.3-0.20220301151551-d06b0f81c0aa/go.mod h1:LkkL34WRi4dI4jt9Cp+ImdZi/P5i36glSHimT5CP5zM=
|
||||
github.com/containers/storage v1.39.0/go.mod h1:UAD0cKLouN4BOQRgZut/nMjrh/EnTCjSNPgp4ZuGWMs=
|
||||
github.com/containers/storage v1.39.1-0.20220330193934-f3200eb5a5d9/go.mod h1:IMa2AfBI+Fxxk2hQqLTGhpJX6z2pZS1/I785QJeUwUY=
|
||||
github.com/containers/storage v1.39.1-0.20220412073713-ea4008e14877 h1:V3aVdbQt9qU6tu4HHAJtro4H8+Hnv6X/hrUNba8dll0=
|
||||
github.com/containers/storage v1.39.1-0.20220412073713-ea4008e14877/go.mod h1:UuYvGSKIdmzkjHbT/PENtxLRVGQ974nyhMbYp0KP19w=
|
||||
github.com/containers/storage v1.39.1-0.20220414183333-eea4e0f5f1f9 h1:cB2AvqxpfyqyyffXtDN0txJhD0lIaZWktbSRI92WpN4=
|
||||
github.com/containers/storage v1.39.1-0.20220414183333-eea4e0f5f1f9/go.mod h1:hFiHLMgNU0r3MiUpE97hEBaEKCN8fEIuEEBXoFC9eN0=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
@ -1005,8 +1006,9 @@ github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7s
|
||||
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/sys/mountinfo v0.6.0 h1:gUDhXQx58YNrpHlK4nSL+7y2pxFZkUcXqzFDKWdC0Oo=
|
||||
github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/sys/mountinfo v0.6.1 h1:+H/KnGEAGRpTrEAqNVQ2AM3SiwMgJUt/TXj+Z8cmCIc=
|
||||
github.com/moby/sys/mountinfo v0.6.1/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg=
|
||||
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
|
||||
github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs=
|
||||
|
44
vendor/github.com/containerd/stargz-snapshotter/estargz/build.go
generated
vendored
44
vendor/github.com/containerd/stargz-snapshotter/estargz/build.go
generated
vendored
@ -26,10 +26,10 @@ import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
@ -48,6 +48,7 @@ type options struct {
|
||||
prioritizedFiles []string
|
||||
missedPrioritizedFiles *[]string
|
||||
compression Compression
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
type Option func(o *options) error
|
||||
@ -104,6 +105,14 @@ func WithCompression(compression Compression) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithContext specifies a context that can be used for clean canceleration.
|
||||
func WithContext(ctx context.Context) Option {
|
||||
return func(o *options) error {
|
||||
o.ctx = ctx
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Blob is an eStargz blob.
|
||||
type Blob struct {
|
||||
io.ReadCloser
|
||||
@ -139,12 +148,29 @@ func Build(tarBlob *io.SectionReader, opt ...Option) (_ *Blob, rErr error) {
|
||||
opts.compression = newGzipCompressionWithLevel(opts.compressionLevel)
|
||||
}
|
||||
layerFiles := newTempFiles()
|
||||
ctx := opts.ctx
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
done := make(chan struct{})
|
||||
defer close(done)
|
||||
go func() {
|
||||
select {
|
||||
case <-done:
|
||||
// nop
|
||||
case <-ctx.Done():
|
||||
layerFiles.CleanupAll()
|
||||
}
|
||||
}()
|
||||
defer func() {
|
||||
if rErr != nil {
|
||||
if err := layerFiles.CleanupAll(); err != nil {
|
||||
rErr = fmt.Errorf("failed to cleanup tmp files: %v: %w", err, rErr)
|
||||
}
|
||||
}
|
||||
if cErr := ctx.Err(); cErr != nil {
|
||||
rErr = fmt.Errorf("error from context %q: %w", cErr, rErr)
|
||||
}
|
||||
}()
|
||||
tarBlob, err := decompressBlob(tarBlob, layerFiles)
|
||||
if err != nil {
|
||||
@ -506,12 +532,13 @@ func newTempFiles() *tempFiles {
|
||||
}
|
||||
|
||||
type tempFiles struct {
|
||||
files []*os.File
|
||||
filesMu sync.Mutex
|
||||
files []*os.File
|
||||
filesMu sync.Mutex
|
||||
cleanupOnce sync.Once
|
||||
}
|
||||
|
||||
func (tf *tempFiles) TempFile(dir, pattern string) (*os.File, error) {
|
||||
f, err := ioutil.TempFile(dir, pattern)
|
||||
f, err := os.CreateTemp(dir, pattern)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -521,7 +548,14 @@ func (tf *tempFiles) TempFile(dir, pattern string) (*os.File, error) {
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (tf *tempFiles) CleanupAll() error {
|
||||
func (tf *tempFiles) CleanupAll() (err error) {
|
||||
tf.cleanupOnce.Do(func() {
|
||||
err = tf.cleanupAll()
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (tf *tempFiles) cleanupAll() error {
|
||||
tf.filesMu.Lock()
|
||||
defer tf.filesMu.Unlock()
|
||||
var allErr []error
|
||||
|
5
vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go
generated
vendored
5
vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go
generated
vendored
@ -31,7 +31,6 @@ import (
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"sort"
|
||||
@ -579,7 +578,7 @@ func (fr *fileReader) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
return 0, fmt.Errorf("fileReader.ReadAt.decompressor.Reader: %v", err)
|
||||
}
|
||||
defer dr.Close()
|
||||
if n, err := io.CopyN(ioutil.Discard, dr, off); n != off || err != nil {
|
||||
if n, err := io.CopyN(io.Discard, dr, off); n != off || err != nil {
|
||||
return 0, fmt.Errorf("discard of %d bytes = %v, %v", off, n, err)
|
||||
}
|
||||
return io.ReadFull(dr, p)
|
||||
@ -933,7 +932,7 @@ func (w *Writer) appendTar(r io.Reader, lossless bool) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
remainDest := ioutil.Discard
|
||||
remainDest := io.Discard
|
||||
if lossless {
|
||||
remainDest = dst // Preserve the remaining bytes in lossless mode
|
||||
}
|
||||
|
5
vendor/github.com/containerd/stargz-snapshotter/estargz/testutil.go
generated
vendored
5
vendor/github.com/containerd/stargz-snapshotter/estargz/testutil.go
generated
vendored
@ -31,7 +31,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
@ -287,11 +286,11 @@ func isSameTarGz(t *testing.T, controller TestingController, a, b []byte) bool {
|
||||
return false
|
||||
|
||||
}
|
||||
aFile, err := ioutil.ReadAll(aTar)
|
||||
aFile, err := io.ReadAll(aTar)
|
||||
if err != nil {
|
||||
t.Fatal("failed to read tar payload of A")
|
||||
}
|
||||
bFile, err := ioutil.ReadAll(bTar)
|
||||
bFile, err := io.ReadAll(bTar)
|
||||
if err != nil {
|
||||
t.Fatal("failed to read tar payload of B")
|
||||
}
|
||||
|
54
vendor/github.com/containers/storage/drivers/overlay/check.go
generated
vendored
54
vendor/github.com/containers/storage/drivers/overlay/check.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package overlay
|
||||
@ -11,6 +12,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/containers/storage/pkg/ioutils"
|
||||
"github.com/containers/storage/pkg/mount"
|
||||
"github.com/containers/storage/pkg/system"
|
||||
@ -218,3 +220,55 @@ func doesVolatile(d string) (bool, error) {
|
||||
}()
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// supportsIdmappedLowerLayers checks if the kernel supports mounting overlay on top of
|
||||
// a idmapped lower layer.
|
||||
func supportsIdmappedLowerLayers(home string) (bool, error) {
|
||||
layerDir, err := ioutil.TempDir(home, "compat")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer func() {
|
||||
_ = os.RemoveAll(layerDir)
|
||||
}()
|
||||
|
||||
mergedDir := filepath.Join(layerDir, "merged")
|
||||
lowerDir := filepath.Join(layerDir, "lower")
|
||||
lowerMappedDir := filepath.Join(layerDir, "lower-mapped")
|
||||
upperDir := filepath.Join(layerDir, "upper")
|
||||
workDir := filepath.Join(layerDir, "work")
|
||||
|
||||
_ = idtools.MkdirAs(mergedDir, 0700, 0, 0)
|
||||
_ = idtools.MkdirAs(lowerDir, 0700, 0, 0)
|
||||
_ = idtools.MkdirAs(lowerMappedDir, 0700, 0, 0)
|
||||
_ = idtools.MkdirAs(upperDir, 0700, 0, 0)
|
||||
_ = idtools.MkdirAs(workDir, 0700, 0, 0)
|
||||
|
||||
idmap := []idtools.IDMap{
|
||||
{
|
||||
ContainerID: 0,
|
||||
HostID: 0,
|
||||
Size: 1,
|
||||
},
|
||||
}
|
||||
pid, cleanupFunc, err := createUsernsProcess(idmap, idmap)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer cleanupFunc()
|
||||
|
||||
if err := createIDMappedMount(lowerDir, lowerMappedDir, int(pid)); err != nil {
|
||||
return false, errors.Wrapf(err, "create mapped mount")
|
||||
}
|
||||
defer unix.Unmount(lowerMappedDir, unix.MNT_DETACH)
|
||||
|
||||
opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lowerMappedDir, upperDir, workDir)
|
||||
flags := uintptr(0)
|
||||
if err := unix.Mount("overlay", mergedDir, "overlay", flags, opts); err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer func() {
|
||||
_ = unix.Unmount(mergedDir, unix.MNT_DETACH)
|
||||
}()
|
||||
return true, nil
|
||||
}
|
||||
|
160
vendor/github.com/containers/storage/drivers/overlay/idmapped_utils.go
generated
vendored
Normal file
160
vendor/github.com/containers/storage/drivers/overlay/idmapped_utils.go
generated
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package overlay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
type attr struct {
|
||||
attrSet uint64
|
||||
attrClr uint64
|
||||
propagation uint64
|
||||
userNs uint64
|
||||
}
|
||||
|
||||
const (
|
||||
// _MOUNT_ATTR_IDMAP - Idmap mount to @userns_fd in struct mount_attr
|
||||
_MOUNT_ATTR_IDMAP = 0x00100000 //nolint:golint
|
||||
|
||||
// _OPEN_TREE_CLONE - Clone the source path mount
|
||||
_OPEN_TREE_CLONE = 0x00000001 //nolint:golint
|
||||
|
||||
// _MOVE_MOUNT_F_EMPTY_PATH - Move the path referenced by the fd
|
||||
_MOVE_MOUNT_F_EMPTY_PATH = 0x00000004 //nolint:golint
|
||||
)
|
||||
|
||||
// openTree is a wrapper for the open_tree syscall
|
||||
func openTree(path string, flags int) (fd int, err error) {
|
||||
var _p0 *byte
|
||||
|
||||
if _p0, err = syscall.BytePtrFromString(path); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
r, _, e1 := syscall.Syscall6(uintptr(unix.SYS_OPEN_TREE), uintptr(0), uintptr(unsafe.Pointer(_p0)),
|
||||
uintptr(flags), 0, 0, 0)
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return int(r), nil
|
||||
}
|
||||
|
||||
// moveMount is a wrapper for the the move_mount syscall.
|
||||
func moveMount(fdTree int, target string) (err error) {
|
||||
var _p0, _p1 *byte
|
||||
|
||||
empty := ""
|
||||
|
||||
if _p0, err = syscall.BytePtrFromString(target); err != nil {
|
||||
return err
|
||||
}
|
||||
if _p1, err = syscall.BytePtrFromString(empty); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
flags := _MOVE_MOUNT_F_EMPTY_PATH
|
||||
|
||||
_, _, e1 := syscall.Syscall6(uintptr(unix.SYS_MOVE_MOUNT),
|
||||
uintptr(fdTree), uintptr(unsafe.Pointer(_p1)),
|
||||
0, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// mountSetAttr is a wrapper for the mount_setattr syscall
|
||||
func mountSetAttr(dfd int, path string, flags uint, attr *attr, size uint) (err error) {
|
||||
var _p0 *byte
|
||||
|
||||
if _p0, err = syscall.BytePtrFromString(path); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, _, e1 := syscall.Syscall6(uintptr(unix.SYS_MOUNT_SETATTR), uintptr(dfd), uintptr(unsafe.Pointer(_p0)),
|
||||
uintptr(flags), uintptr(unsafe.Pointer(attr)), uintptr(size), 0)
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// createIDMappedMount creates a IDMapped bind mount from SOURCE to TARGET using the user namespace
|
||||
// for the PID process.
|
||||
func createIDMappedMount(source, target string, pid int) error {
|
||||
path := fmt.Sprintf("/proc/%d/ns/user", pid)
|
||||
userNsFile, err := os.Open(path)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to get user ns file descriptor for %q", path)
|
||||
}
|
||||
|
||||
var attr attr
|
||||
attr.attrSet = _MOUNT_ATTR_IDMAP
|
||||
attr.attrClr = 0
|
||||
attr.propagation = 0
|
||||
attr.userNs = uint64(userNsFile.Fd())
|
||||
|
||||
defer userNsFile.Close()
|
||||
|
||||
targetDirFd, err := openTree(source, _OPEN_TREE_CLONE|unix.AT_RECURSIVE)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer unix.Close(targetDirFd)
|
||||
|
||||
if err := mountSetAttr(targetDirFd, "", unix.AT_EMPTY_PATH|unix.AT_RECURSIVE,
|
||||
&attr, uint(unsafe.Sizeof(attr))); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Mkdir(target, 0700); err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
return moveMount(targetDirFd, target)
|
||||
}
|
||||
|
||||
// createUsernsProcess forks the current process and creates a user namespace using the specified
|
||||
// mappings. It returns the pid of the new process.
|
||||
func createUsernsProcess(uidMaps []idtools.IDMap, gidMaps []idtools.IDMap) (int, func(), error) {
|
||||
pid, _, err := syscall.Syscall6(uintptr(unix.SYS_CLONE), unix.CLONE_NEWUSER|uintptr(unix.SIGCHLD), 0, 0, 0, 0, 0)
|
||||
if err != 0 {
|
||||
return -1, nil, err
|
||||
}
|
||||
if pid == 0 {
|
||||
_ = unix.Prctl(unix.PR_SET_PDEATHSIG, uintptr(unix.SIGKILL), 0, 0, 0)
|
||||
// just wait for the SIGKILL
|
||||
for {
|
||||
syscall.Syscall6(uintptr(unix.SYS_PAUSE), 0, 0, 0, 0, 0, 0)
|
||||
}
|
||||
}
|
||||
cleanupFunc := func() {
|
||||
unix.Kill(int(pid), unix.SIGKILL)
|
||||
_, _ = unix.Wait4(int(pid), nil, 0, nil)
|
||||
}
|
||||
writeMappings := func(fname string, idmap []idtools.IDMap) error {
|
||||
mappings := ""
|
||||
for _, m := range idmap {
|
||||
mappings = mappings + fmt.Sprintf("%d %d %d\n", m.ContainerID, m.HostID, m.Size)
|
||||
}
|
||||
return ioutil.WriteFile(fmt.Sprintf("/proc/%d/%s", pid, fname), []byte(mappings), 0600)
|
||||
}
|
||||
if err := writeMappings("uid_map", uidMaps); err != nil {
|
||||
cleanupFunc()
|
||||
return -1, nil, err
|
||||
}
|
||||
if err := writeMappings("gid_map", gidMaps); err != nil {
|
||||
cleanupFunc()
|
||||
return -1, nil, err
|
||||
}
|
||||
|
||||
return int(pid), cleanupFunc, nil
|
||||
}
|
141
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
141
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
@ -39,7 +39,6 @@ import (
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vbatts/tar-split/tar/storage"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@ -121,6 +120,8 @@ type Driver struct {
|
||||
supportsVolatile *bool
|
||||
usingMetacopy bool
|
||||
locker *locker.Locker
|
||||
|
||||
supportsIDMappedMounts *bool
|
||||
}
|
||||
|
||||
type additionalLayerStore struct {
|
||||
@ -205,6 +206,26 @@ func checkSupportVolatile(home, runhome string) (bool, error) {
|
||||
return usingVolatile, nil
|
||||
}
|
||||
|
||||
// checkAndRecordIDMappedSupport checks and stores if the kernel supports mounting overlay on top of a
|
||||
// idmapped lower layer.
|
||||
func checkAndRecordIDMappedSupport(home, runhome string) (bool, error) {
|
||||
feature := "idmapped-lower-dir"
|
||||
overlayCacheResult, overlayCacheText, err := cachedFeatureCheck(runhome, feature)
|
||||
if err == nil {
|
||||
if overlayCacheResult {
|
||||
logrus.Debugf("Cached value indicated that overlay is supported")
|
||||
return true, nil
|
||||
}
|
||||
logrus.Debugf("Cached value indicated that overlay is not supported")
|
||||
return false, errors.New(overlayCacheText)
|
||||
}
|
||||
supportsIDMappedMounts, err := supportsIdmappedLowerLayers(home)
|
||||
if err2 := cachedFeatureRecord(runhome, feature, supportsIDMappedMounts, ""); err2 != nil {
|
||||
return false, errors.Wrap(err2, "recording overlay idmapped mounts support status")
|
||||
}
|
||||
return supportsIDMappedMounts, err
|
||||
}
|
||||
|
||||
func checkAndRecordOverlaySupport(fsMagic graphdriver.FsMagic, home, runhome string) (bool, error) {
|
||||
var supportsDType bool
|
||||
|
||||
@ -1485,6 +1506,51 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
}
|
||||
}
|
||||
|
||||
if d.supportsIDmappedMounts() && len(options.UidMaps) > 0 && len(options.GidMaps) > 0 {
|
||||
var newAbsDir []string
|
||||
mappedRoot := filepath.Join(d.home, id, "mapped")
|
||||
if err := os.MkdirAll(mappedRoot, 0700); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
pid, cleanupFunc, err := createUsernsProcess(options.UidMaps, options.GidMaps)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer cleanupFunc()
|
||||
|
||||
idMappedMounts := make(map[string]string)
|
||||
|
||||
// rewrite the lower dirs to their idmapped mount.
|
||||
c := 0
|
||||
for _, absLower := range absLowers {
|
||||
mappedMountSrc := getMappedMountRoot(absLower)
|
||||
|
||||
root, found := idMappedMounts[mappedMountSrc]
|
||||
if !found {
|
||||
root = filepath.Join(mappedRoot, fmt.Sprintf("%d", c))
|
||||
c++
|
||||
if err := createIDMappedMount(mappedMountSrc, root, int(pid)); err != nil {
|
||||
return "", errors.Wrapf(err, "create mapped mount for %q on %q", mappedMountSrc, root)
|
||||
}
|
||||
idMappedMounts[mappedMountSrc] = root
|
||||
|
||||
// overlay takes a reference on the mount, so it is safe to unmount
|
||||
// the mapped idmounts as soon as the final overlay file system is mounted.
|
||||
defer unix.Unmount(root, unix.MNT_DETACH)
|
||||
}
|
||||
|
||||
// relative path to the layer through the id mapped mount
|
||||
rel, err := filepath.Rel(mappedMountSrc, absLower)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
newAbsDir = append(newAbsDir, filepath.Join(root, rel))
|
||||
}
|
||||
absLowers = newAbsDir
|
||||
}
|
||||
|
||||
var opts string
|
||||
if readWrite {
|
||||
opts = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", strings.Join(absLowers, ":"), diffDir, workdir)
|
||||
@ -1587,6 +1653,18 @@ func (d *Driver) Put(id string) error {
|
||||
|
||||
unmounted := false
|
||||
|
||||
mappedRoot := filepath.Join(d.home, id, "mapped")
|
||||
// It should not happen, but cleanup any mapped mount if it was leaked.
|
||||
if _, err := os.Stat(mappedRoot); err == nil {
|
||||
mounts, err := ioutil.ReadDir(mappedRoot)
|
||||
if err == nil {
|
||||
// Go through all of the mapped mounts.
|
||||
for _, m := range mounts {
|
||||
_ = unix.Unmount(filepath.Join(mappedRoot, m.Name()), unix.MNT_DETACH)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if d.options.mountProgram != "" {
|
||||
// Attempt to unmount the FUSE mount using either fusermount or fusermount3.
|
||||
// If they fail, fallback to unix.Unmount
|
||||
@ -1664,11 +1742,24 @@ func (d *Driver) getWhiteoutFormat() archive.WhiteoutFormat {
|
||||
return whiteoutFormat
|
||||
}
|
||||
|
||||
type fileGetNilCloser struct {
|
||||
storage.FileGetter
|
||||
type overlayFileGetter struct {
|
||||
diffDirs []string
|
||||
}
|
||||
|
||||
func (f fileGetNilCloser) Close() error {
|
||||
func (g *overlayFileGetter) Get(path string) (io.ReadCloser, error) {
|
||||
for _, d := range g.diffDirs {
|
||||
f, err := os.Open(filepath.Join(d, path))
|
||||
if err == nil {
|
||||
return f, nil
|
||||
}
|
||||
}
|
||||
if len(g.diffDirs) > 0 {
|
||||
return os.Open(filepath.Join(g.diffDirs[0], path))
|
||||
}
|
||||
return nil, fmt.Errorf("%s: %w", path, os.ErrNotExist)
|
||||
}
|
||||
|
||||
func (g *overlayFileGetter) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1677,13 +1768,18 @@ func (d *Driver) getStagingDir() string {
|
||||
}
|
||||
|
||||
// DiffGetter returns a FileGetCloser that can read files from the directory that
|
||||
// contains files for the layer differences. Used for direct access for tar-split.
|
||||
// contains files for the layer differences, either for this layer, or one of our
|
||||
// lowers if we're just a template directory. Used for direct access for tar-split.
|
||||
func (d *Driver) DiffGetter(id string) (graphdriver.FileGetCloser, error) {
|
||||
p, err := d.getDiffPath(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fileGetNilCloser{storage.NewPathFileGetter(p)}, nil
|
||||
paths, err := d.getLowerDiffPaths(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &overlayFileGetter{diffDirs: append([]string{p}, paths...)}, nil
|
||||
}
|
||||
|
||||
// CleanupStagingDirectory cleanups the staging directory.
|
||||
@ -1958,12 +2054,31 @@ func (d *Driver) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMapp
|
||||
return nil
|
||||
}
|
||||
|
||||
// supportsIDmappedMounts returns whether the kernel supports using idmapped mounts with
|
||||
// overlay lower layers.
|
||||
func (d *Driver) supportsIDmappedMounts() bool {
|
||||
if d.supportsIDMappedMounts != nil {
|
||||
return *d.supportsIDMappedMounts
|
||||
}
|
||||
|
||||
supportsIDMappedMounts, err := checkAndRecordIDMappedSupport(d.home, d.runhome)
|
||||
d.supportsIDMappedMounts = &supportsIDMappedMounts
|
||||
if err == nil {
|
||||
return supportsIDMappedMounts
|
||||
}
|
||||
logrus.Debugf("Check for idmapped mounts support %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in an userNS
|
||||
func (d *Driver) SupportsShifting() bool {
|
||||
if os.Getenv("_TEST_FORCE_SUPPORT_SHIFTING") == "yes-please" {
|
||||
return true
|
||||
}
|
||||
return d.options.mountProgram != ""
|
||||
if d.options.mountProgram != "" {
|
||||
return true
|
||||
}
|
||||
return d.supportsIDmappedMounts()
|
||||
}
|
||||
|
||||
// dumbJoin is more or less a dumber version of filepath.Join, but one which
|
||||
@ -2132,3 +2247,15 @@ func redirectDiffIfAdditionalLayer(diffPath string) (string, error) {
|
||||
}
|
||||
return diffPath, nil
|
||||
}
|
||||
|
||||
// getMappedMountRoot is a heuristic that calculates the parent directory where
|
||||
// the idmapped mount should be applied.
|
||||
// It is useful to minimize the number of idmapped mounts and at the same time use
|
||||
// a common path as long as possible to reduce the length of the mount data argument.
|
||||
func getMappedMountRoot(path string) string {
|
||||
dirName := filepath.Dir(path)
|
||||
if filepath.Base(dirName) == linkDir {
|
||||
return filepath.Dir(dirName)
|
||||
}
|
||||
return dirName
|
||||
}
|
||||
|
4
vendor/github.com/containers/storage/go.mod
generated
vendored
4
vendor/github.com/containers/storage/go.mod
generated
vendored
@ -6,7 +6,7 @@ require (
|
||||
github.com/BurntSushi/toml v1.1.0
|
||||
github.com/Microsoft/go-winio v0.5.2
|
||||
github.com/Microsoft/hcsshim v0.9.2
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.3
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.4
|
||||
github.com/cyphar/filepath-securejoin v0.2.3
|
||||
github.com/docker/go-units v0.4.0
|
||||
github.com/google/go-intervals v0.0.2
|
||||
@ -16,7 +16,7 @@ require (
|
||||
github.com/klauspost/pgzip v1.2.5
|
||||
github.com/mattn/go-shellwords v1.0.12
|
||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
|
||||
github.com/moby/sys/mountinfo v0.6.0
|
||||
github.com/moby/sys/mountinfo v0.6.1
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/runc v1.1.1
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
|
||||
|
8
vendor/github.com/containers/storage/go.sum
generated
vendored
8
vendor/github.com/containers/storage/go.sum
generated
vendored
@ -176,8 +176,8 @@ github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFY
|
||||
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.3 h1:k2kN16Px6LYuv++qFqK+JTcYqc8bEVxzGpf8/gFBL5M=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.3/go.mod h1:7vRJIcImfY8bpifnMjt+HTJoQxASq7T28MYbP15/Nf0=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.4 h1:LjrYUZpyOhiSaU7hHrdR82/RBoxfGWSaC0VeSSMXqnk=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.4/go.mod h1:7vRJIcImfY8bpifnMjt+HTJoQxASq7T28MYbP15/Nf0=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
|
||||
@ -467,8 +467,8 @@ github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQ
|
||||
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/sys/mountinfo v0.6.0 h1:gUDhXQx58YNrpHlK4nSL+7y2pxFZkUcXqzFDKWdC0Oo=
|
||||
github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/sys/mountinfo v0.6.1 h1:+H/KnGEAGRpTrEAqNVQ2AM3SiwMgJUt/TXj+Z8cmCIc=
|
||||
github.com/moby/sys/mountinfo v0.6.1/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
|
||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
65
vendor/github.com/containers/storage/layers.go
generated
vendored
65
vendor/github.com/containers/storage/layers.go
generated
vendored
@ -725,12 +725,32 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
|
||||
parent = parentLayer.ID
|
||||
}
|
||||
var parentMappings, templateIDMappings, oldMappings *idtools.IDMappings
|
||||
var (
|
||||
templateMetadata string
|
||||
templateCompressedDigest digest.Digest
|
||||
templateCompressedSize int64
|
||||
templateUncompressedDigest digest.Digest
|
||||
templateUncompressedSize int64
|
||||
templateCompressionType archive.Compression
|
||||
templateUIDs, templateGIDs []uint32
|
||||
templateTSdata []byte
|
||||
)
|
||||
if moreOptions.TemplateLayer != "" {
|
||||
var tserr error
|
||||
templateLayer, ok := r.lookup(moreOptions.TemplateLayer)
|
||||
if !ok {
|
||||
return nil, -1, ErrLayerUnknown
|
||||
}
|
||||
templateMetadata = templateLayer.Metadata
|
||||
templateIDMappings = idtools.NewIDMappingsFromMaps(templateLayer.UIDMap, templateLayer.GIDMap)
|
||||
templateCompressedDigest, templateCompressedSize = templateLayer.CompressedDigest, templateLayer.CompressedSize
|
||||
templateUncompressedDigest, templateUncompressedSize = templateLayer.UncompressedDigest, templateLayer.UncompressedSize
|
||||
templateCompressionType = templateLayer.CompressionType
|
||||
templateUIDs, templateGIDs = append([]uint32{}, templateLayer.UIDs...), append([]uint32{}, templateLayer.GIDs...)
|
||||
templateTSdata, tserr = ioutil.ReadFile(r.tspath(templateLayer.ID))
|
||||
if tserr != nil && !os.IsNotExist(tserr) {
|
||||
return nil, -1, tserr
|
||||
}
|
||||
} else {
|
||||
templateIDMappings = &idtools.IDMappings{}
|
||||
}
|
||||
@ -775,17 +795,43 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
|
||||
return nil, -1, err
|
||||
}
|
||||
}
|
||||
if len(templateTSdata) > 0 {
|
||||
if err := os.MkdirAll(filepath.Dir(r.tspath(id)), 0o700); err != nil {
|
||||
// We don't have a record of this layer, but at least
|
||||
// try to clean it up underneath us.
|
||||
if err2 := r.driver.Remove(id); err2 != nil {
|
||||
logrus.Errorf("While recovering from a failure creating in UpdateLayerIDMap, error deleting layer %#v: %v", id, err2)
|
||||
}
|
||||
return nil, -1, err
|
||||
}
|
||||
if err = ioutils.AtomicWriteFile(r.tspath(id), templateTSdata, 0o600); err != nil {
|
||||
// We don't have a record of this layer, but at least
|
||||
// try to clean it up underneath us.
|
||||
if err2 := r.driver.Remove(id); err2 != nil {
|
||||
logrus.Errorf("While recovering from a failure creating in UpdateLayerIDMap, error deleting layer %#v: %v", id, err2)
|
||||
}
|
||||
return nil, -1, err
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
layer = &Layer{
|
||||
ID: id,
|
||||
Parent: parent,
|
||||
Names: names,
|
||||
MountLabel: mountLabel,
|
||||
Created: time.Now().UTC(),
|
||||
Flags: make(map[string]interface{}),
|
||||
UIDMap: copyIDMap(moreOptions.UIDMap),
|
||||
GIDMap: copyIDMap(moreOptions.GIDMap),
|
||||
BigDataNames: []string{},
|
||||
ID: id,
|
||||
Parent: parent,
|
||||
Names: names,
|
||||
MountLabel: mountLabel,
|
||||
Metadata: templateMetadata,
|
||||
Created: time.Now().UTC(),
|
||||
CompressedDigest: templateCompressedDigest,
|
||||
CompressedSize: templateCompressedSize,
|
||||
UncompressedDigest: templateUncompressedDigest,
|
||||
UncompressedSize: templateUncompressedSize,
|
||||
CompressionType: templateCompressionType,
|
||||
UIDs: templateUIDs,
|
||||
GIDs: templateGIDs,
|
||||
Flags: make(map[string]interface{}),
|
||||
UIDMap: copyIDMap(moreOptions.UIDMap),
|
||||
GIDMap: copyIDMap(moreOptions.GIDMap),
|
||||
BigDataNames: []string{},
|
||||
}
|
||||
r.layers = append(r.layers, layer)
|
||||
r.idindex.Add(id)
|
||||
@ -872,7 +918,6 @@ func (r *layerStore) Mounted(id string) (int, error) {
|
||||
}
|
||||
|
||||
func (r *layerStore) Mount(id string, options drivers.MountOpts) (string, error) {
|
||||
|
||||
// check whether options include ro option
|
||||
hasReadOnlyOpt := func(opts []string) bool {
|
||||
for _, item := range opts {
|
||||
|
10
vendor/github.com/containers/storage/store.go
generated
vendored
10
vendor/github.com/containers/storage/store.go
generated
vendored
@ -2452,6 +2452,10 @@ func (s *store) DeleteImage(id string, commit bool) (layers []string, err error)
|
||||
}
|
||||
layer := image.TopLayer
|
||||
layersToRemoveMap := make(map[string]struct{})
|
||||
layersToRemove = append(layersToRemove, image.MappedTopLayers...)
|
||||
for _, mappedTopLayer := range image.MappedTopLayers {
|
||||
layersToRemoveMap[mappedTopLayer] = struct{}{}
|
||||
}
|
||||
for layer != "" {
|
||||
if rcstore.Exists(layer) {
|
||||
break
|
||||
@ -2483,12 +2487,6 @@ func (s *store) DeleteImage(id string, commit bool) (layers []string, err error)
|
||||
if hasChildrenNotBeingRemoved() {
|
||||
break
|
||||
}
|
||||
if layer == image.TopLayer {
|
||||
layersToRemove = append(layersToRemove, image.MappedTopLayers...)
|
||||
for _, mappedTopLayer := range image.MappedTopLayers {
|
||||
layersToRemoveMap[mappedTopLayer] = struct{}{}
|
||||
}
|
||||
}
|
||||
layersToRemove = append(layersToRemove, layer)
|
||||
layersToRemoveMap[layer] = struct{}{}
|
||||
layer = parent
|
||||
|
8
vendor/github.com/containers/storage/utils.go
generated
vendored
8
vendor/github.com/containers/storage/utils.go
generated
vendored
@ -42,13 +42,14 @@ func validateMountOptions(mountOptions []string) error {
|
||||
}
|
||||
|
||||
func applyNameOperation(oldNames []string, opParameters []string, op updateNameOperation) ([]string, error) {
|
||||
result := make([]string, 0)
|
||||
var result []string
|
||||
switch op {
|
||||
case setNames:
|
||||
// ignore all old names and just return new names
|
||||
return dedupeNames(opParameters), nil
|
||||
result = opParameters
|
||||
case removeNames:
|
||||
// remove given names from old names
|
||||
result = make([]string, 0, len(oldNames))
|
||||
for _, name := range oldNames {
|
||||
// only keep names in final result which do not intersect with input names
|
||||
// basically `result = oldNames - opParameters`
|
||||
@ -62,11 +63,10 @@ func applyNameOperation(oldNames []string, opParameters []string, op updateNameO
|
||||
result = append(result, name)
|
||||
}
|
||||
}
|
||||
return dedupeNames(result), nil
|
||||
case addNames:
|
||||
result = make([]string, 0, len(opParameters)+len(oldNames))
|
||||
result = append(result, opParameters...)
|
||||
result = append(result, oldNames...)
|
||||
return dedupeNames(result), nil
|
||||
default:
|
||||
return result, errInvalidUpdateNameOperation
|
||||
}
|
||||
|
7
vendor/github.com/moby/sys/mountinfo/mounted_unix.go
generated
vendored
7
vendor/github.com/moby/sys/mountinfo/mounted_unix.go
generated
vendored
@ -4,7 +4,6 @@
|
||||
package mountinfo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
@ -33,13 +32,13 @@ func mountedByStat(path string) (bool, error) {
|
||||
|
||||
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)
|
||||
return "", err
|
||||
}
|
||||
if realPath, err = filepath.EvalSymlinks(realPath); err != nil {
|
||||
return "", fmt.Errorf("failed to canonicalise path for %q: %w", path, err)
|
||||
return "", err
|
||||
}
|
||||
if _, err := os.Stat(realPath); err != nil {
|
||||
return "", fmt.Errorf("failed to stat target of %q: %w", path, err)
|
||||
return "", err
|
||||
}
|
||||
return realPath, nil
|
||||
}
|
||||
|
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
@ -69,7 +69,7 @@ github.com/containerd/containerd/log
|
||||
github.com/containerd/containerd/pkg/userns
|
||||
github.com/containerd/containerd/platforms
|
||||
github.com/containerd/containerd/sys
|
||||
# github.com/containerd/stargz-snapshotter/estargz v0.11.3
|
||||
# github.com/containerd/stargz-snapshotter/estargz v0.11.4
|
||||
github.com/containerd/stargz-snapshotter/estargz
|
||||
github.com/containerd/stargz-snapshotter/estargz/errorutil
|
||||
# github.com/containernetworking/cni v1.0.1
|
||||
@ -233,7 +233,7 @@ github.com/containers/psgo/internal/dev
|
||||
github.com/containers/psgo/internal/host
|
||||
github.com/containers/psgo/internal/proc
|
||||
github.com/containers/psgo/internal/process
|
||||
# github.com/containers/storage v1.39.1-0.20220412073713-ea4008e14877
|
||||
# github.com/containers/storage v1.39.1-0.20220414183333-eea4e0f5f1f9
|
||||
## explicit
|
||||
github.com/containers/storage
|
||||
github.com/containers/storage/drivers
|
||||
@ -479,7 +479,7 @@ github.com/mistifyio/go-zfs
|
||||
github.com/mitchellh/mapstructure
|
||||
# github.com/moby/sys/mount v0.2.0
|
||||
github.com/moby/sys/mount
|
||||
# github.com/moby/sys/mountinfo v0.6.0
|
||||
# github.com/moby/sys/mountinfo v0.6.1
|
||||
github.com/moby/sys/mountinfo
|
||||
# github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6
|
||||
## explicit
|
||||
|
Reference in New Issue
Block a user