mirror of
https://github.com/containers/podman.git
synced 2025-11-02 06:37:09 +08:00
Update vendor of storage,common
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
54
vendor/github.com/containers/storage/drivers/overlay/check.go
generated
vendored
54
vendor/github.com/containers/storage/drivers/overlay/check.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package overlay
|
||||
@ -11,6 +12,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/containers/storage/pkg/ioutils"
|
||||
"github.com/containers/storage/pkg/mount"
|
||||
"github.com/containers/storage/pkg/system"
|
||||
@ -218,3 +220,55 @@ func doesVolatile(d string) (bool, error) {
|
||||
}()
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// supportsIdmappedLowerLayers checks if the kernel supports mounting overlay on top of
|
||||
// a idmapped lower layer.
|
||||
func supportsIdmappedLowerLayers(home string) (bool, error) {
|
||||
layerDir, err := ioutil.TempDir(home, "compat")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer func() {
|
||||
_ = os.RemoveAll(layerDir)
|
||||
}()
|
||||
|
||||
mergedDir := filepath.Join(layerDir, "merged")
|
||||
lowerDir := filepath.Join(layerDir, "lower")
|
||||
lowerMappedDir := filepath.Join(layerDir, "lower-mapped")
|
||||
upperDir := filepath.Join(layerDir, "upper")
|
||||
workDir := filepath.Join(layerDir, "work")
|
||||
|
||||
_ = idtools.MkdirAs(mergedDir, 0700, 0, 0)
|
||||
_ = idtools.MkdirAs(lowerDir, 0700, 0, 0)
|
||||
_ = idtools.MkdirAs(lowerMappedDir, 0700, 0, 0)
|
||||
_ = idtools.MkdirAs(upperDir, 0700, 0, 0)
|
||||
_ = idtools.MkdirAs(workDir, 0700, 0, 0)
|
||||
|
||||
idmap := []idtools.IDMap{
|
||||
{
|
||||
ContainerID: 0,
|
||||
HostID: 0,
|
||||
Size: 1,
|
||||
},
|
||||
}
|
||||
pid, cleanupFunc, err := createUsernsProcess(idmap, idmap)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer cleanupFunc()
|
||||
|
||||
if err := createIDMappedMount(lowerDir, lowerMappedDir, int(pid)); err != nil {
|
||||
return false, errors.Wrapf(err, "create mapped mount")
|
||||
}
|
||||
defer unix.Unmount(lowerMappedDir, unix.MNT_DETACH)
|
||||
|
||||
opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lowerMappedDir, upperDir, workDir)
|
||||
flags := uintptr(0)
|
||||
if err := unix.Mount("overlay", mergedDir, "overlay", flags, opts); err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer func() {
|
||||
_ = unix.Unmount(mergedDir, unix.MNT_DETACH)
|
||||
}()
|
||||
return true, nil
|
||||
}
|
||||
|
||||
160
vendor/github.com/containers/storage/drivers/overlay/idmapped_utils.go
generated
vendored
Normal file
160
vendor/github.com/containers/storage/drivers/overlay/idmapped_utils.go
generated
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package overlay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
type attr struct {
|
||||
attrSet uint64
|
||||
attrClr uint64
|
||||
propagation uint64
|
||||
userNs uint64
|
||||
}
|
||||
|
||||
const (
|
||||
// _MOUNT_ATTR_IDMAP - Idmap mount to @userns_fd in struct mount_attr
|
||||
_MOUNT_ATTR_IDMAP = 0x00100000 //nolint:golint
|
||||
|
||||
// _OPEN_TREE_CLONE - Clone the source path mount
|
||||
_OPEN_TREE_CLONE = 0x00000001 //nolint:golint
|
||||
|
||||
// _MOVE_MOUNT_F_EMPTY_PATH - Move the path referenced by the fd
|
||||
_MOVE_MOUNT_F_EMPTY_PATH = 0x00000004 //nolint:golint
|
||||
)
|
||||
|
||||
// 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), nil
|
||||
}
|
||||
|
||||
// moveMount is a wrapper for the 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 := _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 {
|
||||
path := fmt.Sprintf("/proc/%d/ns/user", pid)
|
||||
userNsFile, err := os.Open(path)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to get user ns file descriptor for %q", path)
|
||||
}
|
||||
|
||||
var attr attr
|
||||
attr.attrSet = _MOUNT_ATTR_IDMAP
|
||||
attr.attrClr = 0
|
||||
attr.propagation = 0
|
||||
attr.userNs = uint64(userNsFile.Fd())
|
||||
|
||||
defer userNsFile.Close()
|
||||
|
||||
targetDirFd, err := openTree(source, _OPEN_TREE_CLONE|unix.AT_RECURSIVE)
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
if err := os.Mkdir(target, 0700); err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
return moveMount(targetDirFd, target)
|
||||
}
|
||||
|
||||
// createUsernsProcess forks the current process and creates a user namespace using the specified
|
||||
// mappings. It returns the pid of the new process.
|
||||
func createUsernsProcess(uidMaps []idtools.IDMap, gidMaps []idtools.IDMap) (int, func(), error) {
|
||||
pid, _, err := syscall.Syscall6(uintptr(unix.SYS_CLONE), unix.CLONE_NEWUSER|uintptr(unix.SIGCHLD), 0, 0, 0, 0, 0)
|
||||
if err != 0 {
|
||||
return -1, nil, err
|
||||
}
|
||||
if pid == 0 {
|
||||
_ = unix.Prctl(unix.PR_SET_PDEATHSIG, uintptr(unix.SIGKILL), 0, 0, 0)
|
||||
// just wait for the SIGKILL
|
||||
for {
|
||||
syscall.Syscall6(uintptr(unix.SYS_PAUSE), 0, 0, 0, 0, 0, 0)
|
||||
}
|
||||
}
|
||||
cleanupFunc := func() {
|
||||
unix.Kill(int(pid), unix.SIGKILL)
|
||||
_, _ = unix.Wait4(int(pid), nil, 0, nil)
|
||||
}
|
||||
writeMappings := func(fname string, idmap []idtools.IDMap) error {
|
||||
mappings := ""
|
||||
for _, m := range idmap {
|
||||
mappings = mappings + fmt.Sprintf("%d %d %d\n", m.ContainerID, m.HostID, m.Size)
|
||||
}
|
||||
return ioutil.WriteFile(fmt.Sprintf("/proc/%d/%s", pid, fname), []byte(mappings), 0600)
|
||||
}
|
||||
if err := writeMappings("uid_map", uidMaps); err != nil {
|
||||
cleanupFunc()
|
||||
return -1, nil, err
|
||||
}
|
||||
if err := writeMappings("gid_map", gidMaps); err != nil {
|
||||
cleanupFunc()
|
||||
return -1, nil, err
|
||||
}
|
||||
|
||||
return int(pid), cleanupFunc, nil
|
||||
}
|
||||
141
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
141
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
@ -39,7 +39,6 @@ import (
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vbatts/tar-split/tar/storage"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@ -121,6 +120,8 @@ type Driver struct {
|
||||
supportsVolatile *bool
|
||||
usingMetacopy bool
|
||||
locker *locker.Locker
|
||||
|
||||
supportsIDMappedMounts *bool
|
||||
}
|
||||
|
||||
type additionalLayerStore struct {
|
||||
@ -205,6 +206,26 @@ func checkSupportVolatile(home, runhome string) (bool, error) {
|
||||
return usingVolatile, nil
|
||||
}
|
||||
|
||||
// checkAndRecordIDMappedSupport checks and stores if the kernel supports mounting overlay on top of a
|
||||
// idmapped lower layer.
|
||||
func checkAndRecordIDMappedSupport(home, runhome string) (bool, error) {
|
||||
feature := "idmapped-lower-dir"
|
||||
overlayCacheResult, overlayCacheText, err := cachedFeatureCheck(runhome, feature)
|
||||
if err == nil {
|
||||
if overlayCacheResult {
|
||||
logrus.Debugf("Cached value indicated that overlay is supported")
|
||||
return true, nil
|
||||
}
|
||||
logrus.Debugf("Cached value indicated that overlay is not supported")
|
||||
return false, errors.New(overlayCacheText)
|
||||
}
|
||||
supportsIDMappedMounts, err := supportsIdmappedLowerLayers(home)
|
||||
if err2 := cachedFeatureRecord(runhome, feature, supportsIDMappedMounts, ""); err2 != nil {
|
||||
return false, errors.Wrap(err2, "recording overlay idmapped mounts support status")
|
||||
}
|
||||
return supportsIDMappedMounts, err
|
||||
}
|
||||
|
||||
func checkAndRecordOverlaySupport(fsMagic graphdriver.FsMagic, home, runhome string) (bool, error) {
|
||||
var supportsDType bool
|
||||
|
||||
@ -1485,6 +1506,51 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
}
|
||||
}
|
||||
|
||||
if d.supportsIDmappedMounts() && len(options.UidMaps) > 0 && len(options.GidMaps) > 0 {
|
||||
var newAbsDir []string
|
||||
mappedRoot := filepath.Join(d.home, id, "mapped")
|
||||
if err := os.MkdirAll(mappedRoot, 0700); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
pid, cleanupFunc, err := createUsernsProcess(options.UidMaps, options.GidMaps)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer cleanupFunc()
|
||||
|
||||
idMappedMounts := make(map[string]string)
|
||||
|
||||
// rewrite the lower dirs to their idmapped mount.
|
||||
c := 0
|
||||
for _, absLower := range absLowers {
|
||||
mappedMountSrc := getMappedMountRoot(absLower)
|
||||
|
||||
root, found := idMappedMounts[mappedMountSrc]
|
||||
if !found {
|
||||
root = filepath.Join(mappedRoot, fmt.Sprintf("%d", c))
|
||||
c++
|
||||
if err := createIDMappedMount(mappedMountSrc, root, int(pid)); err != nil {
|
||||
return "", errors.Wrapf(err, "create mapped mount for %q on %q", mappedMountSrc, root)
|
||||
}
|
||||
idMappedMounts[mappedMountSrc] = root
|
||||
|
||||
// overlay takes a reference on the mount, so it is safe to unmount
|
||||
// the mapped idmounts as soon as the final overlay file system is mounted.
|
||||
defer unix.Unmount(root, unix.MNT_DETACH)
|
||||
}
|
||||
|
||||
// relative path to the layer through the id mapped mount
|
||||
rel, err := filepath.Rel(mappedMountSrc, absLower)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
newAbsDir = append(newAbsDir, filepath.Join(root, rel))
|
||||
}
|
||||
absLowers = newAbsDir
|
||||
}
|
||||
|
||||
var opts string
|
||||
if readWrite {
|
||||
opts = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", strings.Join(absLowers, ":"), diffDir, workdir)
|
||||
@ -1587,6 +1653,18 @@ func (d *Driver) Put(id string) error {
|
||||
|
||||
unmounted := false
|
||||
|
||||
mappedRoot := filepath.Join(d.home, id, "mapped")
|
||||
// It should not happen, but cleanup any mapped mount if it was leaked.
|
||||
if _, err := os.Stat(mappedRoot); err == nil {
|
||||
mounts, err := ioutil.ReadDir(mappedRoot)
|
||||
if err == nil {
|
||||
// Go through all of the mapped mounts.
|
||||
for _, m := range mounts {
|
||||
_ = unix.Unmount(filepath.Join(mappedRoot, m.Name()), unix.MNT_DETACH)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if d.options.mountProgram != "" {
|
||||
// Attempt to unmount the FUSE mount using either fusermount or fusermount3.
|
||||
// If they fail, fallback to unix.Unmount
|
||||
@ -1664,11 +1742,24 @@ func (d *Driver) getWhiteoutFormat() archive.WhiteoutFormat {
|
||||
return whiteoutFormat
|
||||
}
|
||||
|
||||
type fileGetNilCloser struct {
|
||||
storage.FileGetter
|
||||
type overlayFileGetter struct {
|
||||
diffDirs []string
|
||||
}
|
||||
|
||||
func (f fileGetNilCloser) Close() error {
|
||||
func (g *overlayFileGetter) Get(path string) (io.ReadCloser, error) {
|
||||
for _, d := range g.diffDirs {
|
||||
f, err := os.Open(filepath.Join(d, path))
|
||||
if err == nil {
|
||||
return f, nil
|
||||
}
|
||||
}
|
||||
if len(g.diffDirs) > 0 {
|
||||
return os.Open(filepath.Join(g.diffDirs[0], path))
|
||||
}
|
||||
return nil, fmt.Errorf("%s: %w", path, os.ErrNotExist)
|
||||
}
|
||||
|
||||
func (g *overlayFileGetter) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1677,13 +1768,18 @@ func (d *Driver) getStagingDir() string {
|
||||
}
|
||||
|
||||
// DiffGetter returns a FileGetCloser that can read files from the directory that
|
||||
// contains files for the layer differences. Used for direct access for tar-split.
|
||||
// contains files for the layer differences, either for this layer, or one of our
|
||||
// lowers if we're just a template directory. Used for direct access for tar-split.
|
||||
func (d *Driver) DiffGetter(id string) (graphdriver.FileGetCloser, error) {
|
||||
p, err := d.getDiffPath(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fileGetNilCloser{storage.NewPathFileGetter(p)}, nil
|
||||
paths, err := d.getLowerDiffPaths(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &overlayFileGetter{diffDirs: append([]string{p}, paths...)}, nil
|
||||
}
|
||||
|
||||
// CleanupStagingDirectory cleanups the staging directory.
|
||||
@ -1958,12 +2054,31 @@ func (d *Driver) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMapp
|
||||
return nil
|
||||
}
|
||||
|
||||
// supportsIDmappedMounts returns whether the kernel supports using idmapped mounts with
|
||||
// overlay lower layers.
|
||||
func (d *Driver) supportsIDmappedMounts() bool {
|
||||
if d.supportsIDMappedMounts != nil {
|
||||
return *d.supportsIDMappedMounts
|
||||
}
|
||||
|
||||
supportsIDMappedMounts, err := checkAndRecordIDMappedSupport(d.home, d.runhome)
|
||||
d.supportsIDMappedMounts = &supportsIDMappedMounts
|
||||
if err == nil {
|
||||
return supportsIDMappedMounts
|
||||
}
|
||||
logrus.Debugf("Check for idmapped mounts support %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in an userNS
|
||||
func (d *Driver) SupportsShifting() bool {
|
||||
if os.Getenv("_TEST_FORCE_SUPPORT_SHIFTING") == "yes-please" {
|
||||
return true
|
||||
}
|
||||
return d.options.mountProgram != ""
|
||||
if d.options.mountProgram != "" {
|
||||
return true
|
||||
}
|
||||
return d.supportsIDmappedMounts()
|
||||
}
|
||||
|
||||
// dumbJoin is more or less a dumber version of filepath.Join, but one which
|
||||
@ -2132,3 +2247,15 @@ func redirectDiffIfAdditionalLayer(diffPath string) (string, error) {
|
||||
}
|
||||
return diffPath, nil
|
||||
}
|
||||
|
||||
// getMappedMountRoot is a heuristic that calculates the parent directory where
|
||||
// the idmapped mount should be applied.
|
||||
// It is useful to minimize the number of idmapped mounts and at the same time use
|
||||
// a common path as long as possible to reduce the length of the mount data argument.
|
||||
func getMappedMountRoot(path string) string {
|
||||
dirName := filepath.Dir(path)
|
||||
if filepath.Base(dirName) == linkDir {
|
||||
return filepath.Dir(dirName)
|
||||
}
|
||||
return dirName
|
||||
}
|
||||
|
||||
4
vendor/github.com/containers/storage/go.mod
generated
vendored
4
vendor/github.com/containers/storage/go.mod
generated
vendored
@ -6,7 +6,7 @@ require (
|
||||
github.com/BurntSushi/toml v1.1.0
|
||||
github.com/Microsoft/go-winio v0.5.2
|
||||
github.com/Microsoft/hcsshim v0.9.2
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.3
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.4
|
||||
github.com/cyphar/filepath-securejoin v0.2.3
|
||||
github.com/docker/go-units v0.4.0
|
||||
github.com/google/go-intervals v0.0.2
|
||||
@ -16,7 +16,7 @@ require (
|
||||
github.com/klauspost/pgzip v1.2.5
|
||||
github.com/mattn/go-shellwords v1.0.12
|
||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
|
||||
github.com/moby/sys/mountinfo v0.6.0
|
||||
github.com/moby/sys/mountinfo v0.6.1
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/runc v1.1.1
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
|
||||
|
||||
8
vendor/github.com/containers/storage/go.sum
generated
vendored
8
vendor/github.com/containers/storage/go.sum
generated
vendored
@ -176,8 +176,8 @@ github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFY
|
||||
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.3 h1:k2kN16Px6LYuv++qFqK+JTcYqc8bEVxzGpf8/gFBL5M=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.3/go.mod h1:7vRJIcImfY8bpifnMjt+HTJoQxASq7T28MYbP15/Nf0=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.4 h1:LjrYUZpyOhiSaU7hHrdR82/RBoxfGWSaC0VeSSMXqnk=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.11.4/go.mod h1:7vRJIcImfY8bpifnMjt+HTJoQxASq7T28MYbP15/Nf0=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
|
||||
@ -467,8 +467,8 @@ github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQ
|
||||
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/sys/mountinfo v0.6.0 h1:gUDhXQx58YNrpHlK4nSL+7y2pxFZkUcXqzFDKWdC0Oo=
|
||||
github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/sys/mountinfo v0.6.1 h1:+H/KnGEAGRpTrEAqNVQ2AM3SiwMgJUt/TXj+Z8cmCIc=
|
||||
github.com/moby/sys/mountinfo v0.6.1/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
|
||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
||||
65
vendor/github.com/containers/storage/layers.go
generated
vendored
65
vendor/github.com/containers/storage/layers.go
generated
vendored
@ -725,12 +725,32 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
|
||||
parent = parentLayer.ID
|
||||
}
|
||||
var parentMappings, templateIDMappings, oldMappings *idtools.IDMappings
|
||||
var (
|
||||
templateMetadata string
|
||||
templateCompressedDigest digest.Digest
|
||||
templateCompressedSize int64
|
||||
templateUncompressedDigest digest.Digest
|
||||
templateUncompressedSize int64
|
||||
templateCompressionType archive.Compression
|
||||
templateUIDs, templateGIDs []uint32
|
||||
templateTSdata []byte
|
||||
)
|
||||
if moreOptions.TemplateLayer != "" {
|
||||
var tserr error
|
||||
templateLayer, ok := r.lookup(moreOptions.TemplateLayer)
|
||||
if !ok {
|
||||
return nil, -1, ErrLayerUnknown
|
||||
}
|
||||
templateMetadata = templateLayer.Metadata
|
||||
templateIDMappings = idtools.NewIDMappingsFromMaps(templateLayer.UIDMap, templateLayer.GIDMap)
|
||||
templateCompressedDigest, templateCompressedSize = templateLayer.CompressedDigest, templateLayer.CompressedSize
|
||||
templateUncompressedDigest, templateUncompressedSize = templateLayer.UncompressedDigest, templateLayer.UncompressedSize
|
||||
templateCompressionType = templateLayer.CompressionType
|
||||
templateUIDs, templateGIDs = append([]uint32{}, templateLayer.UIDs...), append([]uint32{}, templateLayer.GIDs...)
|
||||
templateTSdata, tserr = ioutil.ReadFile(r.tspath(templateLayer.ID))
|
||||
if tserr != nil && !os.IsNotExist(tserr) {
|
||||
return nil, -1, tserr
|
||||
}
|
||||
} else {
|
||||
templateIDMappings = &idtools.IDMappings{}
|
||||
}
|
||||
@ -775,17 +795,43 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
|
||||
return nil, -1, err
|
||||
}
|
||||
}
|
||||
if len(templateTSdata) > 0 {
|
||||
if err := os.MkdirAll(filepath.Dir(r.tspath(id)), 0o700); err != nil {
|
||||
// We don't have a record of this layer, but at least
|
||||
// try to clean it up underneath us.
|
||||
if err2 := r.driver.Remove(id); err2 != nil {
|
||||
logrus.Errorf("While recovering from a failure creating in UpdateLayerIDMap, error deleting layer %#v: %v", id, err2)
|
||||
}
|
||||
return nil, -1, err
|
||||
}
|
||||
if err = ioutils.AtomicWriteFile(r.tspath(id), templateTSdata, 0o600); err != nil {
|
||||
// We don't have a record of this layer, but at least
|
||||
// try to clean it up underneath us.
|
||||
if err2 := r.driver.Remove(id); err2 != nil {
|
||||
logrus.Errorf("While recovering from a failure creating in UpdateLayerIDMap, error deleting layer %#v: %v", id, err2)
|
||||
}
|
||||
return nil, -1, err
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
layer = &Layer{
|
||||
ID: id,
|
||||
Parent: parent,
|
||||
Names: names,
|
||||
MountLabel: mountLabel,
|
||||
Created: time.Now().UTC(),
|
||||
Flags: make(map[string]interface{}),
|
||||
UIDMap: copyIDMap(moreOptions.UIDMap),
|
||||
GIDMap: copyIDMap(moreOptions.GIDMap),
|
||||
BigDataNames: []string{},
|
||||
ID: id,
|
||||
Parent: parent,
|
||||
Names: names,
|
||||
MountLabel: mountLabel,
|
||||
Metadata: templateMetadata,
|
||||
Created: time.Now().UTC(),
|
||||
CompressedDigest: templateCompressedDigest,
|
||||
CompressedSize: templateCompressedSize,
|
||||
UncompressedDigest: templateUncompressedDigest,
|
||||
UncompressedSize: templateUncompressedSize,
|
||||
CompressionType: templateCompressionType,
|
||||
UIDs: templateUIDs,
|
||||
GIDs: templateGIDs,
|
||||
Flags: make(map[string]interface{}),
|
||||
UIDMap: copyIDMap(moreOptions.UIDMap),
|
||||
GIDMap: copyIDMap(moreOptions.GIDMap),
|
||||
BigDataNames: []string{},
|
||||
}
|
||||
r.layers = append(r.layers, layer)
|
||||
r.idindex.Add(id)
|
||||
@ -872,7 +918,6 @@ func (r *layerStore) Mounted(id string) (int, error) {
|
||||
}
|
||||
|
||||
func (r *layerStore) Mount(id string, options drivers.MountOpts) (string, error) {
|
||||
|
||||
// check whether options include ro option
|
||||
hasReadOnlyOpt := func(opts []string) bool {
|
||||
for _, item := range opts {
|
||||
|
||||
10
vendor/github.com/containers/storage/store.go
generated
vendored
10
vendor/github.com/containers/storage/store.go
generated
vendored
@ -2452,6 +2452,10 @@ func (s *store) DeleteImage(id string, commit bool) (layers []string, err error)
|
||||
}
|
||||
layer := image.TopLayer
|
||||
layersToRemoveMap := make(map[string]struct{})
|
||||
layersToRemove = append(layersToRemove, image.MappedTopLayers...)
|
||||
for _, mappedTopLayer := range image.MappedTopLayers {
|
||||
layersToRemoveMap[mappedTopLayer] = struct{}{}
|
||||
}
|
||||
for layer != "" {
|
||||
if rcstore.Exists(layer) {
|
||||
break
|
||||
@ -2483,12 +2487,6 @@ func (s *store) DeleteImage(id string, commit bool) (layers []string, err error)
|
||||
if hasChildrenNotBeingRemoved() {
|
||||
break
|
||||
}
|
||||
if layer == image.TopLayer {
|
||||
layersToRemove = append(layersToRemove, image.MappedTopLayers...)
|
||||
for _, mappedTopLayer := range image.MappedTopLayers {
|
||||
layersToRemoveMap[mappedTopLayer] = struct{}{}
|
||||
}
|
||||
}
|
||||
layersToRemove = append(layersToRemove, layer)
|
||||
layersToRemoveMap[layer] = struct{}{}
|
||||
layer = parent
|
||||
|
||||
8
vendor/github.com/containers/storage/utils.go
generated
vendored
8
vendor/github.com/containers/storage/utils.go
generated
vendored
@ -42,13 +42,14 @@ func validateMountOptions(mountOptions []string) error {
|
||||
}
|
||||
|
||||
func applyNameOperation(oldNames []string, opParameters []string, op updateNameOperation) ([]string, error) {
|
||||
result := make([]string, 0)
|
||||
var result []string
|
||||
switch op {
|
||||
case setNames:
|
||||
// ignore all old names and just return new names
|
||||
return dedupeNames(opParameters), nil
|
||||
result = opParameters
|
||||
case removeNames:
|
||||
// remove given names from old names
|
||||
result = make([]string, 0, len(oldNames))
|
||||
for _, name := range oldNames {
|
||||
// only keep names in final result which do not intersect with input names
|
||||
// basically `result = oldNames - opParameters`
|
||||
@ -62,11 +63,10 @@ func applyNameOperation(oldNames []string, opParameters []string, op updateNameO
|
||||
result = append(result, name)
|
||||
}
|
||||
}
|
||||
return dedupeNames(result), nil
|
||||
case addNames:
|
||||
result = make([]string, 0, len(opParameters)+len(oldNames))
|
||||
result = append(result, opParameters...)
|
||||
result = append(result, oldNames...)
|
||||
return dedupeNames(result), nil
|
||||
default:
|
||||
return result, errInvalidUpdateNameOperation
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user