Use continuity fs package
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
parent
f12ba2407e
commit
c776b6d8d9
@ -13,8 +13,8 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/fs"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/continuity/fs"
|
||||
"github.com/dmcgowan/go-tar"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -16,8 +16,8 @@ import (
|
||||
|
||||
_ "crypto/sha256"
|
||||
|
||||
"github.com/containerd/containerd/fs"
|
||||
"github.com/containerd/containerd/fs/fstest"
|
||||
"github.com/containerd/continuity/fs"
|
||||
"github.com/containerd/continuity/fs/fstest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -1,71 +0,0 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
_ "crypto/sha256"
|
||||
|
||||
"github.com/containerd/containerd/fs/fstest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// TODO: Create copy directory which requires privilege
|
||||
// chown
|
||||
// mknod
|
||||
// setxattr fstest.SetXAttr("/home", "trusted.overlay.opaque", "y"),
|
||||
|
||||
func TestCopyDirectory(t *testing.T) {
|
||||
apply := fstest.Apply(
|
||||
fstest.CreateDir("/etc/", 0755),
|
||||
fstest.CreateFile("/etc/hosts", []byte("localhost 127.0.0.1"), 0644),
|
||||
fstest.Link("/etc/hosts", "/etc/hosts.allow"),
|
||||
fstest.CreateDir("/usr/local/lib", 0755),
|
||||
fstest.CreateFile("/usr/local/lib/libnothing.so", []byte{0x00, 0x00}, 0755),
|
||||
fstest.Symlink("libnothing.so", "/usr/local/lib/libnothing.so.2"),
|
||||
fstest.CreateDir("/home", 0755),
|
||||
)
|
||||
|
||||
if err := testCopy(apply); err != nil {
|
||||
t.Fatalf("Copy test failed: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// This test used to fail because link-no-nothing.txt would be copied first,
|
||||
// then file operations in dst during the CopyDir would follow the symlink and
|
||||
// fail.
|
||||
func TestCopyDirectoryWithLocalSymlink(t *testing.T) {
|
||||
apply := fstest.Apply(
|
||||
fstest.CreateFile("nothing.txt", []byte{0x00, 0x00}, 0755),
|
||||
fstest.Symlink("nothing.txt", "link-no-nothing.txt"),
|
||||
)
|
||||
|
||||
if err := testCopy(apply); err != nil {
|
||||
t.Fatalf("Copy test failed: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func testCopy(apply fstest.Applier) error {
|
||||
t1, err := ioutil.TempDir("", "test-copy-src-")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create temporary directory")
|
||||
}
|
||||
defer os.RemoveAll(t1)
|
||||
|
||||
t2, err := ioutil.TempDir("", "test-copy-dst-")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create temporary directory")
|
||||
}
|
||||
defer os.RemoveAll(t2)
|
||||
|
||||
if err := apply.Apply(t1); err != nil {
|
||||
return errors.Wrap(err, "failed to apply changes")
|
||||
}
|
||||
|
||||
if err := CopyDir(t2, t1); err != nil {
|
||||
return errors.Wrap(err, "failed to copy")
|
||||
}
|
||||
|
||||
return fstest.CheckDirectoryEqual(t1, t2)
|
||||
}
|
383
fs/diff_test.go
383
fs/diff_test.go
@ -1,383 +0,0 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/fs/fstest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// TODO: Additional tests
|
||||
// - capability test (requires privilege)
|
||||
// - chown test (requires privilege)
|
||||
// - symlink test
|
||||
// - hardlink test
|
||||
|
||||
func skipDiffTestOnWindows(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("diff implementation is incomplete on windows")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimpleDiff(t *testing.T) {
|
||||
skipDiffTestOnWindows(t)
|
||||
l1 := fstest.Apply(
|
||||
fstest.CreateDir("/etc", 0755),
|
||||
fstest.CreateFile("/etc/hosts", []byte("mydomain 10.0.0.1"), 0644),
|
||||
fstest.CreateFile("/etc/profile", []byte("PATH=/usr/bin"), 0644),
|
||||
fstest.CreateFile("/etc/unchanged", []byte("PATH=/usr/bin"), 0644),
|
||||
fstest.CreateFile("/etc/unexpected", []byte("#!/bin/sh"), 0644),
|
||||
)
|
||||
l2 := fstest.Apply(
|
||||
fstest.CreateFile("/etc/hosts", []byte("mydomain 10.0.0.120"), 0644),
|
||||
fstest.CreateFile("/etc/profile", []byte("PATH=/usr/bin"), 0666),
|
||||
fstest.CreateDir("/root", 0700),
|
||||
fstest.CreateFile("/root/.bashrc", []byte("PATH=/usr/sbin:/usr/bin"), 0644),
|
||||
fstest.Remove("/etc/unexpected"),
|
||||
)
|
||||
diff := []TestChange{
|
||||
Modify("/etc/hosts"),
|
||||
Modify("/etc/profile"),
|
||||
Delete("/etc/unexpected"),
|
||||
Add("/root"),
|
||||
Add("/root/.bashrc"),
|
||||
}
|
||||
|
||||
if err := testDiffWithBase(l1, l2, diff); err != nil {
|
||||
t.Fatalf("Failed diff with base: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDirectoryReplace(t *testing.T) {
|
||||
skipDiffTestOnWindows(t)
|
||||
l1 := fstest.Apply(
|
||||
fstest.CreateDir("/dir1", 0755),
|
||||
fstest.CreateFile("/dir1/f1", []byte("#####"), 0644),
|
||||
fstest.CreateDir("/dir1/f2", 0755),
|
||||
fstest.CreateFile("/dir1/f2/f3", []byte("#!/bin/sh"), 0644),
|
||||
)
|
||||
l2 := fstest.Apply(
|
||||
fstest.CreateFile("/dir1/f11", []byte("#New file here"), 0644),
|
||||
fstest.RemoveAll("/dir1/f2"),
|
||||
fstest.CreateFile("/dir1/f2", []byte("Now file"), 0666),
|
||||
)
|
||||
diff := []TestChange{
|
||||
Add("/dir1/f11"),
|
||||
Modify("/dir1/f2"),
|
||||
}
|
||||
|
||||
if err := testDiffWithBase(l1, l2, diff); err != nil {
|
||||
t.Fatalf("Failed diff with base: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveDirectoryTree(t *testing.T) {
|
||||
l1 := fstest.Apply(
|
||||
fstest.CreateDir("/dir1/dir2/dir3", 0755),
|
||||
fstest.CreateFile("/dir1/f1", []byte("f1"), 0644),
|
||||
fstest.CreateFile("/dir1/dir2/f2", []byte("f2"), 0644),
|
||||
)
|
||||
l2 := fstest.Apply(
|
||||
fstest.RemoveAll("/dir1"),
|
||||
)
|
||||
diff := []TestChange{
|
||||
Delete("/dir1"),
|
||||
}
|
||||
|
||||
if err := testDiffWithBase(l1, l2, diff); err != nil {
|
||||
t.Fatalf("Failed diff with base: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileReplace(t *testing.T) {
|
||||
l1 := fstest.Apply(
|
||||
fstest.CreateFile("/dir1", []byte("a file, not a directory"), 0644),
|
||||
)
|
||||
l2 := fstest.Apply(
|
||||
fstest.Remove("/dir1"),
|
||||
fstest.CreateDir("/dir1/dir2", 0755),
|
||||
fstest.CreateFile("/dir1/dir2/f1", []byte("also a file"), 0644),
|
||||
)
|
||||
diff := []TestChange{
|
||||
Modify("/dir1"),
|
||||
Add("/dir1/dir2"),
|
||||
Add("/dir1/dir2/f1"),
|
||||
}
|
||||
|
||||
if err := testDiffWithBase(l1, l2, diff); err != nil {
|
||||
t.Fatalf("Failed diff with base: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParentDirectoryPermission(t *testing.T) {
|
||||
skipDiffTestOnWindows(t)
|
||||
l1 := fstest.Apply(
|
||||
fstest.CreateDir("/dir1", 0700),
|
||||
fstest.CreateDir("/dir2", 0751),
|
||||
fstest.CreateDir("/dir3", 0777),
|
||||
)
|
||||
l2 := fstest.Apply(
|
||||
fstest.CreateDir("/dir1/d", 0700),
|
||||
fstest.CreateFile("/dir1/d/f", []byte("irrelevant"), 0644),
|
||||
fstest.CreateFile("/dir1/f", []byte("irrelevant"), 0644),
|
||||
fstest.CreateFile("/dir2/f", []byte("irrelevant"), 0644),
|
||||
fstest.CreateFile("/dir3/f", []byte("irrelevant"), 0644),
|
||||
)
|
||||
diff := []TestChange{
|
||||
Add("/dir1/d"),
|
||||
Add("/dir1/d/f"),
|
||||
Add("/dir1/f"),
|
||||
Add("/dir2/f"),
|
||||
Add("/dir3/f"),
|
||||
}
|
||||
|
||||
if err := testDiffWithBase(l1, l2, diff); err != nil {
|
||||
t.Fatalf("Failed diff with base: %+v", err)
|
||||
}
|
||||
}
|
||||
func TestUpdateWithSameTime(t *testing.T) {
|
||||
skipDiffTestOnWindows(t)
|
||||
tt := time.Now().Truncate(time.Second)
|
||||
t1 := tt.Add(5 * time.Nanosecond)
|
||||
t2 := tt.Add(6 * time.Nanosecond)
|
||||
l1 := fstest.Apply(
|
||||
fstest.CreateFile("/file-modified-time", []byte("1"), 0644),
|
||||
fstest.Chtimes("/file-modified-time", t1, t1),
|
||||
fstest.CreateFile("/file-no-change", []byte("1"), 0644),
|
||||
fstest.Chtimes("/file-no-change", t1, t1),
|
||||
fstest.CreateFile("/file-same-time", []byte("1"), 0644),
|
||||
fstest.Chtimes("/file-same-time", t1, t1),
|
||||
fstest.CreateFile("/file-truncated-time-1", []byte("1"), 0644),
|
||||
fstest.Chtimes("/file-truncated-time-1", tt, tt),
|
||||
fstest.CreateFile("/file-truncated-time-2", []byte("1"), 0644),
|
||||
fstest.Chtimes("/file-truncated-time-2", tt, tt),
|
||||
fstest.CreateFile("/file-truncated-time-3", []byte("1"), 0644),
|
||||
fstest.Chtimes("/file-truncated-time-3", t1, t1),
|
||||
)
|
||||
l2 := fstest.Apply(
|
||||
fstest.CreateFile("/file-modified-time", []byte("2"), 0644),
|
||||
fstest.Chtimes("/file-modified-time", t2, t2),
|
||||
fstest.CreateFile("/file-no-change", []byte("1"), 0644),
|
||||
fstest.Chtimes("/file-no-change", t1, t1),
|
||||
fstest.CreateFile("/file-same-time", []byte("2"), 0644),
|
||||
fstest.Chtimes("/file-same-time", t1, t1),
|
||||
fstest.CreateFile("/file-truncated-time-1", []byte("1"), 0644),
|
||||
fstest.Chtimes("/file-truncated-time-1", t1, t1),
|
||||
fstest.CreateFile("/file-truncated-time-2", []byte("2"), 0644),
|
||||
fstest.Chtimes("/file-truncated-time-2", tt, tt),
|
||||
fstest.CreateFile("/file-truncated-time-3", []byte("1"), 0644),
|
||||
fstest.Chtimes("/file-truncated-time-3", tt, tt),
|
||||
)
|
||||
diff := []TestChange{
|
||||
Modify("/file-modified-time"),
|
||||
// Include changes with truncated timestamps. Comparing newly
|
||||
// extracted tars which have truncated timestamps will be
|
||||
// expected to produce changes. The expectation is that diff
|
||||
// archives are generated once and kept, newly generated diffs
|
||||
// will not consider cases where only one side is truncated.
|
||||
Modify("/file-truncated-time-1"),
|
||||
Modify("/file-truncated-time-2"),
|
||||
Modify("/file-truncated-time-3"),
|
||||
}
|
||||
|
||||
if err := testDiffWithBase(l1, l2, diff); err != nil {
|
||||
t.Fatalf("Failed diff with base: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// buildkit#172
|
||||
func TestLchtimes(t *testing.T) {
|
||||
skipDiffTestOnWindows(t)
|
||||
mtimes := []time.Time{
|
||||
time.Unix(0, 0), // nsec is 0
|
||||
time.Unix(0, 42), // nsec > 0
|
||||
}
|
||||
for _, mtime := range mtimes {
|
||||
atime := time.Unix(424242, 42)
|
||||
l1 := fstest.Apply(
|
||||
fstest.CreateFile("/foo", []byte("foo"), 0644),
|
||||
fstest.Symlink("/foo", "/lnk0"),
|
||||
fstest.Lchtimes("/lnk0", atime, mtime),
|
||||
)
|
||||
l2 := fstest.Apply() // empty
|
||||
diff := []TestChange{}
|
||||
if err := testDiffWithBase(l1, l2, diff); err != nil {
|
||||
t.Fatalf("Failed diff with base: %+v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testDiffWithBase(base, diff fstest.Applier, expected []TestChange) error {
|
||||
t1, err := ioutil.TempDir("", "diff-with-base-lower-")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create temp dir")
|
||||
}
|
||||
defer os.RemoveAll(t1)
|
||||
t2, err := ioutil.TempDir("", "diff-with-base-upper-")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create temp dir")
|
||||
}
|
||||
defer os.RemoveAll(t2)
|
||||
|
||||
if err := base.Apply(t1); err != nil {
|
||||
return errors.Wrap(err, "failed to apply base filesystem")
|
||||
}
|
||||
|
||||
if err := CopyDir(t2, t1); err != nil {
|
||||
return errors.Wrap(err, "failed to copy base directory")
|
||||
}
|
||||
|
||||
if err := diff.Apply(t2); err != nil {
|
||||
return errors.Wrap(err, "failed to apply diff filesystem")
|
||||
}
|
||||
|
||||
changes, err := collectChanges(t1, t2)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to collect changes")
|
||||
}
|
||||
|
||||
return checkChanges(t2, changes, expected)
|
||||
}
|
||||
|
||||
func TestBaseDirectoryChanges(t *testing.T) {
|
||||
apply := fstest.Apply(
|
||||
fstest.CreateDir("/etc", 0755),
|
||||
fstest.CreateFile("/etc/hosts", []byte("mydomain 10.0.0.1"), 0644),
|
||||
fstest.CreateFile("/etc/profile", []byte("PATH=/usr/bin"), 0644),
|
||||
fstest.CreateDir("/root", 0700),
|
||||
fstest.CreateFile("/root/.bashrc", []byte("PATH=/usr/sbin:/usr/bin"), 0644),
|
||||
)
|
||||
changes := []TestChange{
|
||||
Add("/etc"),
|
||||
Add("/etc/hosts"),
|
||||
Add("/etc/profile"),
|
||||
Add("/root"),
|
||||
Add("/root/.bashrc"),
|
||||
}
|
||||
|
||||
if err := testDiffWithoutBase(apply, changes); err != nil {
|
||||
t.Fatalf("Failed diff without base: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func testDiffWithoutBase(apply fstest.Applier, expected []TestChange) error {
|
||||
tmp, err := ioutil.TempDir("", "diff-without-base-")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create temp dir")
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
if err := apply.Apply(tmp); err != nil {
|
||||
return errors.Wrap(err, "failed to apply filesytem changes")
|
||||
}
|
||||
|
||||
changes, err := collectChanges("", tmp)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to collect changes")
|
||||
}
|
||||
|
||||
return checkChanges(tmp, changes, expected)
|
||||
}
|
||||
|
||||
func checkChanges(root string, changes, expected []TestChange) error {
|
||||
if len(changes) != len(expected) {
|
||||
return errors.Errorf("Unexpected number of changes:\n%s", diffString(changes, expected))
|
||||
}
|
||||
for i := range changes {
|
||||
if changes[i].Path != expected[i].Path || changes[i].Kind != expected[i].Kind {
|
||||
return errors.Errorf("Unexpected change at %d:\n%s", i, diffString(changes, expected))
|
||||
}
|
||||
if changes[i].Kind != ChangeKindDelete {
|
||||
filename := filepath.Join(root, changes[i].Path)
|
||||
efi, err := os.Stat(filename)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to stat %q", filename)
|
||||
}
|
||||
afi := changes[i].FileInfo
|
||||
if afi.Size() != efi.Size() {
|
||||
return errors.Errorf("Unexpected change size %d, %q has size %d", afi.Size(), filename, efi.Size())
|
||||
}
|
||||
if afi.Mode() != efi.Mode() {
|
||||
return errors.Errorf("Unexpected change mode %s, %q has mode %s", afi.Mode(), filename, efi.Mode())
|
||||
}
|
||||
if afi.ModTime() != efi.ModTime() {
|
||||
return errors.Errorf("Unexpected change modtime %s, %q has modtime %s", afi.ModTime(), filename, efi.ModTime())
|
||||
}
|
||||
if expected := filepath.Join(root, changes[i].Path); changes[i].Source != expected {
|
||||
return errors.Errorf("Unexpected source path %s, expected %s", changes[i].Source, expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type TestChange struct {
|
||||
Kind ChangeKind
|
||||
Path string
|
||||
FileInfo os.FileInfo
|
||||
Source string
|
||||
}
|
||||
|
||||
func collectChanges(a, b string) ([]TestChange, error) {
|
||||
changes := []TestChange{}
|
||||
err := Changes(context.Background(), a, b, func(k ChangeKind, p string, f os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
changes = append(changes, TestChange{
|
||||
Kind: k,
|
||||
Path: p,
|
||||
FileInfo: f,
|
||||
Source: filepath.Join(b, p),
|
||||
})
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to compute changes")
|
||||
}
|
||||
|
||||
return changes, nil
|
||||
}
|
||||
|
||||
func diffString(c1, c2 []TestChange) string {
|
||||
return fmt.Sprintf("got(%d):\n%s\nexpected(%d):\n%s", len(c1), changesString(c1), len(c2), changesString(c2))
|
||||
|
||||
}
|
||||
|
||||
func changesString(c []TestChange) string {
|
||||
strs := make([]string, len(c))
|
||||
for i := range c {
|
||||
strs[i] = fmt.Sprintf("\t%s\t%s", c[i].Kind, c[i].Path)
|
||||
}
|
||||
return strings.Join(strs, "\n")
|
||||
}
|
||||
|
||||
func Add(p string) TestChange {
|
||||
return TestChange{
|
||||
Kind: ChangeKindAdd,
|
||||
Path: filepath.FromSlash(p),
|
||||
}
|
||||
}
|
||||
|
||||
func Delete(p string) TestChange {
|
||||
return TestChange{
|
||||
Kind: ChangeKindDelete,
|
||||
Path: filepath.FromSlash(p),
|
||||
}
|
||||
}
|
||||
|
||||
func Modify(p string) TestChange {
|
||||
return TestChange{
|
||||
Kind: ChangeKindModify,
|
||||
Path: filepath.FromSlash(p),
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
// +build linux
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func testSupportsDType(t *testing.T, expected bool, mkfs ...string) {
|
||||
testutil.RequiresRoot(t)
|
||||
mnt, err := ioutil.TempDir("", "containerd-fs-test-supports-dtype")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(mnt)
|
||||
|
||||
deviceName, cleanupDevice, err := testutil.NewLoopback(100 << 20) // 100 MB
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if out, err := exec.Command(mkfs[0], append(mkfs[1:], deviceName)...).CombinedOutput(); err != nil {
|
||||
// not fatal
|
||||
cleanupDevice()
|
||||
t.Skipf("could not mkfs (%v) %s: %v (out: %q)", mkfs, deviceName, err, string(out))
|
||||
}
|
||||
if out, err := exec.Command("mount", deviceName, mnt).CombinedOutput(); err != nil {
|
||||
// not fatal
|
||||
cleanupDevice()
|
||||
t.Skipf("could not mount %s: %v (out: %q)", deviceName, err, string(out))
|
||||
}
|
||||
defer func() {
|
||||
testutil.Unmount(t, mnt)
|
||||
cleanupDevice()
|
||||
}()
|
||||
// check whether it supports d_type
|
||||
result, err := SupportsDType(mnt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("Supports d_type: %v", result)
|
||||
assert.Equal(t, expected, result)
|
||||
}
|
||||
|
||||
func TestSupportsDTypeWithFType0XFS(t *testing.T) {
|
||||
testSupportsDType(t, false, "mkfs.xfs", "-m", "crc=0", "-n", "ftype=0")
|
||||
}
|
||||
|
||||
func TestSupportsDTypeWithFType1XFS(t *testing.T) {
|
||||
testSupportsDType(t, true, "mkfs.xfs", "-m", "crc=0", "-n", "ftype=1")
|
||||
}
|
||||
|
||||
func TestSupportsDTypeWithExt4(t *testing.T) {
|
||||
testSupportsDType(t, true, "mkfs.ext4", "-F")
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/testutil"
|
||||
)
|
||||
|
||||
func TestRequiresRootNOP(t *testing.T) {
|
||||
|
||||
// This is a dummy test case that exist to call
|
||||
// testutil.RequiresRoot() on non-linux platforms. This is
|
||||
// needed because the Makfile root-coverage tests target
|
||||
// determines which packages contain root test by grepping for
|
||||
// testutil.RequiresRoot. Within the fs package, the only test
|
||||
// that references this symbol is in dtype_linux_test.go, but
|
||||
// that file is only built on linux. Since the Makefile is not
|
||||
// go build tag aware it sees this file and then tries to run
|
||||
// the following command on all platforms: "go test ...
|
||||
// github.com/containerd/containerd/fs -test.root". On
|
||||
// non-linux platforms this fails because there are no tests in
|
||||
// the "fs" package that reference testutil.RequiresRoot. To
|
||||
// fix this problem we'll add a reference to this symbol below.
|
||||
|
||||
testutil.RequiresRoot(t)
|
||||
}
|
294
fs/path_test.go
294
fs/path_test.go
@ -1,294 +0,0 @@
|
||||
// +build !windows
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/fs/fstest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type RootCheck struct {
|
||||
unresolved string
|
||||
expected string
|
||||
scope func(string) string
|
||||
cause error
|
||||
}
|
||||
|
||||
func TestRootPath(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
apply fstest.Applier
|
||||
checks []RootCheck
|
||||
}{
|
||||
{
|
||||
name: "SymlinkAbsolute",
|
||||
apply: Symlink("/b", "fs/a/d"),
|
||||
checks: Check("fs/a/d/c/data", "b/c/data"),
|
||||
},
|
||||
{
|
||||
name: "SymlinkRelativePath",
|
||||
apply: Symlink("a", "fs/i"),
|
||||
checks: Check("fs/i", "fs/a"),
|
||||
},
|
||||
{
|
||||
name: "SymlinkSkipSymlinksOutsideScope",
|
||||
apply: Symlink("realdir", "linkdir"),
|
||||
checks: CheckWithScope("foo/bar", "foo/bar", "linkdir"),
|
||||
},
|
||||
{
|
||||
name: "SymlinkLastLink",
|
||||
apply: Symlink("/b", "fs/a/d"),
|
||||
checks: Check("fs/a/d", "b"),
|
||||
},
|
||||
{
|
||||
name: "SymlinkRelativeLinkChangeScope",
|
||||
apply: Symlink("../b", "fs/a/e"),
|
||||
checks: CheckAll(
|
||||
Check("fs/a/e/c/data", "fs/b/c/data"),
|
||||
CheckWithScope("e", "b", "fs/a"), // Original return
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "SymlinkDeepRelativeLinkChangeScope",
|
||||
apply: Symlink("../../../../test", "fs/a/f"),
|
||||
checks: CheckAll(
|
||||
Check("fs/a/f", "test"), // Original return
|
||||
CheckWithScope("a/f", "test", "fs"), // Original return
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "SymlinkRelativeLinkChain",
|
||||
apply: fstest.Apply(
|
||||
Symlink("../g", "fs/b/h"),
|
||||
fstest.Symlink("../../../../../../../../../../../../root", "fs/g"),
|
||||
),
|
||||
checks: Check("fs/b/h", "root"),
|
||||
},
|
||||
{
|
||||
name: "SymlinkBreakoutPath",
|
||||
apply: Symlink("../i/a", "fs/j/k"),
|
||||
checks: CheckWithScope("k", "i/a", "fs/j"),
|
||||
},
|
||||
{
|
||||
name: "SymlinkToRoot",
|
||||
apply: Symlink("/", "foo"),
|
||||
checks: Check("foo", ""),
|
||||
},
|
||||
{
|
||||
name: "SymlinkSlashDotdot",
|
||||
apply: Symlink("/../../", "foo"),
|
||||
checks: Check("foo", ""),
|
||||
},
|
||||
{
|
||||
name: "SymlinkDotdot",
|
||||
apply: Symlink("../../", "foo"),
|
||||
checks: Check("foo", ""),
|
||||
},
|
||||
{
|
||||
name: "SymlinkRelativePath2",
|
||||
apply: Symlink("baz/target", "bar/foo"),
|
||||
checks: Check("bar/foo", "bar/baz/target"),
|
||||
},
|
||||
{
|
||||
name: "SymlinkScopeLink",
|
||||
apply: fstest.Apply(
|
||||
Symlink("root2", "root"),
|
||||
Symlink("../bar", "root2/foo"),
|
||||
),
|
||||
checks: CheckWithScope("foo", "bar", "root"),
|
||||
},
|
||||
{
|
||||
name: "SymlinkSelf",
|
||||
apply: fstest.Apply(
|
||||
Symlink("foo", "root/foo"),
|
||||
),
|
||||
checks: ErrorWithScope("foo", "root", errTooManyLinks),
|
||||
},
|
||||
{
|
||||
name: "SymlinkCircular",
|
||||
apply: fstest.Apply(
|
||||
Symlink("foo", "bar"),
|
||||
Symlink("bar", "foo"),
|
||||
),
|
||||
checks: ErrorWithScope("foo", "", errTooManyLinks), //TODO: Test for circular error
|
||||
},
|
||||
{
|
||||
name: "SymlinkCircularUnderRoot",
|
||||
apply: fstest.Apply(
|
||||
Symlink("baz", "root/bar"),
|
||||
Symlink("../bak", "root/baz"),
|
||||
Symlink("/bar", "root/bak"),
|
||||
),
|
||||
checks: ErrorWithScope("bar", "root", errTooManyLinks), // TODO: Test for circular error
|
||||
},
|
||||
{
|
||||
name: "SymlinkComplexChain",
|
||||
apply: fstest.Apply(
|
||||
fstest.CreateDir("root2", 0777),
|
||||
Symlink("root2", "root"),
|
||||
Symlink("r/s", "root/a"),
|
||||
Symlink("../root/t", "root/r"),
|
||||
Symlink("/../u", "root/root/t/s/b"),
|
||||
Symlink(".", "root/u/c"),
|
||||
Symlink("../v", "root/u/x/y"),
|
||||
Symlink("/../w", "root/u/v"),
|
||||
),
|
||||
checks: CheckWithScope("a/b/c/x/y/z", "w/z", "root"), // Original return
|
||||
},
|
||||
{
|
||||
name: "SymlinkBreakoutNonExistent",
|
||||
apply: fstest.Apply(
|
||||
Symlink("/", "root/slash"),
|
||||
Symlink("/idontexist/../slash", "root/sym"),
|
||||
),
|
||||
checks: CheckWithScope("sym/file", "file", "root"),
|
||||
},
|
||||
{
|
||||
name: "SymlinkNoLexicalCleaning",
|
||||
apply: fstest.Apply(
|
||||
Symlink("/foo/bar", "root/sym"),
|
||||
Symlink("/sym/../baz", "root/hello"),
|
||||
),
|
||||
checks: CheckWithScope("hello", "foo/baz", "root"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, makeRootPathTest(t, test.apply, test.checks))
|
||||
}
|
||||
|
||||
// Add related tests which are unable to follow same pattern
|
||||
t.Run("SymlinkRootScope", testRootPathSymlinkRootScope)
|
||||
t.Run("SymlinkEmpty", testRootPathSymlinkEmpty)
|
||||
}
|
||||
|
||||
func testRootPathSymlinkRootScope(t *testing.T) {
|
||||
tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkRootScope")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
expected, err := filepath.EvalSymlinks(tmpdir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rewrite, err := RootPath("/", tmpdir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if rewrite != expected {
|
||||
t.Fatalf("expected %q got %q", expected, rewrite)
|
||||
}
|
||||
}
|
||||
func testRootPathSymlinkEmpty(t *testing.T) {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res, err := RootPath(wd, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if res != wd {
|
||||
t.Fatalf("expected %q got %q", wd, res)
|
||||
}
|
||||
}
|
||||
|
||||
func makeRootPathTest(t *testing.T, apply fstest.Applier, checks []RootCheck) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
applyDir, err := ioutil.TempDir("", "test-root-path-")
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to make temp directory: %+v", err)
|
||||
}
|
||||
defer os.RemoveAll(applyDir)
|
||||
|
||||
if apply != nil {
|
||||
if err := apply.Apply(applyDir); err != nil {
|
||||
t.Fatalf("Apply failed: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
for i, check := range checks {
|
||||
root := applyDir
|
||||
if check.scope != nil {
|
||||
root = check.scope(root)
|
||||
}
|
||||
|
||||
actual, err := RootPath(root, check.unresolved)
|
||||
if check.cause != nil {
|
||||
if err == nil {
|
||||
t.Errorf("(Check %d) Expected error %q, %q evaluated as %q", i+1, check.cause.Error(), check.unresolved, actual)
|
||||
}
|
||||
if errors.Cause(err) != check.cause {
|
||||
t.Fatalf("(Check %d) Failed to evaluate root path: %+v", i+1, err)
|
||||
}
|
||||
} else {
|
||||
expected := filepath.Join(root, check.expected)
|
||||
if err != nil {
|
||||
t.Fatalf("(Check %d) Failed to evaluate root path: %+v", i+1, err)
|
||||
}
|
||||
if actual != expected {
|
||||
t.Errorf("(Check %d) Unexpected evaluated path %q, expected %q", i+1, actual, expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Check(unresolved, expected string) []RootCheck {
|
||||
return []RootCheck{
|
||||
{
|
||||
unresolved: unresolved,
|
||||
expected: expected,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func CheckWithScope(unresolved, expected, scope string) []RootCheck {
|
||||
return []RootCheck{
|
||||
{
|
||||
unresolved: unresolved,
|
||||
expected: expected,
|
||||
scope: func(root string) string {
|
||||
return filepath.Join(root, scope)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func ErrorWithScope(unresolved, scope string, cause error) []RootCheck {
|
||||
return []RootCheck{
|
||||
{
|
||||
unresolved: unresolved,
|
||||
cause: cause,
|
||||
scope: func(root string) string {
|
||||
return filepath.Join(root, scope)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func CheckAll(checks ...[]RootCheck) []RootCheck {
|
||||
all := make([]RootCheck, 0, len(checks))
|
||||
for _, c := range checks {
|
||||
all = append(all, c...)
|
||||
}
|
||||
return all
|
||||
}
|
||||
|
||||
func Symlink(oldname, newname string) fstest.Applier {
|
||||
dir := filepath.Dir(newname)
|
||||
if dir != "" {
|
||||
return fstest.Apply(
|
||||
fstest.CreateDir(dir, 0755),
|
||||
fstest.Symlink(oldname, newname),
|
||||
)
|
||||
}
|
||||
return fstest.Symlink(oldname, newname)
|
||||
}
|
@ -13,10 +13,10 @@ import (
|
||||
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/fs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/continuity/fs"
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/opencontainers/runc/libcontainer/user"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
|
@ -10,13 +10,13 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/btrfs"
|
||||
"github.com/containerd/containerd/fs"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
"github.com/containerd/containerd/snapshots/storage"
|
||||
"github.com/containerd/continuity/fs"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
@ -6,13 +6,13 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containerd/containerd/fs"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
"github.com/containerd/containerd/snapshots/storage"
|
||||
"github.com/containerd/continuity/fs"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -11,13 +11,13 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/containerd/containerd/fs"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
"github.com/containerd/containerd/snapshots/storage"
|
||||
"github.com/containerd/continuity/fs"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -7,9 +7,9 @@ import (
|
||||
"math/rand"
|
||||
"os"
|
||||
|
||||
"github.com/containerd/containerd/fs/fstest"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
"github.com/containerd/continuity/fs/fstest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -7,8 +7,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/fs/fstest"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
"github.com/containerd/continuity/fs/fstest"
|
||||
)
|
||||
|
||||
// Checks which cover former issues found in older layering models.
|
||||
|
@ -11,11 +11,11 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/fs/fstest"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
"github.com/containerd/containerd/testutil"
|
||||
"github.com/containerd/continuity/fs/fstest"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -13,12 +13,12 @@ import (
|
||||
|
||||
"github.com/Microsoft/hcsshim"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/fs"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/containerd/containerd/snapshots"
|
||||
"github.com/containerd/containerd/snapshots/storage"
|
||||
"github.com/containerd/continuity/fs"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
@ -30,7 +30,7 @@ github.com/pkg/errors v0.8.0
|
||||
github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448
|
||||
golang.org/x/sys 314a259e304ff91bd6985da2a7149bbf91237993 https://github.com/golang/sys
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/containerd/continuity cf279e6ac893682272b4479d4c67fd3abf878b4e
|
||||
github.com/containerd/continuity 1a794c0014a7b786879312d1dab309ba96ead8bc
|
||||
golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
|
||||
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
||||
|
15
vendor/github.com/containerd/continuity/devices/devices_darwin.go
generated
vendored
15
vendor/github.com/containerd/continuity/devices/devices_darwin.go
generated
vendored
@ -1,15 +0,0 @@
|
||||
package devices
|
||||
|
||||
// from /usr/include/sys/types.h
|
||||
|
||||
func getmajor(dev int32) uint64 {
|
||||
return (uint64(dev) >> 24) & 0xff
|
||||
}
|
||||
|
||||
func getminor(dev int32) uint64 {
|
||||
return uint64(dev) & 0xffffff
|
||||
}
|
||||
|
||||
func makedev(major int, minor int) int {
|
||||
return ((major << 24) | minor)
|
||||
}
|
23
vendor/github.com/containerd/continuity/devices/devices_dummy.go
generated
vendored
23
vendor/github.com/containerd/continuity/devices/devices_dummy.go
generated
vendored
@ -1,23 +0,0 @@
|
||||
// +build solaris,!cgo
|
||||
|
||||
//
|
||||
// Implementing the functions below requires cgo support. Non-cgo stubs
|
||||
// versions are defined below to enable cross-compilation of source code
|
||||
// that depends on these functions, but the resultant cross-compiled
|
||||
// binaries cannot actually be used. If the stub function(s) below are
|
||||
// actually invoked they will cause the calling process to exit.
|
||||
//
|
||||
|
||||
package devices
|
||||
|
||||
func getmajor(dev uint64) uint64 {
|
||||
panic("getmajor() support requires cgo.")
|
||||
}
|
||||
|
||||
func getminor(dev uint64) uint64 {
|
||||
panic("getminor() support requires cgo.")
|
||||
}
|
||||
|
||||
func makedev(major int, minor int) int {
|
||||
panic("makedev() support requires cgo.")
|
||||
}
|
15
vendor/github.com/containerd/continuity/devices/devices_freebsd.go
generated
vendored
15
vendor/github.com/containerd/continuity/devices/devices_freebsd.go
generated
vendored
@ -1,15 +0,0 @@
|
||||
package devices
|
||||
|
||||
// from /usr/include/sys/types.h
|
||||
|
||||
func getmajor(dev uint32) uint64 {
|
||||
return (uint64(dev) >> 24) & 0xff
|
||||
}
|
||||
|
||||
func getminor(dev uint32) uint64 {
|
||||
return uint64(dev) & 0xffffff
|
||||
}
|
||||
|
||||
func makedev(major int, minor int) int {
|
||||
return ((major << 24) | minor)
|
||||
}
|
15
vendor/github.com/containerd/continuity/devices/devices_linux.go
generated
vendored
15
vendor/github.com/containerd/continuity/devices/devices_linux.go
generated
vendored
@ -1,15 +0,0 @@
|
||||
package devices
|
||||
|
||||
// from /usr/include/linux/kdev_t.h
|
||||
|
||||
func getmajor(dev uint64) uint64 {
|
||||
return dev >> 8
|
||||
}
|
||||
|
||||
func getminor(dev uint64) uint64 {
|
||||
return dev & 0xff
|
||||
}
|
||||
|
||||
func makedev(major int, minor int) int {
|
||||
return ((major << 8) | minor)
|
||||
}
|
18
vendor/github.com/containerd/continuity/devices/devices_solaris.go
generated
vendored
18
vendor/github.com/containerd/continuity/devices/devices_solaris.go
generated
vendored
@ -1,18 +0,0 @@
|
||||
// +build cgo
|
||||
|
||||
package devices
|
||||
|
||||
//#include <sys/mkdev.h>
|
||||
import "C"
|
||||
|
||||
func getmajor(dev uint64) uint64 {
|
||||
return uint64(C.major(C.dev_t(dev)))
|
||||
}
|
||||
|
||||
func getminor(dev uint64) uint64 {
|
||||
return uint64(C.minor(C.dev_t(dev)))
|
||||
}
|
||||
|
||||
func makedev(major int, minor int) int {
|
||||
return int(C.makedev(C.major_t(major), C.minor_t(minor)))
|
||||
}
|
23
vendor/github.com/containerd/continuity/devices/devices_unix.go
generated
vendored
23
vendor/github.com/containerd/continuity/devices/devices_unix.go
generated
vendored
@ -6,6 +6,8 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func DeviceInfo(fi os.FileInfo) (uint64, uint64, error) {
|
||||
@ -14,42 +16,43 @@ func DeviceInfo(fi os.FileInfo) (uint64, uint64, error) {
|
||||
return 0, 0, fmt.Errorf("cannot extract device from os.FileInfo")
|
||||
}
|
||||
|
||||
return getmajor(sys.Rdev), getminor(sys.Rdev), nil
|
||||
dev := uint64(sys.Rdev)
|
||||
return uint64(unix.Major(dev)), uint64(unix.Minor(dev)), nil
|
||||
}
|
||||
|
||||
// mknod provides a shortcut for syscall.Mknod
|
||||
func Mknod(p string, mode os.FileMode, maj, min int) error {
|
||||
var (
|
||||
m = syscallMode(mode.Perm())
|
||||
dev int
|
||||
dev uint64
|
||||
)
|
||||
|
||||
if mode&os.ModeDevice != 0 {
|
||||
dev = makedev(maj, min)
|
||||
dev = unix.Mkdev(uint32(maj), uint32(min))
|
||||
|
||||
if mode&os.ModeCharDevice != 0 {
|
||||
m |= syscall.S_IFCHR
|
||||
m |= unix.S_IFCHR
|
||||
} else {
|
||||
m |= syscall.S_IFBLK
|
||||
m |= unix.S_IFBLK
|
||||
}
|
||||
} else if mode&os.ModeNamedPipe != 0 {
|
||||
m |= syscall.S_IFIFO
|
||||
m |= unix.S_IFIFO
|
||||
}
|
||||
|
||||
return syscall.Mknod(p, m, dev)
|
||||
return unix.Mknod(p, m, int(dev))
|
||||
}
|
||||
|
||||
// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
|
||||
func syscallMode(i os.FileMode) (o uint32) {
|
||||
o |= uint32(i.Perm())
|
||||
if i&os.ModeSetuid != 0 {
|
||||
o |= syscall.S_ISUID
|
||||
o |= unix.S_ISUID
|
||||
}
|
||||
if i&os.ModeSetgid != 0 {
|
||||
o |= syscall.S_ISGID
|
||||
o |= unix.S_ISGID
|
||||
}
|
||||
if i&os.ModeSticky != 0 {
|
||||
o |= syscall.S_ISVTX
|
||||
o |= unix.S_ISVTX
|
||||
}
|
||||
return
|
||||
}
|
||||
|
74
vendor/github.com/containerd/continuity/driver/utils.go
generated
vendored
Normal file
74
vendor/github.com/containerd/continuity/driver/utils.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
package driver
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// ReadFile works the same as ioutil.ReadFile with the Driver abstraction
|
||||
func ReadFile(r Driver, filename string) ([]byte, error) {
|
||||
f, err := r.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// WriteFile works the same as ioutil.WriteFile with the Driver abstraction
|
||||
func WriteFile(r Driver, filename string, data []byte, perm os.FileMode) error {
|
||||
f, err := r.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
n, err := f.Write(data)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if n != len(data) {
|
||||
return io.ErrShortWrite
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadDir works the same as ioutil.ReadDir with the Driver abstraction
|
||||
func ReadDir(r Driver, dirname string) ([]os.FileInfo, error) {
|
||||
f, err := r.Open(dirname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
dirs, err := f.Readdir(-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sort.Sort(fileInfos(dirs))
|
||||
return dirs, nil
|
||||
}
|
||||
|
||||
// Simple implementation of the sort.Interface for os.FileInfo
|
||||
type fileInfos []os.FileInfo
|
||||
|
||||
func (fis fileInfos) Len() int {
|
||||
return len(fis)
|
||||
}
|
||||
|
||||
func (fis fileInfos) Less(i, j int) bool {
|
||||
return fis[i].Name() < fis[j].Name()
|
||||
}
|
||||
|
||||
func (fis fileInfos) Swap(i, j int) {
|
||||
fis[i], fis[j] = fis[j], fis[i]
|
||||
}
|
0
fs/copy.go → vendor/github.com/containerd/continuity/fs/copy.go
generated
vendored
0
fs/copy.go → vendor/github.com/containerd/continuity/fs/copy.go
generated
vendored
3
fs/copy_linux.go → vendor/github.com/containerd/continuity/fs/copy_linux.go
generated
vendored
3
fs/copy_linux.go → vendor/github.com/containerd/continuity/fs/copy_linux.go
generated
vendored
@ -5,7 +5,6 @@ import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/containerd/containerd/sys"
|
||||
"github.com/containerd/continuity/sysx"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
@ -36,7 +35,7 @@ func copyFileInfo(fi os.FileInfo, name string) error {
|
||||
}
|
||||
}
|
||||
|
||||
timespec := []unix.Timespec{unix.Timespec(sys.StatAtime(st)), unix.Timespec(sys.StatMtime(st))}
|
||||
timespec := []unix.Timespec{unix.Timespec(StatAtime(st)), unix.Timespec(StatMtime(st))}
|
||||
if err := unix.UtimesNanoAt(unix.AT_FDCWD, name, timespec, unix.AT_SYMLINK_NOFOLLOW); err != nil {
|
||||
return errors.Wrapf(err, "failed to utime %s", name)
|
||||
}
|
3
fs/copy_unix.go → vendor/github.com/containerd/continuity/fs/copy_unix.go
generated
vendored
3
fs/copy_unix.go → vendor/github.com/containerd/continuity/fs/copy_unix.go
generated
vendored
@ -7,7 +7,6 @@ import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/containerd/containerd/sys"
|
||||
"github.com/containerd/continuity/sysx"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
@ -38,7 +37,7 @@ func copyFileInfo(fi os.FileInfo, name string) error {
|
||||
}
|
||||
}
|
||||
|
||||
timespec := []syscall.Timespec{sys.StatAtime(st), sys.StatMtime(st)}
|
||||
timespec := []syscall.Timespec{StatAtime(st), StatMtime(st)}
|
||||
if err := syscall.UtimesNano(name, timespec); err != nil {
|
||||
return errors.Wrapf(err, "failed to utime %s", name)
|
||||
}
|
0
fs/copy_windows.go → vendor/github.com/containerd/continuity/fs/copy_windows.go
generated
vendored
0
fs/copy_windows.go → vendor/github.com/containerd/continuity/fs/copy_windows.go
generated
vendored
0
fs/diff.go → vendor/github.com/containerd/continuity/fs/diff.go
generated
vendored
0
fs/diff.go → vendor/github.com/containerd/continuity/fs/diff.go
generated
vendored
0
fs/diff_unix.go → vendor/github.com/containerd/continuity/fs/diff_unix.go
generated
vendored
0
fs/diff_unix.go → vendor/github.com/containerd/continuity/fs/diff_unix.go
generated
vendored
0
fs/diff_windows.go → vendor/github.com/containerd/continuity/fs/diff_windows.go
generated
vendored
0
fs/diff_windows.go → vendor/github.com/containerd/continuity/fs/diff_windows.go
generated
vendored
0
fs/dtype_linux.go → vendor/github.com/containerd/continuity/fs/dtype_linux.go
generated
vendored
0
fs/dtype_linux.go → vendor/github.com/containerd/continuity/fs/dtype_linux.go
generated
vendored
0
fs/du.go → vendor/github.com/containerd/continuity/fs/du.go
generated
vendored
0
fs/du.go → vendor/github.com/containerd/continuity/fs/du.go
generated
vendored
0
fs/du_unix.go → vendor/github.com/containerd/continuity/fs/du_unix.go
generated
vendored
0
fs/du_unix.go → vendor/github.com/containerd/continuity/fs/du_unix.go
generated
vendored
0
fs/du_windows.go → vendor/github.com/containerd/continuity/fs/du_windows.go
generated
vendored
0
fs/du_windows.go → vendor/github.com/containerd/continuity/fs/du_windows.go
generated
vendored
0
fs/fstest/compare.go → vendor/github.com/containerd/continuity/fs/fstest/compare.go
generated
vendored
0
fs/fstest/compare.go → vendor/github.com/containerd/continuity/fs/fstest/compare.go
generated
vendored
0
fs/fstest/file.go → vendor/github.com/containerd/continuity/fs/fstest/file.go
generated
vendored
0
fs/fstest/file.go → vendor/github.com/containerd/continuity/fs/fstest/file.go
generated
vendored
@ -3,12 +3,12 @@ package fstest
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Lchtimes changes access and mod time of file without following symlink
|
||||
func Lchtimes(name string, atime, mtime time.Time) Applier {
|
||||
return applyFn(func(root string) error {
|
||||
return errdefs.ErrNotImplemented
|
||||
return errors.New("Not implemented")
|
||||
})
|
||||
}
|
0
fs/hardlink.go → vendor/github.com/containerd/continuity/fs/hardlink.go
generated
vendored
0
fs/hardlink.go → vendor/github.com/containerd/continuity/fs/hardlink.go
generated
vendored
0
fs/hardlink_unix.go → vendor/github.com/containerd/continuity/fs/hardlink_unix.go
generated
vendored
0
fs/hardlink_unix.go → vendor/github.com/containerd/continuity/fs/hardlink_unix.go
generated
vendored
0
fs/path.go → vendor/github.com/containerd/continuity/fs/path.go
generated
vendored
0
fs/path.go → vendor/github.com/containerd/continuity/fs/path.go
generated
vendored
28
vendor/github.com/containerd/continuity/fs/stat_bsd.go
generated
vendored
Normal file
28
vendor/github.com/containerd/continuity/fs/stat_bsd.go
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
// +build darwin freebsd
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// StatAtime returns the access time from a stat struct
|
||||
func StatAtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Atimespec
|
||||
}
|
||||
|
||||
// StatCtime returns the created time from a stat struct
|
||||
func StatCtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Ctimespec
|
||||
}
|
||||
|
||||
// StatMtime returns the modified time from a stat struct
|
||||
func StatMtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Mtimespec
|
||||
}
|
||||
|
||||
// StatATimeAsTime returns the access time as a time.Time
|
||||
func StatATimeAsTime(st *syscall.Stat_t) time.Time {
|
||||
return time.Unix(int64(st.Atimespec.Sec), int64(st.Atimespec.Nsec)) // nolint: unconvert
|
||||
}
|
26
vendor/github.com/containerd/continuity/fs/stat_linux.go
generated
vendored
Normal file
26
vendor/github.com/containerd/continuity/fs/stat_linux.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// StatAtime returns the Atim
|
||||
func StatAtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Atim
|
||||
}
|
||||
|
||||
// StatCtime returns the Ctim
|
||||
func StatCtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Ctim
|
||||
}
|
||||
|
||||
// StatMtime returns the Mtim
|
||||
func StatMtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Mtim
|
||||
}
|
||||
|
||||
// StatATimeAsTime returns st.Atim as a time.Time
|
||||
func StatATimeAsTime(st *syscall.Stat_t) time.Time {
|
||||
return time.Unix(st.Atim.Sec, st.Atim.Nsec)
|
||||
}
|
0
fs/time.go → vendor/github.com/containerd/continuity/fs/time.go
generated
vendored
0
fs/time.go → vendor/github.com/containerd/continuity/fs/time.go
generated
vendored
4
vendor/github.com/containerd/continuity/proto/manifest.pb.go
generated
vendored
4
vendor/github.com/containerd/continuity/proto/manifest.pb.go
generated
vendored
@ -82,9 +82,9 @@ type Resource struct {
|
||||
// Relative links do not start with a slash and are relative to the
|
||||
// resource path.
|
||||
Target string `protobuf:"bytes,9,opt,name=target" json:"target,omitempty"`
|
||||
// Major specifies the major device number for charactor and block devices.
|
||||
// Major specifies the major device number for character and block devices.
|
||||
Major uint64 `protobuf:"varint,10,opt,name=major" json:"major,omitempty"`
|
||||
// Minor specifies the minor device number for charactor and block devices.
|
||||
// Minor specifies the minor device number for character and block devices.
|
||||
Minor uint64 `protobuf:"varint,11,opt,name=minor" json:"minor,omitempty"`
|
||||
// Xattr provides storage for extended attributes for the target resource.
|
||||
Xattr []*XAttr `protobuf:"bytes,12,rep,name=xattr" json:"xattr,omitempty"`
|
||||
|
6
vendor/github.com/containerd/continuity/proto/manifest.proto
generated
vendored
6
vendor/github.com/containerd/continuity/proto/manifest.proto
generated
vendored
@ -16,7 +16,7 @@ message Resource {
|
||||
|
||||
// NOTE(stevvooe): Need to define clear precedence for user/group/uid/gid precedence.
|
||||
|
||||
// Uid specifies the user id for the resource.
|
||||
// Uid specifies the user id for the resource.
|
||||
int64 uid = 2;
|
||||
|
||||
// Gid specifies the group id for the resource.
|
||||
@ -53,10 +53,10 @@ message Resource {
|
||||
// resource path.
|
||||
string target = 9;
|
||||
|
||||
// Major specifies the major device number for charactor and block devices.
|
||||
// Major specifies the major device number for character and block devices.
|
||||
uint64 major = 10;
|
||||
|
||||
// Minor specifies the minor device number for charactor and block devices.
|
||||
// Minor specifies the minor device number for character and block devices.
|
||||
uint64 minor = 11;
|
||||
|
||||
// Xattr provides storage for extended attributes for the target resource.
|
||||
|
11
vendor/github.com/containerd/continuity/sysx/copy_linux.go
generated
vendored
11
vendor/github.com/containerd/continuity/sysx/copy_linux.go
generated
vendored
@ -1,11 +0,0 @@
|
||||
package sysx
|
||||
|
||||
// These functions will be generated by generate.sh
|
||||
// $ GOOS=linux GOARCH=386 ./generate.sh copy
|
||||
// $ GOOS=linux GOARCH=amd64 ./generate.sh copy
|
||||
// $ GOOS=linux GOARCH=arm ./generate.sh copy
|
||||
// $ GOOS=linux GOARCH=arm64 ./generate.sh copy
|
||||
// $ GOOS=linux GOARCH=ppc64le ./generate.sh copy
|
||||
// $ GOOS=linux GOARCH=s390x ./generate.sh copy
|
||||
|
||||
//sys CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error)
|
20
vendor/github.com/containerd/continuity/sysx/copy_linux_386.go
generated
vendored
20
vendor/github.com/containerd/continuity/sysx/copy_linux_386.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
// mksyscall.pl -l32 copy_linux.go
|
||||
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
|
||||
package sysx
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(SYS_COPY_FILE_RANGE, uintptr(fdin), uintptr(unsafe.Pointer(offin)), uintptr(fdout), uintptr(unsafe.Pointer(offout)), uintptr(len), uintptr(flags))
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
20
vendor/github.com/containerd/continuity/sysx/copy_linux_amd64.go
generated
vendored
20
vendor/github.com/containerd/continuity/sysx/copy_linux_amd64.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
// mksyscall.pl copy_linux.go
|
||||
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
|
||||
package sysx
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(SYS_COPY_FILE_RANGE, uintptr(fdin), uintptr(unsafe.Pointer(offin)), uintptr(fdout), uintptr(unsafe.Pointer(offout)), uintptr(len), uintptr(flags))
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
20
vendor/github.com/containerd/continuity/sysx/copy_linux_arm.go
generated
vendored
20
vendor/github.com/containerd/continuity/sysx/copy_linux_arm.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
// mksyscall.pl -l32 copy_linux.go
|
||||
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
|
||||
package sysx
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(SYS_COPY_FILE_RANGE, uintptr(fdin), uintptr(unsafe.Pointer(offin)), uintptr(fdout), uintptr(unsafe.Pointer(offout)), uintptr(len), uintptr(flags))
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
20
vendor/github.com/containerd/continuity/sysx/copy_linux_arm64.go
generated
vendored
20
vendor/github.com/containerd/continuity/sysx/copy_linux_arm64.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
// mksyscall.pl copy_linux.go
|
||||
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
|
||||
package sysx
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(SYS_COPY_FILE_RANGE, uintptr(fdin), uintptr(unsafe.Pointer(offin)), uintptr(fdout), uintptr(unsafe.Pointer(offout)), uintptr(len), uintptr(flags))
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
20
vendor/github.com/containerd/continuity/sysx/copy_linux_ppc64le.go
generated
vendored
20
vendor/github.com/containerd/continuity/sysx/copy_linux_ppc64le.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
// mksyscall.pl copy_linux.go
|
||||
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
|
||||
package sysx
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(SYS_COPY_FILE_RANGE, uintptr(fdin), uintptr(unsafe.Pointer(offin)), uintptr(fdout), uintptr(unsafe.Pointer(offout)), uintptr(len), uintptr(flags))
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
20
vendor/github.com/containerd/continuity/sysx/copy_linux_s390x.go
generated
vendored
20
vendor/github.com/containerd/continuity/sysx/copy_linux_s390x.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
// mksyscall.pl copy_linux.go
|
||||
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||
|
||||
package sysx
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(SYS_COPY_FILE_RANGE, uintptr(fdin), uintptr(unsafe.Pointer(offin)), uintptr(fdout), uintptr(unsafe.Pointer(offout)), uintptr(len), uintptr(flags))
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
7
vendor/github.com/containerd/continuity/sysx/sysnum_linux_386.go
generated
vendored
7
vendor/github.com/containerd/continuity/sysx/sysnum_linux_386.go
generated
vendored
@ -1,7 +0,0 @@
|
||||
package sysx
|
||||
|
||||
const (
|
||||
// SYS_COPYFILERANGE defined in Kernel 4.5+
|
||||
// Number defined in /usr/include/asm/unistd_32.h
|
||||
SYS_COPY_FILE_RANGE = 377
|
||||
)
|
7
vendor/github.com/containerd/continuity/sysx/sysnum_linux_amd64.go
generated
vendored
7
vendor/github.com/containerd/continuity/sysx/sysnum_linux_amd64.go
generated
vendored
@ -1,7 +0,0 @@
|
||||
package sysx
|
||||
|
||||
const (
|
||||
// SYS_COPYFILERANGE defined in Kernel 4.5+
|
||||
// Number defined in /usr/include/asm/unistd_64.h
|
||||
SYS_COPY_FILE_RANGE = 326
|
||||
)
|
7
vendor/github.com/containerd/continuity/sysx/sysnum_linux_arm.go
generated
vendored
7
vendor/github.com/containerd/continuity/sysx/sysnum_linux_arm.go
generated
vendored
@ -1,7 +0,0 @@
|
||||
package sysx
|
||||
|
||||
const (
|
||||
// SYS_COPY_FILE_RANGE defined in Kernel 4.5+
|
||||
// Number defined in /usr/include/arm-linux-gnueabihf/asm/unistd.h
|
||||
SYS_COPY_FILE_RANGE = 391
|
||||
)
|
7
vendor/github.com/containerd/continuity/sysx/sysnum_linux_arm64.go
generated
vendored
7
vendor/github.com/containerd/continuity/sysx/sysnum_linux_arm64.go
generated
vendored
@ -1,7 +0,0 @@
|
||||
package sysx
|
||||
|
||||
const (
|
||||
// SYS_COPY_FILE_RANGE defined in Kernel 4.5+
|
||||
// Number defined in /usr/include/asm-generic/unistd.h
|
||||
SYS_COPY_FILE_RANGE = 285
|
||||
)
|
7
vendor/github.com/containerd/continuity/sysx/sysnum_linux_ppc64le.go
generated
vendored
7
vendor/github.com/containerd/continuity/sysx/sysnum_linux_ppc64le.go
generated
vendored
@ -1,7 +0,0 @@
|
||||
package sysx
|
||||
|
||||
const (
|
||||
// SYS_COPYFILERANGE defined in Kernel 4.5+
|
||||
// Number defined in /usr/include/asm/unistd_64.h
|
||||
SYS_COPY_FILE_RANGE = 379
|
||||
)
|
7
vendor/github.com/containerd/continuity/sysx/sysnum_linux_s390x.go
generated
vendored
7
vendor/github.com/containerd/continuity/sysx/sysnum_linux_s390x.go
generated
vendored
@ -1,7 +0,0 @@
|
||||
package sysx
|
||||
|
||||
const (
|
||||
// SYS_COPYFILERANGE defined in Kernel 4.5+
|
||||
// Number defined in /usr/include/asm/unistd_64.h
|
||||
SYS_COPY_FILE_RANGE = 375
|
||||
)
|
13
vendor/github.com/containerd/continuity/vendor.conf
generated
vendored
Normal file
13
vendor/github.com/containerd/continuity/vendor.conf
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
bazil.org/fuse 371fbbdaa8987b715bdd21d6adc4c9b20155f748
|
||||
github.com/dustin/go-humanize bb3d318650d48840a39aa21a027c6630e198e626
|
||||
github.com/golang/protobuf 1e59b77b52bf8e4b449a57e6f79f21226d571845
|
||||
github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
|
||||
github.com/opencontainers/go-digest 279bed98673dd5bef374d3b6e4b09e2af76183bf
|
||||
github.com/pkg/errors f15c970de5b76fac0b59abb32d62c17cc7bed265
|
||||
github.com/sirupsen/logrus 89742aefa4b206dcf400792f3bd35b542998eb3b
|
||||
github.com/spf13/cobra 2da4a54c5ceefcee7ca5dd0eea1e18a3b6366489
|
||||
github.com/spf13/pflag 4c012f6dcd9546820e378d0bdda4d8fc772cdfea
|
||||
golang.org/x/crypto 9f005a07e0d31d45e6656d241bb5c0f2efd4bc94
|
||||
golang.org/x/net a337091b0525af65de94df2eb7e98bd9962dcbe2
|
||||
golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
|
||||
golang.org/x/sys 665f6529cca930e27b831a0d1dafffbe1c172924
|
Loading…
Reference in New Issue
Block a user