mirror of
https://github.com/containers/podman.git
synced 2025-09-29 01:35:06 +08:00
2
go.mod
2
go.mod
@ -17,7 +17,7 @@ require (
|
|||||||
github.com/containers/image/v5 v5.17.1-0.20211129144953-4f6d0b45be6c
|
github.com/containers/image/v5 v5.17.1-0.20211129144953-4f6d0b45be6c
|
||||||
github.com/containers/ocicrypt v1.1.2
|
github.com/containers/ocicrypt v1.1.2
|
||||||
github.com/containers/psgo v1.7.1
|
github.com/containers/psgo v1.7.1
|
||||||
github.com/containers/storage v1.37.1-0.20211122214631-59ba58582415
|
github.com/containers/storage v1.37.1-0.20211130181259-1a158c89a518
|
||||||
github.com/coreos/go-systemd/v22 v22.3.2
|
github.com/coreos/go-systemd/v22 v22.3.2
|
||||||
github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3
|
github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3
|
||||||
github.com/cyphar/filepath-securejoin v0.2.3
|
github.com/cyphar/filepath-securejoin v0.2.3
|
||||||
|
4
go.sum
4
go.sum
@ -284,8 +284,8 @@ github.com/containers/storage v1.35.0/go.mod h1:qzYhasQP2/V9D9XdO+vRwkHBhsBO0ozn
|
|||||||
github.com/containers/storage v1.36.0/go.mod h1:vbd3SKVQNHdmU5qQI6hTEcKPxnZkGqydG4f6uwrI5a8=
|
github.com/containers/storage v1.36.0/go.mod h1:vbd3SKVQNHdmU5qQI6hTEcKPxnZkGqydG4f6uwrI5a8=
|
||||||
github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4=
|
github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4=
|
||||||
github.com/containers/storage v1.37.1-0.20211119174841-bf170b3ddac0/go.mod h1:XjCNlt5JUUmRuTJXhFxHb9hHGPho7DNg3o4N/14prdQ=
|
github.com/containers/storage v1.37.1-0.20211119174841-bf170b3ddac0/go.mod h1:XjCNlt5JUUmRuTJXhFxHb9hHGPho7DNg3o4N/14prdQ=
|
||||||
github.com/containers/storage v1.37.1-0.20211122214631-59ba58582415 h1:iqTDpYOxZibrkC7Mo7gCXuJDIT7wyIU432RTmRhlZqY=
|
github.com/containers/storage v1.37.1-0.20211130181259-1a158c89a518 h1:p44O35V8XCefRxOxU1aY6eT9XNMxkWA1drtJpsl211c=
|
||||||
github.com/containers/storage v1.37.1-0.20211122214631-59ba58582415/go.mod h1:hvKpaiPRALDI7oz4Jx+AEch8iS/viRnc22HPilQROWU=
|
github.com/containers/storage v1.37.1-0.20211130181259-1a158c89a518/go.mod h1:T5DX08T/eKKRs0WGDhC/ztngMSth6YuHq15eF8C/Y5A=
|
||||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
|
4
vendor/github.com/containers/storage/.cirrus.yml
generated
vendored
4
vendor/github.com/containers/storage/.cirrus.yml
generated
vendored
@ -17,8 +17,8 @@ env:
|
|||||||
####
|
####
|
||||||
#### Cache-image names to test with (double-quotes around names are critical)
|
#### Cache-image names to test with (double-quotes around names are critical)
|
||||||
###
|
###
|
||||||
FEDORA_NAME: "fedora-34"
|
FEDORA_NAME: "fedora-35"
|
||||||
PRIOR_FEDORA_NAME: "fedora-33"
|
PRIOR_FEDORA_NAME: "fedora-34"
|
||||||
UBUNTU_NAME: "ubuntu-2104"
|
UBUNTU_NAME: "ubuntu-2104"
|
||||||
|
|
||||||
# GCE project where images live
|
# GCE project where images live
|
||||||
|
25
vendor/github.com/containers/storage/Vagrantfile
generated
vendored
25
vendor/github.com/containers/storage/Vagrantfile
generated
vendored
@ -1,25 +0,0 @@
|
|||||||
# -*- mode: ruby -*-
|
|
||||||
# vi: set ft=ruby :
|
|
||||||
#
|
|
||||||
# The fedora/28-cloud-base and debian/jessie64 boxes are also available for
|
|
||||||
# the "virtualbox" provider. Set the VAGRANT_PROVIDER environment variable to
|
|
||||||
# "virtualbox" to use them instead.
|
|
||||||
#
|
|
||||||
Vagrant.configure("2") do |config|
|
|
||||||
config.vm.define "fedora" do |c|
|
|
||||||
c.vm.box = "fedora/28-cloud-base"
|
|
||||||
c.vm.synced_folder ".", "/vagrant", type: "rsync",
|
|
||||||
rsync__exclude: "bundles", rsync__args: ["-vadz", "--delete"]
|
|
||||||
c.vm.provision "shell", inline: <<-SHELL
|
|
||||||
sudo /vagrant/vagrant/provision.sh
|
|
||||||
SHELL
|
|
||||||
end
|
|
||||||
config.vm.define "debian" do |c|
|
|
||||||
c.vm.box = "debian/jessie64"
|
|
||||||
c.vm.synced_folder ".", "/vagrant", type: "rsync",
|
|
||||||
rsync__exclude: "bundles", rsync__args: ["-vadz", "--delete"]
|
|
||||||
c.vm.provision "shell", inline: <<-SHELL
|
|
||||||
sudo /vagrant/vagrant/provision.sh
|
|
||||||
SHELL
|
|
||||||
end
|
|
||||||
end
|
|
1
vendor/github.com/containers/storage/go.mod
generated
vendored
1
vendor/github.com/containers/storage/go.mod
generated
vendored
@ -7,6 +7,7 @@ require (
|
|||||||
github.com/Microsoft/go-winio v0.5.1
|
github.com/Microsoft/go-winio v0.5.1
|
||||||
github.com/Microsoft/hcsshim v0.9.1
|
github.com/Microsoft/hcsshim v0.9.1
|
||||||
github.com/containerd/stargz-snapshotter/estargz v0.10.1
|
github.com/containerd/stargz-snapshotter/estargz v0.10.1
|
||||||
|
github.com/cyphar/filepath-securejoin v0.2.3
|
||||||
github.com/docker/go-units v0.4.0
|
github.com/docker/go-units v0.4.0
|
||||||
github.com/google/go-intervals v0.0.2
|
github.com/google/go-intervals v0.0.2
|
||||||
github.com/hashicorp/go-multierror v1.1.1
|
github.com/hashicorp/go-multierror v1.1.1
|
||||||
|
2
vendor/github.com/containers/storage/go.sum
generated
vendored
2
vendor/github.com/containers/storage/go.sum
generated
vendored
@ -218,6 +218,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr
|
|||||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||||
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
|
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
|
||||||
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
|
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
|
||||||
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
|
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
|
||||||
|
7
vendor/github.com/containers/storage/pkg/archive/archive.go
generated
vendored
7
vendor/github.com/containers/storage/pkg/archive/archive.go
generated
vendored
@ -77,6 +77,10 @@ const (
|
|||||||
containersOverrideXattr = "user.containers.override_stat"
|
containersOverrideXattr = "user.containers.override_stat"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var xattrsToIgnore = map[string]interface{}{
|
||||||
|
"security.selinux": true,
|
||||||
|
}
|
||||||
|
|
||||||
// Archiver allows the reuse of most utility functions of this package with a
|
// Archiver allows the reuse of most utility functions of this package with a
|
||||||
// pluggable Untar function. To facilitate the passing of specific id mappings
|
// pluggable Untar function. To facilitate the passing of specific id mappings
|
||||||
// for untar, an archiver can be created with maps which will then be passed to
|
// for untar, an archiver can be created with maps which will then be passed to
|
||||||
@ -743,6 +747,9 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L
|
|||||||
|
|
||||||
var errs []string
|
var errs []string
|
||||||
for key, value := range hdr.Xattrs {
|
for key, value := range hdr.Xattrs {
|
||||||
|
if _, found := xattrsToIgnore[key]; found {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if err := system.Lsetxattr(path, key, []byte(value), 0); err != nil {
|
if err := system.Lsetxattr(path, key, []byte(value), 0); err != nil {
|
||||||
if errors.Is(err, syscall.ENOTSUP) || (inUserns && errors.Is(err, syscall.EPERM)) {
|
if errors.Is(err, syscall.ENOTSUP) || (inUserns && errors.Is(err, syscall.EPERM)) {
|
||||||
// We ignore errors here because not all graphdrivers support
|
// We ignore errors here because not all graphdrivers support
|
||||||
|
331
vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
generated
vendored
331
vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
generated
vendored
@ -13,6 +13,7 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ import (
|
|||||||
"github.com/containers/storage/pkg/idtools"
|
"github.com/containers/storage/pkg/idtools"
|
||||||
"github.com/containers/storage/pkg/system"
|
"github.com/containers/storage/pkg/system"
|
||||||
"github.com/containers/storage/types"
|
"github.com/containers/storage/types"
|
||||||
|
securejoin "github.com/cyphar/filepath-securejoin"
|
||||||
"github.com/klauspost/compress/zstd"
|
"github.com/klauspost/compress/zstd"
|
||||||
"github.com/klauspost/pgzip"
|
"github.com/klauspost/pgzip"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
@ -57,6 +59,10 @@ type chunkedDiffer struct {
|
|||||||
gzipReader *pgzip.Reader
|
gzipReader *pgzip.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var xattrsToIgnore = map[string]interface{}{
|
||||||
|
"security.selinux": true,
|
||||||
|
}
|
||||||
|
|
||||||
func timeToTimespec(time time.Time) (ts unix.Timespec) {
|
func timeToTimespec(time time.Time) (ts unix.Timespec) {
|
||||||
if time.IsZero() {
|
if time.IsZero() {
|
||||||
// Return UTIME_OMIT special value
|
// Return UTIME_OMIT special value
|
||||||
@ -89,7 +95,7 @@ func copyFileContent(srcFd int, destFile string, dirfd int, mode os.FileMode, us
|
|||||||
src := fmt.Sprintf("/proc/self/fd/%d", srcFd)
|
src := fmt.Sprintf("/proc/self/fd/%d", srcFd)
|
||||||
st, err := os.Stat(src)
|
st, err := os.Stat(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, -1, err
|
return nil, -1, fmt.Errorf("copy file content for %q: %w", destFile, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
copyWithFileRange, copyWithFileClone := true, true
|
copyWithFileRange, copyWithFileClone := true, true
|
||||||
@ -111,15 +117,15 @@ func copyFileContent(srcFd int, destFile string, dirfd int, mode os.FileMode, us
|
|||||||
// If the destination file already exists, we shouldn't blow it away
|
// If the destination file already exists, we shouldn't blow it away
|
||||||
dstFile, err := openFileUnderRoot(destFile, dirfd, newFileFlags, mode)
|
dstFile, err := openFileUnderRoot(destFile, dirfd, newFileFlags, mode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, -1, err
|
return nil, -1, fmt.Errorf("open file %q under rootfs for copy: %w", destFile, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = driversCopy.CopyRegularToFile(src, dstFile, st, ©WithFileRange, ©WithFileClone)
|
err = driversCopy.CopyRegularToFile(src, dstFile, st, ©WithFileRange, ©WithFileClone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dstFile.Close()
|
dstFile.Close()
|
||||||
return nil, -1, err
|
return nil, -1, fmt.Errorf("copy to file %q under rootfs: %w", destFile, err)
|
||||||
}
|
}
|
||||||
return dstFile, st.Size(), err
|
return dstFile, st.Size(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareOtherLayersCache(layersMetadata map[string][]internal.FileMetadata) map[string]map[string][]*internal.FileMetadata {
|
func prepareOtherLayersCache(layersMetadata map[string][]internal.FileMetadata) map[string]map[string][]*internal.FileMetadata {
|
||||||
@ -153,7 +159,7 @@ func getLayersCache(store storage.Store) (map[string][]internal.FileMetadata, ma
|
|||||||
defer manifestReader.Close()
|
defer manifestReader.Close()
|
||||||
manifest, err := ioutil.ReadAll(manifestReader)
|
manifest, err := ioutil.ReadAll(manifestReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, fmt.Errorf("open manifest file for layer %q: %w", r.ID, err)
|
||||||
}
|
}
|
||||||
var toc internal.TOC
|
var toc internal.TOC
|
||||||
if err := json.Unmarshal(manifest, &toc); err != nil {
|
if err := json.Unmarshal(manifest, &toc); err != nil {
|
||||||
@ -162,7 +168,7 @@ func getLayersCache(store storage.Store) (map[string][]internal.FileMetadata, ma
|
|||||||
layersMetadata[r.ID] = toc.Entries
|
layersMetadata[r.ID] = toc.Entries
|
||||||
target, err := store.DifferTarget(r.ID)
|
target, err := store.DifferTarget(r.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, fmt.Errorf("get checkout directory layer %q: %w", r.ID, err)
|
||||||
}
|
}
|
||||||
layersTarget[r.ID] = target
|
layersTarget[r.ID] = target
|
||||||
}
|
}
|
||||||
@ -184,7 +190,7 @@ func GetDiffer(ctx context.Context, store storage.Store, blobSize int64, annotat
|
|||||||
func makeZstdChunkedDiffer(ctx context.Context, store storage.Store, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (*chunkedDiffer, error) {
|
func makeZstdChunkedDiffer(ctx context.Context, store storage.Store, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (*chunkedDiffer, error) {
|
||||||
manifest, tocOffset, err := readZstdChunkedManifest(iss, blobSize, annotations)
|
manifest, tocOffset, err := readZstdChunkedManifest(iss, blobSize, annotations)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("read zstd:chunked manifest: %w", err)
|
||||||
}
|
}
|
||||||
layersMetadata, layersTarget, err := getLayersCache(store)
|
layersMetadata, layersTarget, err := getLayersCache(store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -204,7 +210,7 @@ func makeZstdChunkedDiffer(ctx context.Context, store storage.Store, blobSize in
|
|||||||
func makeEstargzChunkedDiffer(ctx context.Context, store storage.Store, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (*chunkedDiffer, error) {
|
func makeEstargzChunkedDiffer(ctx context.Context, store storage.Store, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (*chunkedDiffer, error) {
|
||||||
manifest, tocOffset, err := readEstargzChunkedManifest(iss, blobSize, annotations)
|
manifest, tocOffset, err := readEstargzChunkedManifest(iss, blobSize, annotations)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("read zstd:chunked manifest: %w", err)
|
||||||
}
|
}
|
||||||
layersMetadata, layersTarget, err := getLayersCache(store)
|
layersMetadata, layersTarget, err := getLayersCache(store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -230,21 +236,21 @@ func makeEstargzChunkedDiffer(ctx context.Context, store storage.Store, blobSize
|
|||||||
func copyFileFromOtherLayer(file *internal.FileMetadata, source string, otherFile *internal.FileMetadata, dirfd int, useHardLinks bool) (bool, *os.File, int64, error) {
|
func copyFileFromOtherLayer(file *internal.FileMetadata, source string, otherFile *internal.FileMetadata, dirfd int, useHardLinks bool) (bool, *os.File, int64, error) {
|
||||||
srcDirfd, err := unix.Open(source, unix.O_RDONLY, 0)
|
srcDirfd, err := unix.Open(source, unix.O_RDONLY, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil, 0, err
|
return false, nil, 0, fmt.Errorf("open source file %q: %w", source, err)
|
||||||
}
|
}
|
||||||
defer unix.Close(srcDirfd)
|
defer unix.Close(srcDirfd)
|
||||||
|
|
||||||
srcFile, err := openFileUnderRoot(otherFile.Name, srcDirfd, unix.O_RDONLY, 0)
|
srcFile, err := openFileUnderRoot(otherFile.Name, srcDirfd, unix.O_RDONLY, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil, 0, err
|
return false, nil, 0, fmt.Errorf("open source file %q under target rootfs: %w", otherFile.Name, err)
|
||||||
}
|
}
|
||||||
defer srcFile.Close()
|
defer srcFile.Close()
|
||||||
|
|
||||||
dstFile, written, err := copyFileContent(int(srcFile.Fd()), file.Name, dirfd, 0, useHardLinks)
|
dstFile, written, err := copyFileContent(int(srcFile.Fd()), file.Name, dirfd, 0, useHardLinks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil, 0, err
|
return false, nil, 0, fmt.Errorf("copy content to %q: %w", file.Name, err)
|
||||||
}
|
}
|
||||||
return true, dstFile, written, err
|
return true, dstFile, written, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// canDedupMetadataWithHardLink says whether it is possible to deduplicate file with otherFile.
|
// canDedupMetadataWithHardLink says whether it is possible to deduplicate file with otherFile.
|
||||||
@ -280,10 +286,6 @@ func canDedupFileWithHardLink(file *internal.FileMetadata, fd int, s os.FileInfo
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
xattrsToIgnore := map[string]interface{}{
|
|
||||||
"security.selinux": true,
|
|
||||||
}
|
|
||||||
|
|
||||||
xattrs := make(map[string]string)
|
xattrs := make(map[string]string)
|
||||||
for _, x := range listXattrs {
|
for _, x := range listXattrs {
|
||||||
v, err := system.Lgetxattr(path, x)
|
v, err := system.Lgetxattr(path, x)
|
||||||
@ -510,7 +512,7 @@ type missingChunk struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setFileAttrs sets the file attributes for file given metadata
|
// setFileAttrs sets the file attributes for file given metadata
|
||||||
func setFileAttrs(file *os.File, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
|
func setFileAttrs(dirfd int, file *os.File, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions, usePath bool) error {
|
||||||
if file == nil || file.Fd() < 0 {
|
if file == nil || file.Fd() < 0 {
|
||||||
return errors.Errorf("invalid file")
|
return errors.Errorf("invalid file")
|
||||||
}
|
}
|
||||||
@ -520,54 +522,237 @@ func setFileAttrs(file *os.File, mode os.FileMode, metadata *internal.FileMetada
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If it is a symlink, force to use the path
|
||||||
if t == tar.TypeSymlink {
|
if t == tar.TypeSymlink {
|
||||||
return nil
|
usePath = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := unix.Fchown(fd, metadata.UID, metadata.GID); err != nil {
|
baseName := ""
|
||||||
if !options.IgnoreChownErrors {
|
if usePath {
|
||||||
return err
|
dirName := filepath.Dir(metadata.Name)
|
||||||
|
if dirName != "" {
|
||||||
|
parentFd, err := openFileUnderRoot(dirName, dirfd, unix.O_PATH|unix.O_DIRECTORY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer parentFd.Close()
|
||||||
|
|
||||||
|
dirfd = int(parentFd.Fd())
|
||||||
}
|
}
|
||||||
|
baseName = filepath.Base(metadata.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
doChown := func() error {
|
||||||
|
if usePath {
|
||||||
|
return unix.Fchownat(dirfd, baseName, metadata.UID, metadata.GID, unix.AT_SYMLINK_NOFOLLOW)
|
||||||
|
}
|
||||||
|
return unix.Fchown(fd, metadata.UID, metadata.GID)
|
||||||
|
}
|
||||||
|
|
||||||
|
doSetXattr := func(k string, v []byte) error {
|
||||||
|
return unix.Fsetxattr(fd, k, v, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
doUtimes := func() error {
|
||||||
|
ts := []unix.Timespec{timeToTimespec(metadata.AccessTime), timeToTimespec(metadata.ModTime)}
|
||||||
|
if usePath {
|
||||||
|
return unix.UtimesNanoAt(dirfd, baseName, ts, unix.AT_SYMLINK_NOFOLLOW)
|
||||||
|
}
|
||||||
|
return unix.UtimesNanoAt(unix.AT_FDCWD, fmt.Sprintf("/proc/self/fd/%d", fd), ts, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
doChmod := func() error {
|
||||||
|
if usePath {
|
||||||
|
return unix.Fchmodat(dirfd, baseName, uint32(mode), unix.AT_SYMLINK_NOFOLLOW)
|
||||||
|
}
|
||||||
|
return unix.Fchmod(fd, uint32(mode))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := doChown(); err != nil {
|
||||||
|
if !options.IgnoreChownErrors {
|
||||||
|
return fmt.Errorf("chown %q to %d:%d: %w", metadata.Name, metadata.UID, metadata.GID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
canIgnore := func(err error) bool {
|
||||||
|
return err == nil || errors.Is(err, unix.ENOSYS) || errors.Is(err, unix.ENOTSUP)
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range metadata.Xattrs {
|
for k, v := range metadata.Xattrs {
|
||||||
|
if _, found := xattrsToIgnore[k]; found {
|
||||||
|
continue
|
||||||
|
}
|
||||||
data, err := base64.StdEncoding.DecodeString(v)
|
data, err := base64.StdEncoding.DecodeString(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("decode xattr %q: %w", v, err)
|
||||||
}
|
}
|
||||||
if err := unix.Fsetxattr(fd, k, data, 0); err != nil {
|
if err := doSetXattr(k, data); !canIgnore(err) {
|
||||||
return err
|
return fmt.Errorf("set xattr %s=%q for %q: %w", k, data, metadata.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ts := []unix.Timespec{timeToTimespec(metadata.AccessTime), timeToTimespec(metadata.ModTime)}
|
if err := doUtimes(); !canIgnore(err) {
|
||||||
if err := unix.UtimesNanoAt(fd, "", ts, 0); err != nil && errors.Is(err, unix.ENOSYS) {
|
return fmt.Errorf("set utimes for %q: %w", metadata.Name, err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := unix.Fchmod(fd, uint32(mode)); err != nil {
|
if err := doChmod(); !canIgnore(err) {
|
||||||
return err
|
return fmt.Errorf("chmod %q: %w", metadata.Name, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// openFileUnderRoot safely opens a file under the specified root directory using openat2
|
func openFileUnderRootFallback(dirfd int, name string, flags uint64, mode os.FileMode) (int, error) {
|
||||||
// name is the path to open relative to dirfd.
|
root := fmt.Sprintf("/proc/self/fd/%d", dirfd)
|
||||||
// dirfd is an open file descriptor to the target checkout directory.
|
|
||||||
// flags are the flags top pass to the open syscall.
|
targetRoot, err := os.Readlink(root)
|
||||||
// mode specifies the mode to use for newly created files.
|
if err != nil {
|
||||||
func openFileUnderRoot(name string, dirfd int, flags uint64, mode os.FileMode) (*os.File, error) {
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
hasNoFollow := (flags & unix.O_NOFOLLOW) != 0
|
||||||
|
|
||||||
|
fd := -1
|
||||||
|
// If O_NOFOLLOW is specified in the flags, then resolve only the parent directory and use the
|
||||||
|
// last component as the path to openat().
|
||||||
|
if hasNoFollow {
|
||||||
|
dirName := filepath.Dir(name)
|
||||||
|
if dirName != "" {
|
||||||
|
newRoot, err := securejoin.SecureJoin(root, filepath.Dir(name))
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
root = newRoot
|
||||||
|
}
|
||||||
|
|
||||||
|
parentDirfd, err := unix.Open(root, unix.O_PATH, 0)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
defer unix.Close(parentDirfd)
|
||||||
|
|
||||||
|
fd, err = unix.Openat(parentDirfd, filepath.Base(name), int(flags), uint32(mode))
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newPath, err := securejoin.SecureJoin(root, name)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
fd, err = unix.Openat(dirfd, newPath, int(flags), uint32(mode))
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target, err := os.Readlink(fmt.Sprintf("/proc/self/fd/%d", fd))
|
||||||
|
if err != nil {
|
||||||
|
unix.Close(fd)
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add an additional check to make sure the opened fd is inside the rootfs
|
||||||
|
if !strings.HasPrefix(target, targetRoot) {
|
||||||
|
unix.Close(fd)
|
||||||
|
return -1, fmt.Errorf("error while resolving %q. It resolves outside the root directory", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func openFileUnderRootOpenat2(dirfd int, name string, flags uint64, mode os.FileMode) (int, error) {
|
||||||
how := unix.OpenHow{
|
how := unix.OpenHow{
|
||||||
Flags: flags,
|
Flags: flags,
|
||||||
Mode: uint64(mode & 07777),
|
Mode: uint64(mode & 07777),
|
||||||
Resolve: unix.RESOLVE_IN_ROOT,
|
Resolve: unix.RESOLVE_IN_ROOT,
|
||||||
}
|
}
|
||||||
|
return unix.Openat2(dirfd, name, &how)
|
||||||
|
}
|
||||||
|
|
||||||
fd, err := unix.Openat2(dirfd, name, &how)
|
// skipOpenat2 is set when openat2 is not supported by the underlying kernel and avoid
|
||||||
if err != nil {
|
// using it again.
|
||||||
return nil, err
|
var skipOpenat2 int32
|
||||||
|
|
||||||
|
// openFileUnderRootRaw tries to open a file using openat2 and if it is not supported fallbacks to a
|
||||||
|
// userspace lookup.
|
||||||
|
func openFileUnderRootRaw(dirfd int, name string, flags uint64, mode os.FileMode) (int, error) {
|
||||||
|
var fd int
|
||||||
|
var err error
|
||||||
|
if atomic.LoadInt32(&skipOpenat2) > 0 {
|
||||||
|
fd, err = openFileUnderRootFallback(dirfd, name, flags, mode)
|
||||||
|
} else {
|
||||||
|
fd, err = openFileUnderRootOpenat2(dirfd, name, flags, mode)
|
||||||
|
// If the function failed with ENOSYS, switch off the support for openat2
|
||||||
|
// and fallback to using safejoin.
|
||||||
|
if err != nil && errors.Is(err, unix.ENOSYS) {
|
||||||
|
atomic.StoreInt32(&skipOpenat2, 1)
|
||||||
|
fd, err = openFileUnderRootFallback(dirfd, name, flags, mode)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return os.NewFile(uintptr(fd), name), nil
|
return fd, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// openFileUnderRoot safely opens a file under the specified root directory using openat2
|
||||||
|
// name is the path to open relative to dirfd.
|
||||||
|
// dirfd is an open file descriptor to the target checkout directory.
|
||||||
|
// flags are the flags to pass to the open syscall.
|
||||||
|
// mode specifies the mode to use for newly created files.
|
||||||
|
func openFileUnderRoot(name string, dirfd int, flags uint64, mode os.FileMode) (*os.File, error) {
|
||||||
|
fd, err := openFileUnderRootRaw(dirfd, name, flags, mode)
|
||||||
|
if err == nil {
|
||||||
|
return os.NewFile(uintptr(fd), name), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
hasCreate := (flags & unix.O_CREAT) != 0
|
||||||
|
if errors.Is(err, unix.ENOENT) && hasCreate {
|
||||||
|
parent := filepath.Dir(name)
|
||||||
|
if parent != "" {
|
||||||
|
newDirfd, err2 := openOrCreateDirUnderRoot(parent, dirfd, 0)
|
||||||
|
if err2 == nil {
|
||||||
|
defer newDirfd.Close()
|
||||||
|
fd, err := openFileUnderRootRaw(dirfd, name, flags, mode)
|
||||||
|
if err == nil {
|
||||||
|
return os.NewFile(uintptr(fd), name), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("open %q under the rootfs: %w", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// openOrCreateDirUnderRoot safely opens a directory or create it if it is missing.
|
||||||
|
// name is the path to open relative to dirfd.
|
||||||
|
// dirfd is an open file descriptor to the target checkout directory.
|
||||||
|
// mode specifies the mode to use for newly created files.
|
||||||
|
func openOrCreateDirUnderRoot(name string, dirfd int, mode os.FileMode) (*os.File, error) {
|
||||||
|
fd, err := openFileUnderRootRaw(dirfd, name, unix.O_DIRECTORY|unix.O_RDONLY, mode)
|
||||||
|
if err == nil {
|
||||||
|
return os.NewFile(uintptr(fd), name), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if errors.Is(err, unix.ENOENT) {
|
||||||
|
parent := filepath.Dir(name)
|
||||||
|
if parent != "" {
|
||||||
|
pDir, err2 := openOrCreateDirUnderRoot(parent, dirfd, mode)
|
||||||
|
if err2 != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer pDir.Close()
|
||||||
|
|
||||||
|
baseName := filepath.Base(name)
|
||||||
|
|
||||||
|
if err2 := unix.Mkdirat(int(pDir.Fd()), baseName, 0755); err2 != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fd, err = openFileUnderRootRaw(int(pDir.Fd()), baseName, unix.O_DIRECTORY|unix.O_RDONLY, mode)
|
||||||
|
if err == nil {
|
||||||
|
return os.NewFile(uintptr(fd), name), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *chunkedDiffer) createFileFromCompressedStream(dest string, dirfd int, reader io.Reader, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) (err error) {
|
func (c *chunkedDiffer) createFileFromCompressedStream(dest string, dirfd int, reader io.Reader, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) (err error) {
|
||||||
@ -631,7 +816,7 @@ func (c *chunkedDiffer) createFileFromCompressedStream(dest string, dirfd int, r
|
|||||||
if digester.Digest() != manifestChecksum {
|
if digester.Digest() != manifestChecksum {
|
||||||
return fmt.Errorf("checksum mismatch for %q", dest)
|
return fmt.Errorf("checksum mismatch for %q", dest)
|
||||||
}
|
}
|
||||||
return setFileAttrs(file, mode, metadata, options)
|
return setFileAttrs(dirfd, file, mode, metadata, options, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *chunkedDiffer) storeMissingFiles(streams chan io.ReadCloser, errs chan error, dest string, dirfd int, missingChunks []missingChunk, options *archive.TarOptions) error {
|
func (c *chunkedDiffer) storeMissingFiles(streams chan io.ReadCloser, errs chan error, dest string, dirfd int, missingChunks []missingChunk, options *archive.TarOptions) error {
|
||||||
@ -755,13 +940,13 @@ func (c *chunkedDiffer) retrieveMissingFiles(dest string, dirfd int, missingChun
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func safeMkdir(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
|
func safeMkdir(dirfd int, mode os.FileMode, name string, metadata *internal.FileMetadata, options *archive.TarOptions) error {
|
||||||
parent := filepath.Dir(metadata.Name)
|
parent := filepath.Dir(name)
|
||||||
base := filepath.Base(metadata.Name)
|
base := filepath.Base(name)
|
||||||
|
|
||||||
parentFd := dirfd
|
parentFd := dirfd
|
||||||
if parent != "." {
|
if parent != "." {
|
||||||
parentFile, err := openFileUnderRoot(parent, dirfd, unix.O_DIRECTORY|unix.O_PATH|unix.O_RDONLY, 0)
|
parentFile, err := openOrCreateDirUnderRoot(parent, dirfd, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -771,21 +956,21 @@ func safeMkdir(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, opt
|
|||||||
|
|
||||||
if err := unix.Mkdirat(parentFd, base, uint32(mode)); err != nil {
|
if err := unix.Mkdirat(parentFd, base, uint32(mode)); err != nil {
|
||||||
if !os.IsExist(err) {
|
if !os.IsExist(err) {
|
||||||
return err
|
return fmt.Errorf("mkdir %q: %w", name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := openFileUnderRoot(metadata.Name, dirfd, unix.O_RDONLY, 0)
|
file, err := openFileUnderRoot(name, dirfd, unix.O_DIRECTORY|unix.O_RDONLY, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
return setFileAttrs(file, mode, metadata, options)
|
return setFileAttrs(dirfd, file, mode, metadata, options, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func safeLink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
|
func safeLink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
|
||||||
sourceFile, err := openFileUnderRoot(metadata.Linkname, dirfd, unix.O_RDONLY, 0)
|
sourceFile, err := openFileUnderRoot(metadata.Linkname, dirfd, unix.O_PATH|unix.O_RDONLY|unix.O_NOFOLLOW, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -794,7 +979,7 @@ func safeLink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, opti
|
|||||||
destDir, destBase := filepath.Dir(metadata.Name), filepath.Base(metadata.Name)
|
destDir, destBase := filepath.Dir(metadata.Name), filepath.Base(metadata.Name)
|
||||||
destDirFd := dirfd
|
destDirFd := dirfd
|
||||||
if destDir != "." {
|
if destDir != "." {
|
||||||
f, err := openFileUnderRoot(destDir, dirfd, unix.O_RDONLY, 0)
|
f, err := openOrCreateDirUnderRoot(destDir, dirfd, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -804,23 +989,33 @@ func safeLink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, opti
|
|||||||
|
|
||||||
err = doHardLink(int(sourceFile.Fd()), destDirFd, destBase)
|
err = doHardLink(int(sourceFile.Fd()), destDirFd, destBase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("create hardlink %q pointing to %q: %w", metadata.Name, metadata.Linkname, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newFile, err := openFileUnderRoot(metadata.Name, dirfd, unix.O_WRONLY, 0)
|
newFile, err := openFileUnderRoot(metadata.Name, dirfd, unix.O_WRONLY|unix.O_NOFOLLOW, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// If the target is a symlink, open the file with O_PATH.
|
||||||
|
if errors.Is(err, unix.ELOOP) {
|
||||||
|
newFile, err := openFileUnderRoot(metadata.Name, dirfd, unix.O_PATH|unix.O_NOFOLLOW, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer newFile.Close()
|
||||||
|
|
||||||
|
return setFileAttrs(dirfd, newFile, mode, metadata, options, true)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer newFile.Close()
|
defer newFile.Close()
|
||||||
|
|
||||||
return setFileAttrs(newFile, mode, metadata, options)
|
return setFileAttrs(dirfd, newFile, mode, metadata, options, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func safeSymlink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
|
func safeSymlink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, options *archive.TarOptions) error {
|
||||||
destDir, destBase := filepath.Dir(metadata.Name), filepath.Base(metadata.Name)
|
destDir, destBase := filepath.Dir(metadata.Name), filepath.Base(metadata.Name)
|
||||||
destDirFd := dirfd
|
destDirFd := dirfd
|
||||||
if destDir != "." {
|
if destDir != "." {
|
||||||
f, err := openFileUnderRoot(destDir, dirfd, unix.O_RDONLY, 0)
|
f, err := openOrCreateDirUnderRoot(destDir, dirfd, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -828,7 +1023,10 @@ func safeSymlink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, o
|
|||||||
destDirFd = int(f.Fd())
|
destDirFd = int(f.Fd())
|
||||||
}
|
}
|
||||||
|
|
||||||
return unix.Symlinkat(metadata.Linkname, destDirFd, destBase)
|
if err := unix.Symlinkat(metadata.Linkname, destDirFd, destBase); err != nil {
|
||||||
|
return fmt.Errorf("create symlink %q pointing to %q: %w", metadata.Name, metadata.Linkname, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type whiteoutHandler struct {
|
type whiteoutHandler struct {
|
||||||
@ -837,13 +1035,16 @@ type whiteoutHandler struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d whiteoutHandler) Setxattr(path, name string, value []byte) error {
|
func (d whiteoutHandler) Setxattr(path, name string, value []byte) error {
|
||||||
file, err := openFileUnderRoot(path, d.Dirfd, unix.O_RDONLY, 0)
|
file, err := openOrCreateDirUnderRoot(path, d.Dirfd, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
return unix.Fsetxattr(int(file.Fd()), name, value, 0)
|
if err := unix.Fsetxattr(int(file.Fd()), name, value, 0); err != nil {
|
||||||
|
return fmt.Errorf("set xattr %s=%q for %q: %w", name, value, path, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d whiteoutHandler) Mknod(path string, mode uint32, dev int) error {
|
func (d whiteoutHandler) Mknod(path string, mode uint32, dev int) error {
|
||||||
@ -852,7 +1053,7 @@ func (d whiteoutHandler) Mknod(path string, mode uint32, dev int) error {
|
|||||||
|
|
||||||
dirfd := d.Dirfd
|
dirfd := d.Dirfd
|
||||||
if dir != "" {
|
if dir != "" {
|
||||||
dir, err := openFileUnderRoot(dir, d.Dirfd, unix.O_RDONLY, 0)
|
dir, err := openOrCreateDirUnderRoot(dir, d.Dirfd, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -861,12 +1062,16 @@ func (d whiteoutHandler) Mknod(path string, mode uint32, dev int) error {
|
|||||||
dirfd = int(dir.Fd())
|
dirfd = int(dir.Fd())
|
||||||
}
|
}
|
||||||
|
|
||||||
return unix.Mknodat(dirfd, base, mode, dev)
|
if err := unix.Mknodat(dirfd, base, mode, dev); err != nil {
|
||||||
|
return fmt.Errorf("mknod %q: %w", path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkChownErr(err error, name string, uid, gid int) error {
|
func checkChownErr(err error, name string, uid, gid int) error {
|
||||||
if errors.Is(err, syscall.EINVAL) {
|
if errors.Is(err, syscall.EINVAL) {
|
||||||
return errors.Wrapf(err, "potentially insufficient UIDs or GIDs available in user namespace (requested %d:%d for %s): Check /etc/subuid and /etc/subgid if configured locally", uid, gid, name)
|
return fmt.Errorf("potentially insufficient UIDs or GIDs available in user namespace (requested %d:%d for %s): Check /etc/subuid and /etc/subgid if configured locally: %w", uid, gid, name, err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -961,7 +1166,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
|
|||||||
|
|
||||||
dirfd, err := unix.Open(dest, unix.O_RDONLY|unix.O_PATH, 0)
|
dirfd, err := unix.Open(dest, unix.O_RDONLY|unix.O_PATH, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return output, err
|
return output, fmt.Errorf("cannot open %q: %w", dest, err)
|
||||||
}
|
}
|
||||||
defer unix.Close(dirfd)
|
defer unix.Close(dirfd)
|
||||||
|
|
||||||
@ -1021,7 +1226,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
if err := setFileAttrs(file, mode, &r, options); err != nil {
|
if err := setFileAttrs(dirfd, file, mode, &r, options, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -1033,7 +1238,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
|
|||||||
}
|
}
|
||||||
|
|
||||||
case tar.TypeDir:
|
case tar.TypeDir:
|
||||||
if err := safeMkdir(dirfd, mode, &r, options); err != nil {
|
if err := safeMkdir(dirfd, mode, r.Name, &r, options); err != nil {
|
||||||
return output, err
|
return output, err
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@ -1070,7 +1275,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions) (gra
|
|||||||
finalizeFile := func(dstFile *os.File) error {
|
finalizeFile := func(dstFile *os.File) error {
|
||||||
if dstFile != nil {
|
if dstFile != nil {
|
||||||
defer dstFile.Close()
|
defer dstFile.Close()
|
||||||
if err := setFileAttrs(dstFile, mode, &r, options); err != nil {
|
if err := setFileAttrs(dirfd, dstFile, mode, &r, options, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
vendor/github.com/containers/storage/types/options.go
generated
vendored
4
vendor/github.com/containers/storage/types/options.go
generated
vendored
@ -42,6 +42,10 @@ func init() {
|
|||||||
defaultStoreOptions.GraphDriverName = ""
|
defaultStoreOptions.GraphDriverName = ""
|
||||||
|
|
||||||
if _, err := os.Stat(defaultOverrideConfigFile); err == nil {
|
if _, err := os.Stat(defaultOverrideConfigFile); err == nil {
|
||||||
|
// The DefaultConfigFile(rootless) function returns the path
|
||||||
|
// of the used storage.conf file, by returning defaultConfigFile
|
||||||
|
// If override exists containers/storage uses it by default.
|
||||||
|
defaultConfigFile = defaultOverrideConfigFile
|
||||||
ReloadConfigurationFileIfNeeded(defaultOverrideConfigFile, &defaultStoreOptions)
|
ReloadConfigurationFileIfNeeded(defaultOverrideConfigFile, &defaultStoreOptions)
|
||||||
} else {
|
} else {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -219,7 +219,7 @@ github.com/containers/psgo/internal/dev
|
|||||||
github.com/containers/psgo/internal/host
|
github.com/containers/psgo/internal/host
|
||||||
github.com/containers/psgo/internal/proc
|
github.com/containers/psgo/internal/proc
|
||||||
github.com/containers/psgo/internal/process
|
github.com/containers/psgo/internal/process
|
||||||
# github.com/containers/storage v1.37.1-0.20211122214631-59ba58582415
|
# github.com/containers/storage v1.37.1-0.20211130181259-1a158c89a518
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containers/storage
|
github.com/containers/storage
|
||||||
github.com/containers/storage/drivers
|
github.com/containers/storage/drivers
|
||||||
|
Reference in New Issue
Block a user