summaryrefslogtreecommitdiff
path: root/vendor/github.com/containers/storage/pkg
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2023-07-14 07:19:56 -0400
committerDaniel J Walsh <dwalsh@redhat.com>2023-07-14 07:19:56 -0400
commit13a9500166a83989c60e2155d767fc2100773ad2 (patch)
tree4c3cea2d3cbc7c6cedc8865f3aff35120fed5d19 /vendor/github.com/containers/storage/pkg
parentbb72016f58d4e99bdfafba0ae6c7af61ca28b3e6 (diff)
Update vendor containers/(common, buildah, image, storage)
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Diffstat (limited to 'vendor/github.com/containers/storage/pkg')
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/changes_other.go5
-rw-r--r--vendor/github.com/containers/storage/pkg/chunked/cache_linux.go40
-rw-r--r--vendor/github.com/containers/storage/pkg/chunked/storage_linux.go80
-rw-r--r--vendor/github.com/containers/storage/pkg/idmap/idmapped_utils.go83
-rw-r--r--vendor/github.com/containers/storage/pkg/system/stat_unix.go6
-rw-r--r--vendor/github.com/containers/storage/pkg/system/stat_windows.go4
6 files changed, 133 insertions, 85 deletions
diff --git a/vendor/github.com/containers/storage/pkg/archive/changes_other.go b/vendor/github.com/containers/storage/pkg/archive/changes_other.go
index c27930e97..ca272e68f 100644
--- a/vendor/github.com/containers/storage/pkg/archive/changes_other.go
+++ b/vendor/github.com/containers/storage/pkg/archive/changes_other.go
@@ -92,7 +92,10 @@ func collectFileInfo(sourceDir string, idMappings *idtools.IDMappings) (*FileInf
return err
}
- if s.Dev() != sourceStat.Dev() {
+ // Don't cross mount points. This ignores file mounts to avoid
+ // generating a diff which deletes all files following the
+ // mount.
+ if s.Dev() != sourceStat.Dev() && s.IsDir() {
return filepath.SkipDir
}
diff --git a/vendor/github.com/containers/storage/pkg/chunked/cache_linux.go b/vendor/github.com/containers/storage/pkg/chunked/cache_linux.go
index cd13212e6..56c30e267 100644
--- a/vendor/github.com/containers/storage/pkg/chunked/cache_linux.go
+++ b/vendor/github.com/containers/storage/pkg/chunked/cache_linux.go
@@ -15,6 +15,7 @@ import (
"unsafe"
storage "github.com/containers/storage"
+ graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/chunked/internal"
"github.com/containers/storage/pkg/ioutils"
jsoniter "github.com/json-iterator/go"
@@ -109,7 +110,7 @@ func (c *layersCache) load() error {
}
bigData, err := c.store.LayerBigData(r.ID, cacheKey)
- // if the cache areadly exists, read and use it
+ // if the cache already exists, read and use it
if err == nil {
defer bigData.Close()
metadata, err := readMetadataFromCache(bigData)
@@ -122,6 +123,23 @@ func (c *layersCache) load() error {
return err
}
+ var lcd chunkedLayerData
+
+ clFile, err := c.store.LayerBigData(r.ID, chunkedLayerDataKey)
+ if err != nil && !errors.Is(err, os.ErrNotExist) {
+ return err
+ }
+ if clFile != nil {
+ cl, err := io.ReadAll(clFile)
+ if err != nil {
+ return fmt.Errorf("open manifest file for layer %q: %w", r.ID, err)
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ if err := json.Unmarshal(cl, &lcd); err != nil {
+ return err
+ }
+ }
+
// otherwise create it from the layer TOC.
manifestReader, err := c.store.LayerBigData(r.ID, bigDataKey)
if err != nil {
@@ -134,7 +152,7 @@ func (c *layersCache) load() error {
return fmt.Errorf("open manifest file for layer %q: %w", r.ID, err)
}
- metadata, err := writeCache(manifest, r.ID, c.store)
+ metadata, err := writeCache(manifest, lcd.Format, r.ID, c.store)
if err == nil {
c.addLayer(r.ID, metadata)
}
@@ -211,13 +229,13 @@ type setBigData interface {
// - digest(file.payload))
// - digest(digest(file.payload) + file.UID + file.GID + file.mode + file.xattrs)
// - digest(i) for each i in chunks(file payload)
-func writeCache(manifest []byte, id string, dest setBigData) (*metadata, error) {
+func writeCache(manifest []byte, format graphdriver.DifferOutputFormat, id string, dest setBigData) (*metadata, error) {
var vdata bytes.Buffer
tagLen := 0
digestLen := 0
var tagsBuffer bytes.Buffer
- toc, err := prepareMetadata(manifest)
+ toc, err := prepareMetadata(manifest, format)
if err != nil {
return nil, err
}
@@ -396,7 +414,7 @@ func readMetadataFromCache(bigData io.Reader) (*metadata, error) {
}, nil
}
-func prepareMetadata(manifest []byte) ([]*internal.FileMetadata, error) {
+func prepareMetadata(manifest []byte, format graphdriver.DifferOutputFormat) ([]*internal.FileMetadata, error) {
toc, err := unmarshalToc(manifest)
if err != nil {
// ignore errors here. They might be caused by a different manifest format.
@@ -404,6 +422,17 @@ func prepareMetadata(manifest []byte) ([]*internal.FileMetadata, error) {
return nil, nil //nolint: nilnil
}
+ switch format {
+ case graphdriver.DifferOutputFormatDir:
+ case graphdriver.DifferOutputFormatFlat:
+ toc.Entries, err = makeEntriesFlat(toc.Entries)
+ if err != nil {
+ return nil, err
+ }
+ default:
+ return nil, fmt.Errorf("unknown format %q", format)
+ }
+
var r []*internal.FileMetadata
chunkSeen := make(map[string]bool)
for i := range toc.Entries {
@@ -420,6 +449,7 @@ func prepareMetadata(manifest []byte) ([]*internal.FileMetadata, error) {
chunkSeen[cd] = true
}
}
+
return r, nil
}
diff --git a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
index a80b28fb5..f13056082 100644
--- a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
+++ b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
@@ -28,6 +28,7 @@ import (
"github.com/containers/storage/pkg/system"
"github.com/containers/storage/types"
securejoin "github.com/cyphar/filepath-securejoin"
+ jsoniter "github.com/json-iterator/go"
"github.com/klauspost/compress/zstd"
"github.com/klauspost/pgzip"
digest "github.com/opencontainers/go-digest"
@@ -41,6 +42,8 @@ const (
newFileFlags = (unix.O_CREAT | unix.O_TRUNC | unix.O_EXCL | unix.O_WRONLY)
containersOverrideXattr = "user.containers.override_stat"
bigDataKey = "zstd-chunked-manifest"
+ chunkedData = "zstd-chunked-data"
+ chunkedLayerDataKey = "zstd-chunked-layer-data"
fileTypeZstdChunked = iota
fileTypeEstargz
@@ -73,6 +76,11 @@ var xattrsToIgnore = map[string]interface{}{
"security.selinux": true,
}
+// chunkedLayerData is used to store additional information about the layer
+type chunkedLayerData struct {
+ Format graphdriver.DifferOutputFormat `json:"format"`
+}
+
func timeToTimespec(time *time.Time) (ts unix.Timespec) {
if time == nil || time.IsZero() {
// Return UTIME_OMIT special value
@@ -241,7 +249,7 @@ func copyFileFromOtherLayer(file *internal.FileMetadata, source string, name str
srcFile, err := openFileUnderRoot(name, srcDirfd, unix.O_RDONLY, 0)
if err != nil {
- return false, nil, 0, fmt.Errorf("open source file under target rootfs: %w", err)
+ return false, nil, 0, fmt.Errorf("open source file under target rootfs (%s): %w", name, err)
}
defer srcFile.Close()
@@ -844,7 +852,14 @@ func openDestinationFile(dirfd int, metadata *internal.FileMetadata, options *ar
}, nil
}
-func (d *destinationFile) Close() error {
+func (d *destinationFile) Close() (Err error) {
+ defer func() {
+ err := d.file.Close()
+ if Err == nil {
+ Err = err
+ }
+ }()
+
manifestChecksum, err := digest.Parse(d.metadata.Digest)
if err != nil {
return err
@@ -1317,7 +1332,39 @@ func (c *chunkedDiffer) findAndCopyFile(dirfd int, r *internal.FileMetadata, cop
return false, nil
}
-func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (graphdriver.DriverWithDifferOutput, error) {
+func makeEntriesFlat(mergedEntries []internal.FileMetadata) ([]internal.FileMetadata, error) {
+ var new []internal.FileMetadata
+
+ hashes := make(map[string]string)
+ for i := range mergedEntries {
+ if mergedEntries[i].Type != TypeReg {
+ continue
+ }
+ if mergedEntries[i].Digest == "" {
+ if mergedEntries[i].Size != 0 {
+ return nil, fmt.Errorf("missing digest for %q", mergedEntries[i].Name)
+ }
+ continue
+ }
+ digest, err := digest.Parse(mergedEntries[i].Digest)
+ if err != nil {
+ return nil, err
+ }
+ d := digest.Encoded()
+
+ if hashes[d] != "" {
+ continue
+ }
+ hashes[d] = d
+
+ mergedEntries[i].Name = fmt.Sprintf("%s/%s", d[0:2], d[2:])
+
+ new = append(new, mergedEntries[i])
+ }
+ return new, nil
+}
+
+func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions, differOpts *graphdriver.DifferOptions) (graphdriver.DriverWithDifferOutput, error) {
defer c.layersCache.release()
defer func() {
if c.zstdReader != nil {
@@ -1325,11 +1372,21 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
}
}()
+ lcd := chunkedLayerData{
+ Format: differOpts.Format,
+ }
+
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ lcdBigData, err := json.Marshal(lcd)
+ if err != nil {
+ return graphdriver.DriverWithDifferOutput{}, err
+ }
output := graphdriver.DriverWithDifferOutput{
Differ: c,
TarSplit: c.tarSplit,
BigData: map[string][]byte{
- bigDataKey: c.manifest,
+ bigDataKey: c.manifest,
+ chunkedLayerDataKey: lcdBigData,
},
TOCDigest: c.tocDigest,
}
@@ -1389,6 +1446,21 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
}
defer unix.Close(dirfd)
+ if differOpts != nil && differOpts.Format == graphdriver.DifferOutputFormatFlat {
+ mergedEntries, err = makeEntriesFlat(mergedEntries)
+ if err != nil {
+ return output, err
+ }
+ createdDirs := make(map[string]struct{})
+ for _, e := range mergedEntries {
+ d := e.Name[0:2]
+ if _, found := createdDirs[d]; !found {
+ unix.Mkdirat(dirfd, d, 0o755)
+ createdDirs[d] = struct{}{}
+ }
+ }
+ }
+
// hardlinks can point to missing files. So create them after all files
// are retrieved
var hardLinks []hardLinkToCreate
diff --git a/vendor/github.com/containers/storage/pkg/idmap/idmapped_utils.go b/vendor/github.com/containers/storage/pkg/idmap/idmapped_utils.go
index 68c8c867d..87484d95b 100644
--- a/vendor/github.com/containers/storage/pkg/idmap/idmapped_utils.go
+++ b/vendor/github.com/containers/storage/pkg/idmap/idmapped_utils.go
@@ -8,75 +8,11 @@ import (
"os"
"runtime"
"syscall"
- "unsafe"
"github.com/containers/storage/pkg/idtools"
"golang.org/x/sys/unix"
)
-type attr struct {
- attrSet uint64
- attrClr uint64
- propagation uint64
- userNs uint64
-}
-
-// openTree is a wrapper for the open_tree syscall
-func openTree(path string, flags int) (fd int, err error) {
- var _p0 *byte
-
- if _p0, err = syscall.BytePtrFromString(path); err != nil {
- return 0, err
- }
-
- r, _, e1 := syscall.Syscall6(uintptr(unix.SYS_OPEN_TREE), uintptr(0), uintptr(unsafe.Pointer(_p0)),
- uintptr(flags), 0, 0, 0)
- if e1 != 0 {
- err = e1
- }
- return int(r), err
-}
-
-// moveMount is a wrapper for the move_mount syscall.
-func moveMount(fdTree int, target string) (err error) {
- var _p0, _p1 *byte
-
- empty := ""
-
- if _p0, err = syscall.BytePtrFromString(target); err != nil {
- return err
- }
- if _p1, err = syscall.BytePtrFromString(empty); err != nil {
- return err
- }
-
- flags := unix.MOVE_MOUNT_F_EMPTY_PATH
-
- _, _, e1 := syscall.Syscall6(uintptr(unix.SYS_MOVE_MOUNT),
- uintptr(fdTree), uintptr(unsafe.Pointer(_p1)),
- 0, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
- if e1 != 0 {
- err = e1
- }
- return
-}
-
-// mountSetAttr is a wrapper for the mount_setattr syscall
-func mountSetAttr(dfd int, path string, flags uint, attr *attr, size uint) (err error) {
- var _p0 *byte
-
- if _p0, err = syscall.BytePtrFromString(path); err != nil {
- return err
- }
-
- _, _, e1 := syscall.Syscall6(uintptr(unix.SYS_MOUNT_SETATTR), uintptr(dfd), uintptr(unsafe.Pointer(_p0)),
- uintptr(flags), uintptr(unsafe.Pointer(attr)), uintptr(size), 0)
- if e1 != 0 {
- err = e1
- }
- return
-}
-
// CreateIDMappedMount creates a IDMapped bind mount from SOURCE to TARGET using the user namespace
// for the PID process.
func CreateIDMappedMount(source, target string, pid int) error {
@@ -85,29 +21,26 @@ func CreateIDMappedMount(source, target string, pid int) error {
if err != nil {
return fmt.Errorf("unable to get user ns file descriptor for %q: %w", path, err)
}
-
- var attr attr
- attr.attrSet = unix.MOUNT_ATTR_IDMAP
- attr.attrClr = 0
- attr.propagation = 0
- attr.userNs = uint64(userNsFile.Fd())
-
defer userNsFile.Close()
- targetDirFd, err := openTree(source, unix.OPEN_TREE_CLONE)
+ targetDirFd, err := unix.OpenTree(0, source, unix.OPEN_TREE_CLONE)
if err != nil {
return err
}
defer unix.Close(targetDirFd)
- if err := mountSetAttr(targetDirFd, "", unix.AT_EMPTY_PATH|unix.AT_RECURSIVE,
- &attr, uint(unsafe.Sizeof(attr))); err != nil {
+ if err := unix.MountSetattr(targetDirFd, "", unix.AT_EMPTY_PATH|unix.AT_RECURSIVE,
+ &unix.MountAttr{
+ Attr_set: unix.MOUNT_ATTR_IDMAP,
+ Userns_fd: uint64(userNsFile.Fd()),
+ }); err != nil {
return err
}
if err := os.Mkdir(target, 0o700); err != nil && !os.IsExist(err) {
return err
}
- return moveMount(targetDirFd, target)
+
+ return unix.MoveMount(targetDirFd, "", 0, target, unix.MOVE_MOUNT_F_EMPTY_PATH)
}
// CreateUsernsProcess forks the current process and creates a user namespace using the specified
diff --git a/vendor/github.com/containers/storage/pkg/system/stat_unix.go b/vendor/github.com/containers/storage/pkg/system/stat_unix.go
index 47ae899f8..e552e91d7 100644
--- a/vendor/github.com/containers/storage/pkg/system/stat_unix.go
+++ b/vendor/github.com/containers/storage/pkg/system/stat_unix.go
@@ -7,6 +7,8 @@ import (
"os"
"strconv"
"syscall"
+
+ "golang.org/x/sys/unix"
)
// StatT type contains status of a file. It contains metadata
@@ -57,6 +59,10 @@ func (s StatT) Dev() uint64 {
return s.dev
}
+func (s StatT) IsDir() bool {
+ return (s.mode & unix.S_IFDIR) != 0
+}
+
// Stat takes a path to a file and returns
// a system.StatT type pertaining to that file.
//
diff --git a/vendor/github.com/containers/storage/pkg/system/stat_windows.go b/vendor/github.com/containers/storage/pkg/system/stat_windows.go
index 6d5c6c142..828be2088 100644
--- a/vendor/github.com/containers/storage/pkg/system/stat_windows.go
+++ b/vendor/github.com/containers/storage/pkg/system/stat_windows.go
@@ -48,6 +48,10 @@ func (s StatT) Dev() uint64 {
return 0
}
+func (s StatT) IsDir() bool {
+ return s.Mode().IsDir()
+}
+
// Stat takes a path to a file and returns
// a system.StatT type pertaining to that file.
//