Update continuity vendor
Pulls in copy and fstest changes Signed-off-by: Derek McGowan <derek@mcgstyle.net>
This commit is contained in:
		| @@ -50,25 +50,25 @@ func testLookup(t *testing.T, fsType string) { | |||||||
| 	} | 	} | ||||||
| 	defer os.RemoveAll(mnt) | 	defer os.RemoveAll(mnt) | ||||||
|  |  | ||||||
| 	deviceName, cleanupDevice, err := loopback.New(100 << 20) // 100 MB | 	loop, err := loopback.New(100 << 20) // 100 MB | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	if out, err := exec.Command("mkfs", "-t", fsType, deviceName).CombinedOutput(); err != nil { | 	if out, err := exec.Command("mkfs", "-t", fsType, loop.Device).CombinedOutput(); err != nil { | ||||||
| 		// not fatal | 		// not fatal | ||||||
| 		cleanupDevice() | 		loop.Close() | ||||||
| 		t.Skipf("could not mkfs (%s) %s: %v (out: %q)", fsType, deviceName, err, string(out)) | 		t.Skipf("could not mkfs (%s) %s: %v (out: %q)", fsType, loop.Device, err, string(out)) | ||||||
| 	} | 	} | ||||||
| 	if out, err := exec.Command("mount", deviceName, mnt).CombinedOutput(); err != nil { | 	if out, err := exec.Command("mount", loop.Device, mnt).CombinedOutput(); err != nil { | ||||||
| 		// not fatal | 		// not fatal | ||||||
| 		cleanupDevice() | 		loop.Close() | ||||||
| 		t.Skipf("could not mount %s: %v (out: %q)", deviceName, err, string(out)) | 		t.Skipf("could not mount %s: %v (out: %q)", loop.Device, err, string(out)) | ||||||
| 	} | 	} | ||||||
| 	defer func() { | 	defer func() { | ||||||
| 		testutil.Unmount(t, mnt) | 		testutil.Unmount(t, mnt) | ||||||
| 		cleanupDevice() | 		loop.Close() | ||||||
| 	}() | 	}() | ||||||
| 	assert.Check(t, strings.HasPrefix(deviceName, "/dev/loop")) | 	assert.Check(t, strings.HasPrefix(loop.Device, "/dev/loop")) | ||||||
| 	checkLookup(t, fsType, mnt, mnt) | 	checkLookup(t, fsType, mnt, mnt) | ||||||
|  |  | ||||||
| 	newMnt, err := ioutil.TempDir("", "containerd-mountinfo-test-newMnt") | 	newMnt, err := ioutil.TempDir("", "containerd-mountinfo-test-newMnt") | ||||||
|   | |||||||
| @@ -52,24 +52,24 @@ func boltSnapshotter(t *testing.T) func(context.Context, string) (snapshots.Snap | |||||||
| 		if os.Getpagesize() > 4096 { | 		if os.Getpagesize() > 4096 { | ||||||
| 			loopbackSize = int64(650 << 20) // 650 MB | 			loopbackSize = int64(650 << 20) // 650 MB | ||||||
| 		} | 		} | ||||||
| 		deviceName, cleanupDevice, err := loopback.New(loopbackSize) | 		loop, err := loopback.New(loopbackSize) | ||||||
|  |  | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, nil, err | 			return nil, nil, err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if out, err := exec.Command(mkbtrfs, deviceName).CombinedOutput(); err != nil { | 		if out, err := exec.Command(mkbtrfs, loop.Device).CombinedOutput(); err != nil { | ||||||
| 			cleanupDevice() | 			loop.Close() | ||||||
| 			return nil, nil, errors.Wrapf(err, "failed to make btrfs filesystem (out: %q)", out) | 			return nil, nil, errors.Wrapf(err, "failed to make btrfs filesystem (out: %q)", out) | ||||||
| 		} | 		} | ||||||
| 		if out, err := exec.Command("mount", deviceName, root).CombinedOutput(); err != nil { | 		if out, err := exec.Command("mount", loop.Device, root).CombinedOutput(); err != nil { | ||||||
| 			cleanupDevice() | 			loop.Close() | ||||||
| 			return nil, nil, errors.Wrapf(err, "failed to mount device %s (out: %q)", deviceName, out) | 			return nil, nil, errors.Wrapf(err, "failed to mount device %s (out: %q)", loop.Device, out) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		snapshotter, err := NewSnapshotter(root) | 		snapshotter, err := NewSnapshotter(root) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			cleanupDevice() | 			loop.Close() | ||||||
| 			return nil, nil, errors.Wrap(err, "failed to create new snapshotter") | 			return nil, nil, errors.Wrap(err, "failed to create new snapshotter") | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -78,7 +78,7 @@ func boltSnapshotter(t *testing.T) func(context.Context, string) (snapshots.Snap | |||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
| 			err := mount.UnmountAll(root, unix.MNT_DETACH) | 			err := mount.UnmountAll(root, unix.MNT_DETACH) | ||||||
| 			if cerr := cleanupDevice(); cerr != nil { | 			if cerr := loop.Close(); cerr != nil { | ||||||
| 				err = errors.Wrap(cerr, "device cleanup failed") | 				err = errors.Wrap(cerr, "device cleanup failed") | ||||||
| 			} | 			} | ||||||
| 			return err | 			return err | ||||||
|   | |||||||
| @@ -36,23 +36,23 @@ func testOverlaySupported(t testing.TB, expected bool, mkfs ...string) { | |||||||
| 	} | 	} | ||||||
| 	defer os.RemoveAll(mnt) | 	defer os.RemoveAll(mnt) | ||||||
|  |  | ||||||
| 	deviceName, cleanupDevice, err := loopback.New(100 << 20) // 100 MB | 	loop, err := loopback.New(100 << 20) // 100 MB | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	if out, err := exec.Command(mkfs[0], append(mkfs[1:], deviceName)...).CombinedOutput(); err != nil { | 	if out, err := exec.Command(mkfs[0], append(mkfs[1:], loop.Device)...).CombinedOutput(); err != nil { | ||||||
| 		// not fatal | 		// not fatal | ||||||
| 		cleanupDevice() | 		loop.Close() | ||||||
| 		t.Skipf("could not mkfs (%v) %s: %v (out: %q)", mkfs, deviceName, err, string(out)) | 		t.Skipf("could not mkfs (%v) %s: %v (out: %q)", mkfs, loop.Device, err, string(out)) | ||||||
| 	} | 	} | ||||||
| 	if out, err := exec.Command("mount", deviceName, mnt).CombinedOutput(); err != nil { | 	if out, err := exec.Command("mount", loop.Device, mnt).CombinedOutput(); err != nil { | ||||||
| 		// not fatal | 		// not fatal | ||||||
| 		cleanupDevice() | 		loop.Close() | ||||||
| 		t.Skipf("could not mount %s: %v (out: %q)", deviceName, err, string(out)) | 		t.Skipf("could not mount %s: %v (out: %q)", loop.Device, err, string(out)) | ||||||
| 	} | 	} | ||||||
| 	defer func() { | 	defer func() { | ||||||
| 		testutil.Unmount(t, mnt) | 		testutil.Unmount(t, mnt) | ||||||
| 		cleanupDevice() | 		loop.Close() | ||||||
| 	}() | 	}() | ||||||
| 	workload := func() { | 	workload := func() { | ||||||
| 		err = Supported(mnt) | 		err = Supported(mnt) | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ github.com/containerd/cgroups c4b9ac5c7601384c965b9646fc515884e091ebb9 | |||||||
| github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40 | github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40 | ||||||
| github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c | github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c | ||||||
| github.com/containerd/btrfs af5082808c833de0e79c1e72eea9fea239364877 | github.com/containerd/btrfs af5082808c833de0e79c1e72eea9fea239364877 | ||||||
| github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4 | github.com/containerd/continuity f2a389ac0a02ce21c09edd7344677a601970f41c | ||||||
| github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6 | github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6 | ||||||
| github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098 | github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098 | ||||||
| github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 | github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								vendor/github.com/containerd/continuity/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/containerd/continuity/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,6 +1,7 @@ | |||||||
|  |  | ||||||
|                                  Apache License |                                  Apache License | ||||||
|                            Version 2.0, January 2004 |                            Version 2.0, January 2004 | ||||||
|                         http://www.apache.org/licenses/ |                         https://www.apache.org/licenses/ | ||||||
|  |  | ||||||
|    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||||||
|  |  | ||||||
| @@ -175,28 +176,16 @@ | |||||||
|  |  | ||||||
|    END OF TERMS AND CONDITIONS |    END OF TERMS AND CONDITIONS | ||||||
|  |  | ||||||
|    APPENDIX: How to apply the Apache License to your work. |    Copyright The containerd Authors | ||||||
|  |  | ||||||
|       To apply the Apache License to your work, attach the following |  | ||||||
|       boilerplate notice, with the fields enclosed by brackets "{}" |  | ||||||
|       replaced with your own identifying information. (Don't include |  | ||||||
|       the brackets!)  The text should be enclosed in the appropriate |  | ||||||
|       comment syntax for the file format. We also recommend that a |  | ||||||
|       file or class name and description of purpose be included on the |  | ||||||
|       same "printed page" as the copyright notice for easier |  | ||||||
|       identification within third-party archives. |  | ||||||
|  |  | ||||||
|    Copyright {yyyy} {name of copyright owner} |  | ||||||
|  |  | ||||||
|    Licensed under the Apache License, Version 2.0 (the "License"); |    Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|    you may not use this file except in compliance with the License. |    you may not use this file except in compliance with the License. | ||||||
|    You may obtain a copy of the License at |    You may obtain a copy of the License at | ||||||
|  |  | ||||||
|        http://www.apache.org/licenses/LICENSE-2.0 |        https://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|    Unless required by applicable law or agreed to in writing, software |    Unless required by applicable law or agreed to in writing, software | ||||||
|    distributed under the License is distributed on an "AS IS" BASIS, |    distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|    See the License for the specific language governing permissions and |    See the License for the specific language governing permissions and | ||||||
|    limitations under the License. |    limitations under the License. | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								vendor/github.com/containerd/continuity/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/containerd/continuity/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -72,3 +72,13 @@ If you change the proto file you will need to rebuild the generated Go with `go | |||||||
| ```console | ```console | ||||||
| $ go generate ./proto | $ go generate ./proto | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | ## Project details | ||||||
|  |  | ||||||
|  | continuity is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). | ||||||
|  | As a containerd sub-project, you will find the: | ||||||
|  |  * [Project governance](https://github.com/containerd/project/blob/master/GOVERNANCE.md), | ||||||
|  |  * [Maintainers](https://github.com/containerd/project/blob/master/MAINTAINERS), | ||||||
|  |  * and [Contributing guidelines](https://github.com/containerd/project/blob/master/CONTRIBUTING.md) | ||||||
|  |  | ||||||
|  | information in our [`containerd/project`](https://github.com/containerd/project) repository. | ||||||
|   | |||||||
							
								
								
									
										51
									
								
								vendor/github.com/containerd/continuity/fs/copy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										51
									
								
								vendor/github.com/containerd/continuity/fs/copy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -32,14 +32,49 @@ var bufferPool = &sync.Pool{ | |||||||
| 	}, | 	}, | ||||||
| } | } | ||||||
|  |  | ||||||
| // CopyDir copies the directory from src to dst. | // XAttrErrorHandlers transform a non-nil xattr error. | ||||||
| // Most efficient copy of files is attempted. | // Return nil to ignore an error. | ||||||
| func CopyDir(dst, src string) error { | // xattrKey can be empty for listxattr operation. | ||||||
| 	inodes := map[uint64]string{} | type XAttrErrorHandler func(dst, src, xattrKey string, err error) error | ||||||
| 	return copyDirectory(dst, src, inodes) |  | ||||||
|  | type copyDirOpts struct { | ||||||
|  | 	xeh XAttrErrorHandler | ||||||
| } | } | ||||||
|  |  | ||||||
| func copyDirectory(dst, src string, inodes map[uint64]string) error { | type CopyDirOpt func(*copyDirOpts) error | ||||||
|  |  | ||||||
|  | // WithXAttrErrorHandler allows specifying XAttrErrorHandler | ||||||
|  | // If nil XAttrErrorHandler is specified (default), CopyDir stops | ||||||
|  | // on a non-nil xattr error. | ||||||
|  | func WithXAttrErrorHandler(xeh XAttrErrorHandler) CopyDirOpt { | ||||||
|  | 	return func(o *copyDirOpts) error { | ||||||
|  | 		o.xeh = xeh | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // WithAllowXAttrErrors allows ignoring xattr errors. | ||||||
|  | func WithAllowXAttrErrors() CopyDirOpt { | ||||||
|  | 	xeh := func(dst, src, xattrKey string, err error) error { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return WithXAttrErrorHandler(xeh) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // CopyDir copies the directory from src to dst. | ||||||
|  | // Most efficient copy of files is attempted. | ||||||
|  | func CopyDir(dst, src string, opts ...CopyDirOpt) error { | ||||||
|  | 	var o copyDirOpts | ||||||
|  | 	for _, opt := range opts { | ||||||
|  | 		if err := opt(&o); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	inodes := map[uint64]string{} | ||||||
|  | 	return copyDirectory(dst, src, inodes, &o) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) error { | ||||||
| 	stat, err := os.Stat(src) | 	stat, err := os.Stat(src) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return errors.Wrapf(err, "failed to stat %s", src) | 		return errors.Wrapf(err, "failed to stat %s", src) | ||||||
| @@ -75,7 +110,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string) error { | |||||||
|  |  | ||||||
| 		switch { | 		switch { | ||||||
| 		case fi.IsDir(): | 		case fi.IsDir(): | ||||||
| 			if err := copyDirectory(target, source, inodes); err != nil { | 			if err := copyDirectory(target, source, inodes, o); err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
| 			continue | 			continue | ||||||
| @@ -111,7 +146,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string) error { | |||||||
| 			return errors.Wrap(err, "failed to copy file info") | 			return errors.Wrap(err, "failed to copy file info") | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if err := copyXAttrs(target, source); err != nil { | 		if err := copyXAttrs(target, source, o.xeh); err != nil { | ||||||
| 			return errors.Wrap(err, "failed to copy xattrs") | 			return errors.Wrap(err, "failed to copy xattrs") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
							
								
								
									
										37
									
								
								vendor/github.com/containerd/continuity/fs/copy_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/containerd/continuity/fs/copy_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -59,6 +59,8 @@ func copyFileInfo(fi os.FileInfo, name string) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | const maxSSizeT = int64(^uint(0) >> 1) | ||||||
|  |  | ||||||
| func copyFileContent(dst, src *os.File) error { | func copyFileContent(dst, src *os.File) error { | ||||||
| 	st, err := src.Stat() | 	st, err := src.Stat() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -71,7 +73,16 @@ func copyFileContent(dst, src *os.File) error { | |||||||
| 	dstFd := int(dst.Fd()) | 	dstFd := int(dst.Fd()) | ||||||
|  |  | ||||||
| 	for size > 0 { | 	for size > 0 { | ||||||
| 		n, err := unix.CopyFileRange(srcFd, nil, dstFd, nil, int(size), 0) | 		// Ensure that we are never trying to copy more than SSIZE_MAX at a | ||||||
|  | 		// time and at the same time avoids overflows when the file is larger | ||||||
|  | 		// than 4GB on 32-bit systems. | ||||||
|  | 		var copySize int | ||||||
|  | 		if size > maxSSizeT { | ||||||
|  | 			copySize = int(maxSSizeT) | ||||||
|  | 		} else { | ||||||
|  | 			copySize = int(size) | ||||||
|  | 		} | ||||||
|  | 		n, err := unix.CopyFileRange(srcFd, nil, dstFd, nil, copySize, 0) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			if (err != unix.ENOSYS && err != unix.EXDEV) || !first { | 			if (err != unix.ENOSYS && err != unix.EXDEV) || !first { | ||||||
| 				return errors.Wrap(err, "copy file range failed") | 				return errors.Wrap(err, "copy file range failed") | ||||||
| @@ -90,18 +101,34 @@ func copyFileContent(dst, src *os.File) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func copyXAttrs(dst, src string) error { | func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error { | ||||||
| 	xattrKeys, err := sysx.LListxattr(src) | 	xattrKeys, err := sysx.LListxattr(src) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return errors.Wrapf(err, "failed to list xattrs on %s", src) | 		e := errors.Wrapf(err, "failed to list xattrs on %s", src) | ||||||
|  | 		if xeh != nil { | ||||||
|  | 			e = xeh(dst, src, "", e) | ||||||
|  | 		} | ||||||
|  | 		return e | ||||||
| 	} | 	} | ||||||
| 	for _, xattr := range xattrKeys { | 	for _, xattr := range xattrKeys { | ||||||
| 		data, err := sysx.LGetxattr(src, xattr) | 		data, err := sysx.LGetxattr(src, xattr) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src) | 			e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src) | ||||||
|  | 			if xeh != nil { | ||||||
|  | 				if e = xeh(dst, src, xattr, e); e == nil { | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			return e | ||||||
| 		} | 		} | ||||||
| 		if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil { | 		if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil { | ||||||
| 			return errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst) | 			e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst) | ||||||
|  | 			if xeh != nil { | ||||||
|  | 				if e = xeh(dst, src, xattr, e); e == nil { | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			return e | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								vendor/github.com/containerd/continuity/fs/copy_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/containerd/continuity/fs/copy_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -69,18 +69,34 @@ func copyFileContent(dst, src *os.File) error { | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| func copyXAttrs(dst, src string) error { | func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error { | ||||||
| 	xattrKeys, err := sysx.LListxattr(src) | 	xattrKeys, err := sysx.LListxattr(src) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return errors.Wrapf(err, "failed to list xattrs on %s", src) | 		e := errors.Wrapf(err, "failed to list xattrs on %s", src) | ||||||
|  | 		if xeh != nil { | ||||||
|  | 			e = xeh(dst, src, "", e) | ||||||
|  | 		} | ||||||
|  | 		return e | ||||||
| 	} | 	} | ||||||
| 	for _, xattr := range xattrKeys { | 	for _, xattr := range xattrKeys { | ||||||
| 		data, err := sysx.LGetxattr(src, xattr) | 		data, err := sysx.LGetxattr(src, xattr) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src) | 			e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src) | ||||||
|  | 			if xeh != nil { | ||||||
|  | 				if e = xeh(dst, src, xattr, e); e == nil { | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			return e | ||||||
| 		} | 		} | ||||||
| 		if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil { | 		if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil { | ||||||
| 			return errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst) | 			e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst) | ||||||
|  | 			if xeh != nil { | ||||||
|  | 				if e = xeh(dst, src, xattr, e); e == nil { | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			return e | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/containerd/continuity/fs/copy_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/containerd/continuity/fs/copy_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -40,7 +40,7 @@ func copyFileContent(dst, src *os.File) error { | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| func copyXAttrs(dst, src string) error { | func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								vendor/github.com/containerd/continuity/fs/fstest/compare.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/containerd/continuity/fs/fstest/compare.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -49,15 +49,7 @@ func CheckDirectoryEqual(d1, d2 string) error { | |||||||
|  |  | ||||||
| 	diff := diffResourceList(m1.Resources, m2.Resources) | 	diff := diffResourceList(m1.Resources, m2.Resources) | ||||||
| 	if diff.HasDiff() { | 	if diff.HasDiff() { | ||||||
| 		if len(diff.Deletions) != 0 { | 		return errors.Errorf("directory diff between %s and %s\n%s", d1, d2, diff.String()) | ||||||
| 			return errors.Errorf("directory diff between %s and %s\n%s", d1, d2, diff.String()) |  | ||||||
| 		} |  | ||||||
| 		// TODO: Also skip Recycle Bin contents in Windows layers which is used to store deleted files in some cases |  | ||||||
| 		for _, add := range diff.Additions { |  | ||||||
| 			if ok, _ := metadataFiles[add.Path()]; !ok { |  | ||||||
| 				return errors.Errorf("directory diff between %s and %s\n%s", d1, d2, diff.String()) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								vendor/github.com/containerd/continuity/fs/fstest/compare_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/containerd/continuity/fs/fstest/compare_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -17,6 +17,7 @@ | |||||||
| package fstest | package fstest | ||||||
|  |  | ||||||
| // TODO: Any more metadata files generated by Windows layers? | // TODO: Any more metadata files generated by Windows layers? | ||||||
|  | // TODO: Also skip Recycle Bin contents in Windows layers which is used to store deleted files in some cases | ||||||
| var metadataFiles = map[string]bool{ | var metadataFiles = map[string]bool{ | ||||||
| 	"\\System Volume Information": true, | 	"\\System Volume Information": true, | ||||||
| 	"\\WcSandboxState":            true, | 	"\\WcSandboxState":            true, | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								vendor/github.com/containerd/continuity/fs/fstest/continuity_util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/containerd/continuity/fs/fstest/continuity_util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -42,7 +42,17 @@ type resourceListDifference struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (l resourceListDifference) HasDiff() bool { | func (l resourceListDifference) HasDiff() bool { | ||||||
| 	return len(l.Additions) > 0 || len(l.Deletions) > 0 || len(l.Updates) > 0 | 	if len(l.Deletions) > 0 || len(l.Updates) > 0 || (len(metadataFiles) == 0 && len(l.Additions) > 0) { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for _, add := range l.Additions { | ||||||
|  | 		if ok, _ := metadataFiles[add.Path()]; !ok { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return false | ||||||
| } | } | ||||||
|  |  | ||||||
| func (l resourceListDifference) String() string { | func (l resourceListDifference) String() string { | ||||||
|   | |||||||
							
								
								
									
										33
									
								
								vendor/github.com/containerd/continuity/fs/path.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								vendor/github.com/containerd/continuity/fs/path.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -22,7 +22,6 @@ import ( | |||||||
| 	"io" | 	"io" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	"github.com/pkg/errors" | 	"github.com/pkg/errors" | ||||||
| ) | ) | ||||||
| @@ -47,9 +46,8 @@ func pathChange(lower, upper *currentPath) (ChangeKind, string) { | |||||||
| 	if upper == nil { | 	if upper == nil { | ||||||
| 		return ChangeKindDelete, lower.path | 		return ChangeKindDelete, lower.path | ||||||
| 	} | 	} | ||||||
| 	// TODO: compare by directory |  | ||||||
|  |  | ||||||
| 	switch i := strings.Compare(lower.path, upper.path); { | 	switch i := directoryCompare(lower.path, upper.path); { | ||||||
| 	case i < 0: | 	case i < 0: | ||||||
| 		// File in lower that is not in upper | 		// File in lower that is not in upper | ||||||
| 		return ChangeKindDelete, lower.path | 		return ChangeKindDelete, lower.path | ||||||
| @@ -61,6 +59,35 @@ func pathChange(lower, upper *currentPath) (ChangeKind, string) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func directoryCompare(a, b string) int { | ||||||
|  | 	l := len(a) | ||||||
|  | 	if len(b) < l { | ||||||
|  | 		l = len(b) | ||||||
|  | 	} | ||||||
|  | 	for i := 0; i < l; i++ { | ||||||
|  | 		c1, c2 := a[i], b[i] | ||||||
|  | 		if c1 == filepath.Separator { | ||||||
|  | 			c1 = byte(0) | ||||||
|  | 		} | ||||||
|  | 		if c2 == filepath.Separator { | ||||||
|  | 			c2 = byte(0) | ||||||
|  | 		} | ||||||
|  | 		if c1 < c2 { | ||||||
|  | 			return -1 | ||||||
|  | 		} | ||||||
|  | 		if c1 > c2 { | ||||||
|  | 			return +1 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if len(a) < len(b) { | ||||||
|  | 		return -1 | ||||||
|  | 	} | ||||||
|  | 	if len(a) > len(b) { | ||||||
|  | 		return +1 | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
| func sameFile(f1, f2 *currentPath) (bool, error) { | func sameFile(f1, f2 *currentPath) (bool, error) { | ||||||
| 	if os.SameFile(f1.f, f2.f) { | 	if os.SameFile(f1.f, f2.f) { | ||||||
| 		return true, nil | 		return true, nil | ||||||
|   | |||||||
							
								
								
									
										55
									
								
								vendor/github.com/containerd/continuity/testutil/loopback/loopback_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										55
									
								
								vendor/github.com/containerd/continuity/testutil/loopback/loopback_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -22,24 +22,25 @@ import ( | |||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/exec" | 	"os/exec" | ||||||
|  | 	"syscall" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"github.com/pkg/errors" | 	"github.com/pkg/errors" | ||||||
| 	"github.com/sirupsen/logrus" | 	"github.com/sirupsen/logrus" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // New creates a loopback device, and returns its device name (/dev/loopX), and its clean-up function. | // New creates a loopback device | ||||||
| func New(size int64) (string, func() error, error) { | func New(size int64) (*Loopback, error) { | ||||||
| 	// create temporary file for the disk image | 	// create temporary file for the disk image | ||||||
| 	file, err := ioutil.TempFile("", "containerd-test-loopback") | 	file, err := ioutil.TempFile("", "containerd-test-loopback") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", nil, errors.Wrap(err, "could not create temporary file for loopback") | 		return nil, errors.Wrap(err, "could not create temporary file for loopback") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := file.Truncate(size); err != nil { | 	if err := file.Truncate(size); err != nil { | ||||||
| 		file.Close() | 		file.Close() | ||||||
| 		os.Remove(file.Name()) | 		os.Remove(file.Name()) | ||||||
| 		return "", nil, errors.Wrap(err, "failed to resize temp file") | 		return nil, errors.Wrap(err, "failed to resize temp file") | ||||||
| 	} | 	} | ||||||
| 	file.Close() | 	file.Close() | ||||||
|  |  | ||||||
| @@ -48,7 +49,7 @@ func New(size int64) (string, func() error, error) { | |||||||
| 	p, err := losetup.Output() | 	p, err := losetup.Output() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		os.Remove(file.Name()) | 		os.Remove(file.Name()) | ||||||
| 		return "", nil, errors.Wrap(err, "loopback setup failed") | 		return nil, errors.Wrap(err, "loopback setup failed") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	deviceName := strings.TrimSpace(string(p)) | 	deviceName := strings.TrimSpace(string(p)) | ||||||
| @@ -68,5 +69,47 @@ func New(size int64) (string, func() error, error) { | |||||||
| 		return os.Remove(file.Name()) | 		return os.Remove(file.Name()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return deviceName, cleanup, nil | 	l := Loopback{ | ||||||
|  | 		File: file.Name(), | ||||||
|  | 		Device: deviceName, | ||||||
|  | 		close: cleanup, | ||||||
|  | 	} | ||||||
|  | 	return &l, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Loopback device | ||||||
|  | type Loopback struct { | ||||||
|  | 	// File is the underlying sparse file | ||||||
|  | 	File string | ||||||
|  | 	// Device is /dev/loopX | ||||||
|  | 	Device string | ||||||
|  | 	close func() error | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // SoftSize returns st_size | ||||||
|  | func (l *Loopback) SoftSize() (int64, error) { | ||||||
|  | 	st, err := os.Stat(l.File) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return 0, err | ||||||
|  | 	} | ||||||
|  | 	return st.Size(), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // HardSize returns st_blocks * 512; see stat(2) | ||||||
|  | func (l *Loopback) HardSize() (int64, error) { | ||||||
|  | 	st, err := os.Stat(l.File) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return 0, err | ||||||
|  | 	} | ||||||
|  | 	st2, ok := st.Sys().(*syscall.Stat_t) | ||||||
|  | 	if !ok { | ||||||
|  | 		return 0, errors.New("st.Sys() is not a *syscall.Stat_t") | ||||||
|  | 	} | ||||||
|  | 	// NOTE: st_blocks has nothing to do with st_blksize; see stat(2) | ||||||
|  | 	return st2.Blocks * 512, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Close detaches the device and removes the underlying file | ||||||
|  | func (l *Loopback) Close() error { | ||||||
|  | 	return l.close() | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Derek McGowan
					Derek McGowan