vendor: update buildkit to master@c36941f4a10e

Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
Justin Chadwell
2023-05-30 09:10:52 +01:00
parent 17bdbbd3c3
commit 6c62225d1b
141 changed files with 1402 additions and 1161 deletions

View File

@ -1,7 +1,5 @@
linters:
enable:
- structcheck
- varcheck
- staticcheck
- unconvert
- gofmt

View File

@ -18,6 +18,7 @@ package continuity
import (
"bytes"
"errors"
"fmt"
"io"
"os"
@ -151,7 +152,7 @@ func (c *context) Resource(p string, fi os.FileInfo) (Resource, error) {
}
base.xattrs, err = c.resolveXAttrs(fp, fi, base)
if err != nil && err != ErrNotSupported {
if err != nil && !errors.Is(err, ErrNotSupported) {
return nil, err
}
@ -410,7 +411,7 @@ func (c *context) Apply(resource Resource) error {
return fmt.Errorf("resource %v escapes root", resource)
}
var chmod = true
chmod := true
fi, err := c.driver.Lstat(fp)
if err != nil {
if !os.IsNotExist(err) {

View File

@ -56,7 +56,7 @@ func WriteFile(r Driver, filename string, data []byte, perm os.FileMode) error {
return nil
}
// ReadDir works the same as ioutil.ReadDir with the Driver abstraction
// ReadDir works the same as os.ReadDir with the Driver abstraction
func ReadDir(r Driver, dirname string) ([]os.FileInfo, error) {
f, err := r.Open(dirname)
if err != nil {

View File

@ -18,7 +18,6 @@ package fs
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sync"
@ -111,7 +110,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
}
}
fis, err := ioutil.ReadDir(src)
entries, err := os.ReadDir(src)
if err != nil {
return fmt.Errorf("failed to read %s: %w", src, err)
}
@ -124,18 +123,23 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
return fmt.Errorf("failed to copy xattrs: %w", err)
}
for _, fi := range fis {
source := filepath.Join(src, fi.Name())
target := filepath.Join(dst, fi.Name())
for _, entry := range entries {
source := filepath.Join(src, entry.Name())
target := filepath.Join(dst, entry.Name())
fileInfo, err := entry.Info()
if err != nil {
return fmt.Errorf("failed to get file info for %s: %w", entry.Name(), err)
}
switch {
case fi.IsDir():
case entry.IsDir():
if err := copyDirectory(target, source, inodes, o); err != nil {
return err
}
continue
case (fi.Mode() & os.ModeType) == 0:
link, err := getLinkSource(target, fi, inodes)
case (fileInfo.Mode() & os.ModeType) == 0:
link, err := getLinkSource(target, fileInfo, inodes)
if err != nil {
return fmt.Errorf("failed to get hardlink: %w", err)
}
@ -146,7 +150,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
} else if err := CopyFile(target, source); err != nil {
return fmt.Errorf("failed to copy files: %w", err)
}
case (fi.Mode() & os.ModeSymlink) == os.ModeSymlink:
case (fileInfo.Mode() & os.ModeSymlink) == os.ModeSymlink:
link, err := os.Readlink(source)
if err != nil {
return fmt.Errorf("failed to read link: %s: %w", source, err)
@ -154,18 +158,18 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
if err := os.Symlink(link, target); err != nil {
return fmt.Errorf("failed to create symlink: %s: %w", target, err)
}
case (fi.Mode() & os.ModeDevice) == os.ModeDevice,
(fi.Mode() & os.ModeNamedPipe) == os.ModeNamedPipe,
(fi.Mode() & os.ModeSocket) == os.ModeSocket:
if err := copyIrregular(target, fi); err != nil {
case (fileInfo.Mode() & os.ModeDevice) == os.ModeDevice,
(fileInfo.Mode() & os.ModeNamedPipe) == os.ModeNamedPipe,
(fileInfo.Mode() & os.ModeSocket) == os.ModeSocket:
if err := copyIrregular(target, fileInfo); err != nil {
return fmt.Errorf("failed to create irregular file: %w", err)
}
default:
logrus.Warnf("unsupported mode: %s: %s", source, fi.Mode())
logrus.Warnf("unsupported mode: %s: %s", source, fileInfo.Mode())
continue
}
if err := copyFileInfo(fi, source, target); err != nil {
if err := copyFileInfo(fileInfo, source, target); err != nil {
return fmt.Errorf("failed to copy file info: %w", err)
}
@ -180,6 +184,10 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
// CopyFile copies the source file to the target.
// The most efficient means of copying is used for the platform.
func CopyFile(target, source string) error {
return copyFile(target, source)
}
func openAndCopyFile(target, source string) error {
src, err := os.Open(source)
if err != nil {
return fmt.Errorf("failed to open source %s: %w", source, err)

View File

@ -0,0 +1,35 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package fs
import (
"errors"
"fmt"
"golang.org/x/sys/unix"
)
func copyFile(target, source string) error {
if err := unix.Clonefile(source, target, unix.CLONE_NOFOLLOW); err != nil {
if !errors.Is(err, unix.ENOTSUP) && !errors.Is(err, unix.EXDEV) {
return fmt.Errorf("clonefile failed: %w", err)
}
return openAndCopyFile(target, source)
}
return nil
}

View File

@ -0,0 +1,22 @@
//go:build !darwin
// +build !darwin
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package fs
var copyFile = openAndCopyFile

View File

@ -23,6 +23,7 @@ import (
"fmt"
"io"
"os"
"runtime"
"syscall"
"github.com/containerd/continuity/sysx"
@ -71,6 +72,10 @@ func copyFileContent(dst, src *os.File) error {
func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAttrErrorHandler) error {
xattrKeys, err := sysx.LListxattr(src)
if err != nil {
if os.IsPermission(err) && runtime.GOOS == "darwin" {
// On darwin, character devices do not permit listing xattrs
return nil
}
e := fmt.Errorf("failed to list xattrs on %s: %w", src, err)
if errorHandler != nil {
e = errorHandler(dst, src, "", e)

View File

@ -49,7 +49,6 @@ func copyFileInfo(fi os.FileInfo, src, name string) error {
secInfo, err := windows.GetNamedSecurityInfo(
src, windows.SE_FILE_OBJECT,
windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION)
if err != nil {
return err
}
@ -68,7 +67,6 @@ func copyFileInfo(fi os.FileInfo, src, name string) error {
name, windows.SE_FILE_OBJECT,
windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION,
sid, nil, dacl, nil); err != nil {
return err
}
return nil

View File

@ -80,12 +80,13 @@ type ChangeFunc func(ChangeKind, string, os.FileInfo, error) error
//
// The change callback is called by the order of path names and
// should be appliable in that order.
// Due to this apply ordering, the following is true
// - Removed directory trees only create a single change for the root
// directory removed. Remaining changes are implied.
// - A directory which is modified to become a file will not have
// delete entries for sub-path items, their removal is implied
// by the removal of the parent directory.
//
// Due to this apply ordering, the following is true
// - Removed directory trees only create a single change for the root
// directory removed. Remaining changes are implied.
// - A directory which is modified to become a file will not have
// delete entries for sub-path items, their removal is implied
// by the removal of the parent directory.
//
// Opaque directories will not be treated specially and each file
// removed from the base directory will show up as a removal.

View File

@ -21,14 +21,13 @@ package fs
import (
"fmt"
"io/ioutil"
"os"
"syscall"
"unsafe"
)
func locateDummyIfEmpty(path string) (string, error) {
children, err := ioutil.ReadDir(path)
children, err := os.ReadDir(path)
if err != nil {
return "", err
}

View File

@ -28,10 +28,11 @@ import (
// blocksUnitSize is the unit used by `st_blocks` in `stat` in bytes.
// See https://man7.org/linux/man-pages/man2/stat.2.html
// st_blocks
// This field indicates the number of blocks allocated to the
// file, in 512-byte units. (This may be smaller than
// st_size/512 when the file has holes.)
//
// st_blocks
// This field indicates the number of blocks allocated to the
// file, in 512-byte units. (This may be smaller than
// st_size/512 when the file has holes.)
const blocksUnitSize = 512
type inode struct {
@ -48,7 +49,6 @@ func newInode(stat *syscall.Stat_t) inode {
}
func diskUsage(ctx context.Context, roots ...string) (Usage, error) {
var (
size int64
inodes = map[inode]struct{}{} // expensive!

View File

@ -26,9 +26,7 @@ import (
)
func diskUsage(ctx context.Context, roots ...string) (Usage, error) {
var (
size int64
)
var size int64
// TODO(stevvooe): Support inodes (or equivalent) for windows.
@ -57,9 +55,7 @@ func diskUsage(ctx context.Context, roots ...string) (Usage, error) {
}
func diffUsage(ctx context.Context, a, b string) (Usage, error) {
var (
size int64
)
var size int64
if err := Changes(ctx, a, b, func(kind ChangeKind, _ string, fi os.FileInfo, err error) error {
if err != nil {

View File

@ -16,9 +16,22 @@
package fstest
// 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{
"\\System Volume Information": true,
"\\WcSandboxState": true,
"\\System Volume Information": true,
"\\WcSandboxState": true,
"\\WcSandboxState\\Hives": true,
"\\WcSandboxState\\Hives\\DefaultUser_Delta": true,
"\\WcSandboxState\\Hives\\Sam_Delta": true,
"\\WcSandboxState\\Hives\\Security_Delta": true,
"\\WcSandboxState\\Hives\\Software_Delta": true,
"\\WcSandboxState\\Hives\\System_Delta": true,
"\\WcSandboxState\\initialized": true,
"\\Windows": true,
"\\Windows\\System32": true,
"\\Windows\\System32\\config": true,
"\\Windows\\System32\\config\\DEFAULT": true,
"\\Windows\\System32\\config\\SAM": true,
"\\Windows\\System32\\config\\SECURITY": true,
"\\Windows\\System32\\config\\SOFTWARE": true,
"\\Windows\\System32\\config\\SYSTEM": true,
}

View File

@ -129,7 +129,6 @@ func compareResource(r1, r2 continuity.Resource) bool {
// TODO(dmcgowan): Check if is XAttrer
return compareResourceTypes(r1, r2)
}
func compareResourceTypes(r1, r2 continuity.Resource) bool {

View File

@ -32,13 +32,13 @@ func Lchtimes(name string, atime, mtime time.Time) Applier {
// that the filter will mount. It is used for testing the snapshotter
func Base() Applier {
return Apply(
CreateDir("Windows", 0755),
CreateDir("Windows/System32", 0755),
CreateDir("Windows/System32/Config", 0755),
CreateFile("Windows/System32/Config/SYSTEM", []byte("foo\n"), 0777),
CreateFile("Windows/System32/Config/SOFTWARE", []byte("foo\n"), 0777),
CreateFile("Windows/System32/Config/SAM", []byte("foo\n"), 0777),
CreateFile("Windows/System32/Config/SECURITY", []byte("foo\n"), 0777),
CreateFile("Windows/System32/Config/DEFAULT", []byte("foo\n"), 0777),
CreateDir("Windows", 0o755),
CreateDir("Windows/System32", 0o755),
CreateDir("Windows/System32/Config", 0o755),
CreateFile("Windows/System32/Config/SYSTEM", []byte("foo\n"), 0o777),
CreateFile("Windows/System32/Config/SOFTWARE", []byte("foo\n"), 0o777),
CreateFile("Windows/System32/Config/SAM", []byte("foo\n"), 0o777),
CreateFile("Windows/System32/Config/SECURITY", []byte("foo\n"), 0o777),
CreateFile("Windows/System32/Config/DEFAULT", []byte("foo\n"), 0o777),
)
}

View File

@ -81,14 +81,14 @@ var (
// baseApplier creates a basic filesystem layout
// with multiple types of files for basic tests.
baseApplier = Apply(
CreateDir("/etc/", 0755),
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost"), 0644),
CreateDir("/etc/", 0o755),
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost"), 0o644),
Link("/etc/hosts", "/etc/hosts.allow"),
CreateDir("/usr/local/lib", 0755),
CreateFile("/usr/local/lib/libnothing.so", []byte{0x00, 0x00}, 0755),
CreateDir("/usr/local/lib", 0o755),
CreateFile("/usr/local/lib/libnothing.so", []byte{0x00, 0x00}, 0o755),
Symlink("libnothing.so", "/usr/local/lib/libnothing.so.2"),
CreateDir("/home", 0755),
CreateDir("/home/derek", 0700),
CreateDir("/home", 0o755),
CreateDir("/home/derek", 0o700),
// TODO: CreateSocket: how should Sockets be handled in continuity?
)
@ -96,10 +96,10 @@ var (
basicTest = []Applier{
baseApplier,
Apply(
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0644),
CreateFile("/etc/fstab", []byte("/dev/sda1\t/\text4\tdefaults 1 1\n"), 0600),
CreateFile("/etc/badfile", []byte(""), 0666),
CreateFile("/home/derek/.zshrc", []byte("#ZSH is just better\n"), 0640),
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0o644),
CreateFile("/etc/fstab", []byte("/dev/sda1\t/\text4\tdefaults 1 1\n"), 0o600),
CreateFile("/etc/badfile", []byte(""), 0o666),
CreateFile("/home/derek/.zshrc", []byte("#ZSH is just better\n"), 0o640),
),
Apply(
Remove("/etc/badfile"),
@ -111,8 +111,8 @@ var (
),
Apply(
RemoveAll("/home"),
CreateDir("/home/derek", 0700),
CreateFile("/home/derek/.bashrc", []byte("#not going away\n"), 0640),
CreateDir("/home/derek", 0o700),
CreateFile("/home/derek/.bashrc", []byte("#not going away\n"), 0o640),
Link("/etc/hosts", "/etc/hosts.allow"),
),
}
@ -121,58 +121,58 @@ var (
// deletions are properly picked up and applied
deletionTest = []Applier{
Apply(
CreateDir("/test/somedir", 0755),
CreateDir("/lib", 0700),
CreateFile("/lib/hidden", []byte{}, 0644),
CreateDir("/test/somedir", 0o755),
CreateDir("/lib", 0o700),
CreateFile("/lib/hidden", []byte{}, 0o644),
),
Apply(
CreateFile("/test/a", []byte{}, 0644),
CreateFile("/test/b", []byte{}, 0644),
CreateDir("/test/otherdir", 0755),
CreateFile("/test/otherdir/.empty", []byte{}, 0644),
CreateFile("/test/a", []byte{}, 0o644),
CreateFile("/test/b", []byte{}, 0o644),
CreateDir("/test/otherdir", 0o755),
CreateFile("/test/otherdir/.empty", []byte{}, 0o644),
RemoveAll("/lib"),
CreateDir("/lib", 0700),
CreateFile("/lib/not-hidden", []byte{}, 0644),
CreateDir("/lib", 0o700),
CreateFile("/lib/not-hidden", []byte{}, 0o644),
),
Apply(
Remove("/test/a"),
Remove("/test/b"),
RemoveAll("/test/otherdir"),
CreateFile("/lib/newfile", []byte{}, 0644),
CreateFile("/lib/newfile", []byte{}, 0o644),
),
}
// updateTest covers file updates for content and permission
updateTest = []Applier{
Apply(
CreateDir("/d1", 0755),
CreateDir("/d2", 0700),
CreateFile("/d1/f1", []byte("something..."), 0644),
CreateFile("/d1/f2", []byte("else..."), 0644),
CreateFile("/d1/f3", []byte("entirely..."), 0644),
CreateDir("/d1", 0o755),
CreateDir("/d2", 0o700),
CreateFile("/d1/f1", []byte("something..."), 0o644),
CreateFile("/d1/f2", []byte("else..."), 0o644),
CreateFile("/d1/f3", []byte("entirely..."), 0o644),
),
Apply(
CreateFile("/d1/f1", []byte("file content of a different length"), 0664),
CreateFile("/d1/f1", []byte("file content of a different length"), 0o664),
Remove("/d1/f3"),
CreateFile("/d1/f3", []byte("updated content"), 0664),
Chmod("/d1/f2", 0766),
Chmod("/d2", 0777),
CreateFile("/d1/f3", []byte("updated content"), 0o664),
Chmod("/d1/f2", 0o766),
Chmod("/d2", 0o777),
),
}
// directoryPermissionsTest covers directory permissions on update
directoryPermissionsTest = []Applier{
Apply(
CreateDir("/d1", 0700),
CreateDir("/d2", 0751),
CreateDir("/d3", 0777),
CreateDir("/d1", 0o700),
CreateDir("/d2", 0o751),
CreateDir("/d3", 0o777),
),
Apply(
CreateFile("/d1/f", []byte("irrelevant"), 0644),
CreateDir("/d1/d", 0700),
CreateFile("/d1/d/f", []byte("irrelevant"), 0644),
CreateFile("/d2/f", []byte("irrelevant"), 0644),
CreateFile("/d3/f", []byte("irrelevant"), 0644),
CreateFile("/d1/f", []byte("irrelevant"), 0o644),
CreateDir("/d1/d", 0o700),
CreateFile("/d1/d/f", []byte("irrelevant"), 0o644),
CreateFile("/d2/f", []byte("irrelevant"), 0o644),
CreateFile("/d3/f", []byte("irrelevant"), 0o644),
),
}
@ -180,28 +180,28 @@ var (
// files
parentDirectoryPermissionsTest = []Applier{
Apply(
CreateDir("/d1", 0700),
CreateDir("/d1/a", 0700),
CreateDir("/d1/a/b", 0700),
CreateDir("/d1/a/b/c", 0700),
CreateFile("/d1/a/b/f", []byte("content1"), 0644),
CreateDir("/d2", 0751),
CreateDir("/d2/a/b", 0751),
CreateDir("/d2/a/b/c", 0751),
CreateFile("/d2/a/b/f", []byte("content1"), 0644),
CreateDir("/d1", 0o700),
CreateDir("/d1/a", 0o700),
CreateDir("/d1/a/b", 0o700),
CreateDir("/d1/a/b/c", 0o700),
CreateFile("/d1/a/b/f", []byte("content1"), 0o644),
CreateDir("/d2", 0o751),
CreateDir("/d2/a/b", 0o751),
CreateDir("/d2/a/b/c", 0o751),
CreateFile("/d2/a/b/f", []byte("content1"), 0o644),
),
Apply(
CreateFile("/d1/a/b/f", []byte("content1"), 0644),
Chmod("/d1/a/b/c", 0700),
CreateFile("/d2/a/b/f", []byte("content2"), 0644),
Chmod("/d2/a/b/c", 0751),
CreateFile("/d1/a/b/f", []byte("content1"), 0o644),
Chmod("/d1/a/b/c", 0o700),
CreateFile("/d2/a/b/f", []byte("content2"), 0o644),
Chmod("/d2/a/b/c", 0o751),
),
}
hardlinkUnmodified = []Applier{
baseApplier,
Apply(
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0644),
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0o644),
),
Apply(
Link("/etc/hosts", "/etc/hosts.deny"),
@ -213,7 +213,7 @@ var (
hardlinkBeforeUnmodified = []Applier{
baseApplier,
Apply(
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0644),
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0o644),
),
Apply(
Link("/etc/hosts", "/etc/before-hosts"),
@ -225,11 +225,11 @@ var (
hardlinkBeforeModified = []Applier{
baseApplier,
Apply(
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0644),
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0o644),
),
Apply(
Remove("/etc/hosts"),
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost"), 0644),
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost"), 0o644),
Link("/etc/hosts", "/etc/before-hosts"),
),
}

View File

@ -25,9 +25,7 @@ import (
"path/filepath"
)
var (
errTooManyLinks = errors.New("too many links")
)
var errTooManyLinks = errors.New("too many links")
type currentPath struct {
path string

View File

@ -21,9 +21,7 @@ import (
"os"
)
var (
errNotAHardLink = fmt.Errorf("invalid hardlink")
)
var errNotAHardLink = fmt.Errorf("invalid hardlink")
type hardlinkManager struct {
hardlinks map[hardlinkKey][]Resource

View File

@ -37,26 +37,32 @@ func atomicWriteFile(filename string, r io.Reader, dataSize int64, perm os.FileM
if err != nil {
return err
}
needClose := true
defer func() {
if needClose {
f.Close()
}
}()
err = os.Chmod(f.Name(), perm)
if err != nil {
f.Close()
return err
}
n, err := io.Copy(f, r)
if err == nil && n < dataSize {
f.Close()
return io.ErrShortWrite
}
if err != nil {
f.Close()
return err
}
if err := f.Sync(); err != nil {
f.Close()
if err = f.Sync(); err != nil {
return err
}
needClose = false
if err := f.Close(); err != nil {
return err
}
return os.Rename(f.Name(), filename)
}