diff -Nru golang-github-containers-storage-1.36.0+ds1/.cirrus.yml golang-github-containers-storage-1.37.2+ds1/.cirrus.yml --- golang-github-containers-storage-1.36.0+ds1/.cirrus.yml 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/.cirrus.yml 2022-04-21 18:58:04.000000000 +0000 @@ -20,16 +20,14 @@ FEDORA_NAME: "fedora-34" PRIOR_FEDORA_NAME: "fedora-33" UBUNTU_NAME: "ubuntu-2104" - PRIOR_UBUNTU_NAME: "ubuntu-2010" # GCE project where images live IMAGE_PROJECT: "libpod-218412" # VM Image built in containers/automation_images - _BUILT_IMAGE_SUFFIX: "c6248193773010944" + _BUILT_IMAGE_SUFFIX: "c6431352024203264" FEDORA_CACHE_IMAGE_NAME: "fedora-${_BUILT_IMAGE_SUFFIX}" PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${_BUILT_IMAGE_SUFFIX}" UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${_BUILT_IMAGE_SUFFIX}" - PRIOR_UBUNTU_CACHE_IMAGE_NAME: "prior-ubuntu-${_BUILT_IMAGE_SUFFIX}" #### #### Command variables to help avoid duplication @@ -115,15 +113,6 @@ TEST_DRIVER: "overlay" -prior_ubuntu_testing_task: - <<: *ubuntu_testing - alias: prior_ubuntu_testing - name: *std_test_name - env: - OS_NAME: "${PRIOR_UBUNTU_NAME}" - VM_IMAGE: "${PRIOR_UBUNTU_CACHE_IMAGE_NAME}" - - lint_task: env: CIRRUS_WORKING_DIR: "/go/src/github.com/containers/storage" @@ -153,7 +142,6 @@ ${FEDORA_CACHE_IMAGE_NAME} ${PRIOR_FEDORA_CACHE_IMAGE_NAME} ${UBUNTU_CACHE_IMAGE_NAME} - ${PRIOR_UBUNTU_CACHE_IMAGE_NAME} BUILDID: "${CIRRUS_BUILD_ID}" REPOREF: "${CIRRUS_CHANGE_IN_REPO}" GCPJSON: ENCRYPTED[244a93fe8b386b48b96f748342bf741350e43805eee81dd04b45093bdf737e540b993fc735df41f131835fa0f9b65826] @@ -181,7 +169,6 @@ - fedora_testing - prior_fedora_testing - ubuntu_testing - - prior_ubuntu_testing - meta - vendor container: diff -Nru golang-github-containers-storage-1.36.0+ds1/cmd/containers-storage/container.go golang-github-containers-storage-1.37.2+ds1/cmd/containers-storage/container.go --- golang-github-containers-storage-1.36.0+ds1/cmd/containers-storage/container.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/cmd/containers-storage/container.go 2022-04-21 18:58:04.000000000 +0000 @@ -211,12 +211,8 @@ json.NewEncoder(os.Stdout).Encode(mappings) } else { fmt.Printf("ID: %s\n", container.ID) - if len(uids) > 0 { - fmt.Printf("UIDs: %v\n", uids) - } - if len(gids) > 0 { - fmt.Printf("GIDs: %v\n", gids) - } + fmt.Printf("UIDs: %v\n", uids) + fmt.Printf("GIDs: %v\n", gids) } } if len(matched) != len(args) { diff -Nru golang-github-containers-storage-1.36.0+ds1/debian/changelog golang-github-containers-storage-1.37.2+ds1/debian/changelog --- golang-github-containers-storage-1.36.0+ds1/debian/changelog 2021-11-06 15:40:57.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/debian/changelog 2022-04-21 18:58:58.000000000 +0000 @@ -1,3 +1,16 @@ +golang-github-containers-storage (1.37.2+ds1-1) unstable; urgency=medium + + * New upstream release. + Exposes "RawTo{Container,Host}", required to resolve CVE-2022-1227. + + -- Reinhard Tartler Thu, 21 Apr 2022 14:58:58 -0400 + +golang-github-containers-storage (1.37.1+ds1-1) unstable; urgency=medium + + * New upstream release. + + -- Reinhard Tartler Wed, 13 Apr 2022 20:56:37 -0400 + golang-github-containers-storage (1.36.0+ds1-3) unstable; urgency=medium * re-enable estargz support diff -Nru golang-github-containers-storage-1.36.0+ds1/debian/gitlab-ci.yml golang-github-containers-storage-1.37.2+ds1/debian/gitlab-ci.yml --- golang-github-containers-storage-1.36.0+ds1/debian/gitlab-ci.yml 1970-01-01 00:00:00.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/debian/gitlab-ci.yml 2022-04-21 18:58:58.000000000 +0000 @@ -0,0 +1,6 @@ +# auto-generated, DO NOT MODIFY. +# The authoritative copy of this file lives at: +# https://salsa.debian.org/go-team/infra/pkg-go-tools/blob/master/config/gitlabciyml.go +--- +include: + - https://salsa.debian.org/go-team/infra/pkg-go-tools/-/raw/master/pipeline/test-archive.yml diff -Nru golang-github-containers-storage-1.36.0+ds1/drivers/aufs/aufs.go golang-github-containers-storage-1.37.2+ds1/drivers/aufs/aufs.go --- golang-github-containers-storage-1.36.0+ds1/drivers/aufs/aufs.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/drivers/aufs/aufs.go 2022-04-21 18:58:04.000000000 +0000 @@ -730,14 +730,14 @@ enableDirpermLock.Do(func() { base, err := ioutil.TempDir("", "storage-aufs-base") if err != nil { - logrus.Errorf("error checking dirperm1: %v", err) + logrus.Errorf("Checking dirperm1: %v", err) return } defer os.RemoveAll(base) union, err := ioutil.TempDir("", "storage-aufs-union") if err != nil { - logrus.Errorf("error checking dirperm1: %v", err) + logrus.Errorf("Checking dirperm1: %v", err) return } defer os.RemoveAll(union) @@ -748,7 +748,7 @@ } enableDirperm = true if err := Unmount(union); err != nil { - logrus.Errorf("error checking dirperm1: failed to unmount %v", err) + logrus.Errorf("Checking dirperm1: failed to unmount %v", err) } }) return enableDirperm diff -Nru golang-github-containers-storage-1.36.0+ds1/drivers/driver_linux.go golang-github-containers-storage-1.37.2+ds1/drivers/driver_linux.go --- golang-github-containers-storage-1.36.0+ds1/drivers/driver_linux.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/drivers/driver_linux.go 2022-04-21 18:58:04.000000000 +0000 @@ -50,6 +50,40 @@ FsMagicOverlay = FsMagic(0x794C7630) // FsMagicFUSE filesystem id for FUSE FsMagicFUSE = FsMagic(0x65735546) + // FsMagicAcfs filesystem id for Acfs + FsMagicAcfs = FsMagic(0x61636673) + // FsMagicAfs filesystem id for Afs + FsMagicAfs = FsMagic(0x5346414f) + // FsMagicCephFs filesystem id for Ceph + FsMagicCephFs = FsMagic(0x00C36400) + // FsMagicCIFS filesystem id for CIFS + FsMagicCIFS = FsMagic(0xFF534D42) + // FsMagicFHGFS filesystem id for FHGFS + FsMagicFHGFSFs = FsMagic(0x19830326) + // FsMagicIBRIX filesystem id for IBRIX + FsMagicIBRIX = FsMagic(0x013111A8) + // FsMagicKAFS filesystem id for KAFS + FsMagicKAFS = FsMagic(0x6B414653) + // FsMagicLUSTRE filesystem id for LUSTRE + FsMagicLUSTRE = FsMagic(0x0BD00BD0) + // FsMagicNCP filesystem id for NCP + FsMagicNCP = FsMagic(0x564C) + // FsMagicNFSD filesystem id for NFSD + FsMagicNFSD = FsMagic(0x6E667364) + // FsMagicOCFS2 filesystem id for OCFS2 + FsMagicOCFS2 = FsMagic(0x7461636F) + // FsMagicPANFS filesystem id for PANFS + FsMagicPANFS = FsMagic(0xAAD7AAEA) + // FsMagicPRLFS filesystem id for PRLFS + FsMagicPRLFS = FsMagic(0x7C7C6673) + // FsMagicSMB2 filesystem id for SMB2 + FsMagicSMB2 = FsMagic(0xFE534D42) + // FsMagicSNFS filesystem id for SNFS + FsMagicSNFS = FsMagic(0xBEEFDEAD) + // FsMagicVBOXSF filesystem id for VBOXSF + FsMagicVBOXSF = FsMagic(0x786F4256) + // FsMagicVXFS filesystem id for VXFS + FsMagicVXFS = FsMagic(0xA501FCF5) ) var ( diff -Nru golang-github-containers-storage-1.36.0+ds1/drivers/fsdiff.go golang-github-containers-storage-1.37.2+ds1/drivers/fsdiff.go --- golang-github-containers-storage-1.36.0+ds1/drivers/fsdiff.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/drivers/fsdiff.go 2022-04-21 18:58:04.000000000 +0000 @@ -180,7 +180,7 @@ start := time.Now().UTC() logrus.Debug("Start untar layer") if size, err = ApplyUncompressedLayer(layerFs, options.Diff, tarOptions); err != nil { - logrus.Errorf("Error while applying layer: %s", err) + logrus.Errorf("While applying layer: %s", err) return } logrus.Debugf("Untar time: %vs", time.Now().UTC().Sub(start).Seconds()) diff -Nru golang-github-containers-storage-1.36.0+ds1/drivers/overlay/overlay.go golang-github-containers-storage-1.37.2+ds1/drivers/overlay/overlay.go --- golang-github-containers-storage-1.36.0+ds1/drivers/overlay/overlay.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/drivers/overlay/overlay.go 2022-04-21 18:58:04.000000000 +0000 @@ -174,21 +174,21 @@ var usingVolatile bool if err == nil { if volatileCacheResult { - logrus.Debugf("cached value indicated that volatile is being used") + logrus.Debugf("Cached value indicated that volatile is being used") } else { - logrus.Debugf("cached value indicated that volatile is not being used") + logrus.Debugf("Cached value indicated that volatile is not being used") } usingVolatile = volatileCacheResult } else { usingVolatile, err = doesVolatile(home) if err == nil { if usingVolatile { - logrus.Debugf("overlay test mount indicated that volatile is being used") + logrus.Debugf("overlay: test mount indicated that volatile is being used") } else { - logrus.Debugf("overlay test mount indicated that volatile is not being used") + logrus.Debugf("overlay: test mount indicated that volatile is not being used") } if err = cachedFeatureRecord(runhome, feature, usingVolatile, ""); err != nil { - return false, errors.Wrap(err, "error recording volatile-being-used status") + return false, errors.Wrap(err, "recording volatile-being-used status") } } } @@ -206,9 +206,9 @@ overlayCacheResult, overlayCacheText, err := cachedFeatureCheck(runhome, feature) if err == nil { if overlayCacheResult { - logrus.Debugf("cached value indicated that overlay is supported") + logrus.Debugf("Cached value indicated that overlay is supported") } else { - logrus.Debugf("cached value indicated that overlay is not supported") + logrus.Debugf("Cached value indicated that overlay is not supported") } supportsDType = overlayCacheResult if !supportsDType { @@ -225,12 +225,12 @@ } err = errors.Wrap(err, "kernel does not support overlay fs") if err2 := cachedFeatureRecord(runhome, feature, false, err.Error()); err2 != nil { - return false, errors.Wrapf(err2, "error recording overlay not being supported (%v)", err) + return false, errors.Wrapf(err2, "recording overlay not being supported (%v)", err) } return false, err } if err = cachedFeatureRecord(runhome, feature, supportsDType, ""); err != nil { - return false, errors.Wrap(err, "error recording overlay support status") + return false, errors.Wrap(err, "recording overlay support status") } } return supportsDType, nil @@ -248,6 +248,23 @@ return supportsVolatile, nil } +// isNetworkFileSystem checks if the specified file system is supported by native overlay +// as backing store when running in a user namespace. +func isNetworkFileSystem(fsMagic graphdriver.FsMagic) bool { + switch fsMagic { + // a bunch of network file systems... + case graphdriver.FsMagicNfsFs, graphdriver.FsMagicSmbFs, graphdriver.FsMagicAcfs, + graphdriver.FsMagicAfs, graphdriver.FsMagicCephFs, graphdriver.FsMagicCIFS, + graphdriver.FsMagicFHGFSFs, graphdriver.FsMagicGPFS, graphdriver.FsMagicIBRIX, + graphdriver.FsMagicKAFS, graphdriver.FsMagicLUSTRE, graphdriver.FsMagicNCP, + graphdriver.FsMagicNFSD, graphdriver.FsMagicOCFS2, graphdriver.FsMagicPANFS, + graphdriver.FsMagicPRLFS, graphdriver.FsMagicSMB2, graphdriver.FsMagicSNFS, + graphdriver.FsMagicVBOXSF, graphdriver.FsMagicVXFS: + return true + } + return false +} + // Init returns the a native diff driver for overlay filesystem. // If overlay filesystem is not supported on the host, a wrapped graphdriver.ErrNotSupported is returned as error. // If an overlay filesystem is not supported over an existing filesystem then a wrapped graphdriver.ErrIncompatibleFS is returned. @@ -265,33 +282,53 @@ backingFs = fsName } + runhome := filepath.Join(options.RunRoot, filepath.Base(home)) + rootUID, rootGID, err := idtools.GetRootUIDGID(options.UIDMaps, options.GIDMaps) + if err != nil { + return nil, err + } + + // Create the driver home dir + if err := idtools.MkdirAllAs(path.Join(home, linkDir), 0700, rootUID, rootGID); err != nil { + return nil, err + } + + if err := idtools.MkdirAllAs(runhome, 0700, rootUID, rootGID); err != nil { + return nil, err + } + + if opts.mountProgram == "" { + if supported, err := SupportsNativeOverlay(home, runhome); err != nil { + return nil, err + } else if !supported { + if path, err := exec.LookPath("fuse-overlayfs"); err == nil { + opts.mountProgram = path + } + } + } + if opts.mountProgram != "" { + if unshare.IsRootless() && isNetworkFileSystem(fsMagic) && opts.forceMask == nil { + m := os.FileMode(0700) + opts.forceMask = &m + logrus.Warnf("Network file system detected as backing store. Enforcing overlay option `force_mask=\"%o\"`. Add it to storage.conf to silence this warning", m) + } + if err := ioutil.WriteFile(getMountProgramFlagFile(home), []byte("true"), 0600); err != nil { return nil, err } } else { - // check if they are running over btrfs, aufs, zfs, overlay, or ecryptfs if opts.forceMask != nil { return nil, errors.New("'force_mask' is supported only with 'mount_program'") } + // check if they are running over btrfs, aufs, zfs, overlay, or ecryptfs switch fsMagic { case graphdriver.FsMagicAufs, graphdriver.FsMagicZfs, graphdriver.FsMagicOverlay, graphdriver.FsMagicEcryptfs: return nil, errors.Wrapf(graphdriver.ErrIncompatibleFS, "'overlay' is not supported over %s, a mount_program is required", backingFs) } - } - - rootUID, rootGID, err := idtools.GetRootUIDGID(options.UIDMaps, options.GIDMaps) - if err != nil { - return nil, err - } - - // Create the driver home dir - if err := idtools.MkdirAllAs(path.Join(home, linkDir), 0700, rootUID, rootGID); err != nil { - return nil, err - } - runhome := filepath.Join(options.RunRoot, filepath.Base(home)) - if err := idtools.MkdirAllAs(runhome, 0700, rootUID, rootGID); err != nil { - return nil, err + if unshare.IsRootless() && isNetworkFileSystem(fsMagic) { + return nil, errors.Wrapf(graphdriver.ErrIncompatibleFS, "A network file system with user namespaces is not supported. Please use a mount_program") + } } var usingMetacopy bool @@ -310,24 +347,24 @@ metacopyCacheResult, _, err := cachedFeatureCheck(runhome, feature) if err == nil { if metacopyCacheResult { - logrus.Debugf("cached value indicated that metacopy is being used") + logrus.Debugf("Cached value indicated that metacopy is being used") } else { - logrus.Debugf("cached value indicated that metacopy is not being used") + logrus.Debugf("Cached value indicated that metacopy is not being used") } usingMetacopy = metacopyCacheResult } else { usingMetacopy, err = doesMetacopy(home, opts.mountOptions) if err == nil { if usingMetacopy { - logrus.Debugf("overlay test mount indicated that metacopy is being used") + logrus.Debugf("overlay: test mount indicated that metacopy is being used") } else { - logrus.Debugf("overlay test mount indicated that metacopy is not being used") + logrus.Debugf("overlay: test mount indicated that metacopy is not being used") } if err = cachedFeatureRecord(runhome, feature, usingMetacopy, ""); err != nil { - return nil, errors.Wrap(err, "error recording metacopy-being-used status") + return nil, errors.Wrap(err, "recording metacopy-being-used status") } } else { - logrus.Infof("overlay test mount did not indicate whether or not metacopy is being used: %v", err) + logrus.Infof("overlay: test mount did not indicate whether or not metacopy is being used: %v", err) return nil, err } } @@ -533,14 +570,11 @@ return err } -func SupportsNativeOverlay(graphroot, rundir string) (bool, error) { - if os.Geteuid() != 0 || graphroot == "" || rundir == "" { +func SupportsNativeOverlay(home, runhome string) (bool, error) { + if os.Geteuid() != 0 || home == "" || runhome == "" { return false, nil } - home := filepath.Join(graphroot, "overlay") - runhome := filepath.Join(rundir, "overlay") - var contents string flagContent, err := ioutil.ReadFile(getMountProgramFlagFile(home)) if err == nil { @@ -548,7 +582,7 @@ } switch contents { case "true": - logrus.Debugf("overlay storage already configured with a mount-program") + logrus.Debugf("overlay: storage already configured with a mount-program") return false, nil default: needsMountProgram, err := scanForMountProgramIndicators(home) @@ -640,17 +674,17 @@ flags = fmt.Sprintf("%s,userxattr", flags) } if err := syscall.Mknod(filepath.Join(upperDir, "whiteout"), syscall.S_IFCHR|0600, int(unix.Mkdev(0, 0))); err != nil { - logrus.Debugf("unable to create kernel-style whiteout: %v", err) + logrus.Debugf("Unable to create kernel-style whiteout: %v", err) return supportsDType, errors.Wrapf(err, "unable to create kernel-style whiteout") } if len(flags) < unix.Getpagesize() { err := unix.Mount("overlay", mergedDir, "overlay", 0, flags) if err == nil { - logrus.Debugf("overlay test mount with multiple lowers succeeded") + logrus.Debugf("overlay: test mount with multiple lowers succeeded") return supportsDType, nil } - logrus.Debugf("overlay test mount with multiple lowers failed %v", err) + logrus.Debugf("overlay: test mount with multiple lowers failed %v", err) } flags = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lower1Dir, upperDir, workDir) if selinux.GetEnabled() { @@ -659,10 +693,10 @@ if len(flags) < unix.Getpagesize() { err := unix.Mount("overlay", mergedDir, "overlay", 0, flags) if err == nil { - logrus.StandardLogger().Logf(logLevel, "overlay test mount with multiple lowers failed, but succeeded with a single lower") + logrus.StandardLogger().Logf(logLevel, "overlay: test mount with multiple lowers failed, but succeeded with a single lower") return supportsDType, errors.Wrap(graphdriver.ErrNotSupported, "kernel too old to provide multiple lowers feature for overlay") } - logrus.Debugf("overlay test mount with a single lower failed %v", err) + logrus.Debugf("overlay: test mount with a single lower failed %v", err) } logrus.StandardLogger().Logf(logLevel, "'overlay' is not supported over %s at %q", backingFs, home) return supportsDType, errors.Wrapf(graphdriver.ErrIncompatibleFS, "'overlay' is not supported over %s at %q", backingFs, home) @@ -682,9 +716,9 @@ nativeDiffCacheResult, nativeDiffCacheText, err := cachedFeatureCheck(d.runhome, feature) if err == nil { if nativeDiffCacheResult { - logrus.Debugf("cached value indicated that native-diff is usable") + logrus.Debugf("Cached value indicated that native-diff is usable") } else { - logrus.Debugf("cached value indicated that native-diff is not being used") + logrus.Debugf("Cached value indicated that native-diff is not being used") logrus.Info(nativeDiffCacheText) } useNaiveDiffOnly = !nativeDiffCacheResult @@ -821,7 +855,7 @@ opts.StorageOpt["inodes"] = strconv.FormatUint(d.options.quota.Inodes, 10) } - return d.create(id, parent, opts) + return d.create(id, parent, opts, false) } // Create is used to create the upper, lower, and merge directories required for overlay fs for a given id. @@ -831,15 +865,16 @@ if _, ok := opts.StorageOpt["size"]; ok { return fmt.Errorf("--storage-opt size is only supported for ReadWrite Layers") } + if _, ok := opts.StorageOpt["inodes"]; ok { return fmt.Errorf("--storage-opt inodes is only supported for ReadWrite Layers") } } - return d.create(id, parent, opts) + return d.create(id, parent, opts, true) } -func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr error) { +func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, disableQuota bool) (retErr error) { dir := d.dir(id) uidMaps := d.uidMaps @@ -880,7 +915,7 @@ } }() - if d.quotaCtl != nil { + if d.quotaCtl != nil && !disableQuota { quota := quota.Quota{} if opts != nil && len(opts.StorageOpt) > 0 { driver := &Driver{} @@ -994,7 +1029,7 @@ } logrus.Warnf("Can't read parent link %q because it does not exist. Going through storage to recreate the missing links.", path.Join(parentDir, "link")) if err := d.recreateSymlinks(); err != nil { - return "", errors.Wrap(err, "error recreating the links") + return "", errors.Wrap(err, "recreating the links") } parentLink, err = ioutil.ReadFile(path.Join(parentDir, "link")) if err != nil { @@ -1038,7 +1073,7 @@ if os.IsNotExist(err) { logrus.Warnf("Can't read link %q because it does not exist. A storage corruption might have occurred, attempting to recreate the missing symlinks. It might be best wipe the storage to avoid further errors due to storage corruption.", lower) if err := d.recreateSymlinks(); err != nil { - return nil, fmt.Errorf("error recreating the missing symlinks: %v", err) + return nil, fmt.Errorf("recreating the missing symlinks: %v", err) } // let's call Readlink on lower again now that we have recreated the missing symlinks lp, err = os.Readlink(lower) @@ -1121,7 +1156,7 @@ // List all the directories under the home directory dirs, err := ioutil.ReadDir(d.home) if err != nil { - return fmt.Errorf("error reading driver home directory %q: %v", d.home, err) + return fmt.Errorf("reading driver home directory %q: %v", d.home, err) } linksDir := filepath.Join(d.home, "l") // This makes the link directory if it doesn't exist @@ -1148,7 +1183,7 @@ // Read the "link" file under each layer to get the name of the symlink data, err := ioutil.ReadFile(path.Join(d.dir(dir.Name()), "link")) if err != nil { - errs = multierror.Append(errs, errors.Wrapf(err, "error reading name of symlink for %q", dir)) + errs = multierror.Append(errs, errors.Wrapf(err, "reading name of symlink for %q", dir)) continue } linkPath := path.Join(d.home, linkDir, strings.Trim(string(data), "\n")) @@ -1162,7 +1197,7 @@ } madeProgress = true } else if err != nil { - errs = multierror.Append(errs, errors.Wrapf(err, "error trying to stat %q", linkPath)) + errs = multierror.Append(errs, err) continue } } @@ -1170,7 +1205,7 @@ // that each symlink we have corresponds to one. links, err := ioutil.ReadDir(linksDir) if err != nil { - errs = multierror.Append(errs, errors.Wrapf(err, "error reading links directory %q", linksDir)) + errs = multierror.Append(errs, err) continue } // Go through all of the symlinks in the "l" directory @@ -1178,7 +1213,7 @@ // Read the symlink's target, which should be "../$layer/diff" target, err := os.Readlink(filepath.Join(linksDir, link.Name())) if err != nil { - errs = multierror.Append(errs, errors.Wrapf(err, "error reading target of link %q", link)) + errs = multierror.Append(errs, err) continue } targetComponents := strings.Split(target, string(os.PathSeparator)) @@ -1196,7 +1231,7 @@ data, err := ioutil.ReadFile(linkFile) if err != nil || string(data) != link.Name() { if err := ioutil.WriteFile(linkFile, []byte(link.Name()), 0644); err != nil { - errs = multierror.Append(errs, errors.Wrapf(err, "error correcting link for layer %q", targetID)) + errs = multierror.Append(errs, errors.Wrapf(err, "correcting link for layer %s", targetID)) continue } madeProgress = true @@ -1241,7 +1276,7 @@ if unshare.IsRootless() { logLevel = logrus.DebugLevel } - logrus.StandardLogger().Logf(logLevel, "ignoring metacopy option from storage.conf, not supported with booted kernel") + logrus.StandardLogger().Logf(logLevel, "Ignoring metacopy option from storage.conf, not supported with booted kernel") } } } @@ -1275,7 +1310,7 @@ } logrus.Warnf("Can't read parent link %q because it does not exist. Going through storage to recreate the missing links.", path.Join(dir, "link")) if err := d.recreateSymlinks(); err != nil { - return "", errors.Wrap(err, "error recreating the links") + return "", errors.Wrap(err, "recreating the links") } link, err = ioutil.ReadFile(path.Join(dir, "link")) if err != nil { @@ -1330,7 +1365,7 @@ if lower == "" && os.IsNotExist(err) { logrus.Warnf("Can't stat lower layer %q because it does not exist. Going through storage to recreate the missing symlinks.", newpath) if err := d.recreateSymlinks(); err != nil { - return "", fmt.Errorf("error recreating the missing symlinks: %v", err) + return "", fmt.Errorf("Recreating the missing symlinks: %v", err) } lower = newpath } else if lower == "" { @@ -1381,7 +1416,7 @@ if retErr != nil { if c := d.ctr.Decrement(mergedDir); c <= 0 { if mntErr := unix.Unmount(mergedDir, 0); mntErr != nil { - logrus.Errorf("error unmounting %v: %v", mergedDir, mntErr) + logrus.Errorf("Unmounting %v: %v", mergedDir, mntErr) } } } @@ -1430,6 +1465,11 @@ label = d.optsAppendMappings(label, options.UidMaps, options.GidMaps) } + // if forceMask is in place, tell fuse-overlayfs to write the permissions mask to an unprivileged xattr as well. + if d.options.forceMask != nil { + label = label + ",xattr_permissions=2" + } + mountProgram := exec.Command(d.options.mountProgram, "-o", label, target) mountProgram.Dir = d.home var b bytes.Buffer @@ -1473,7 +1513,7 @@ flags, data := mount.ParseOptions(mountData) logrus.Debugf("overlay: mount_data=%s", mountData) if err := mountFunc("overlay", mountTarget, "overlay", uintptr(flags), data); err != nil { - return "", fmt.Errorf("error creating overlay mount to %s, mount_data=%q: %v", mountTarget, mountData, err) + return "", fmt.Errorf("creating overlay mount to %s, mount_data=%q: %v", mountTarget, mountData, err) } return mergedDir, nil @@ -1820,7 +1860,7 @@ err = graphdriver.ChownPathByMaps(layerFs, toContainer, toHost) if err != nil { if err2 := d.Put(id); err2 != nil { - logrus.Errorf("%v; error unmounting %v: %v", err, id, err2) + logrus.Errorf("%v; unmounting %v: %v", err, id, err2) } return err } @@ -1923,7 +1963,7 @@ if al, err := d.getAdditionalLayerPathByID(id); err == nil { notifyReleaseAdditionalLayer(al) } else if !os.IsNotExist(err) { - logrus.Warnf("unexpected error on reading Additional Layer Store pointer %v", err) + logrus.Warnf("Unexpected error on reading Additional Layer Store pointer %v", err) } } @@ -2004,10 +2044,10 @@ } else if err == nil { f.Close() if err := os.Remove(useFile); err != nil { - logrus.Warnf("failed to remove use file") + logrus.Warnf("Failed to remove use file") } } - logrus.Warnf("unexpected error by Additional Layer Store %v during use; GC doesn't seem to be supported", err) + logrus.Warnf("Unexpected error by Additional Layer Store %v during use; GC doesn't seem to be supported", err) } // notifyReleaseAdditionalLayer notifies Additional Layer Store that we don't use the specified @@ -2024,7 +2064,7 @@ if os.IsNotExist(err) { return } - logrus.Warnf("unexpected error by Additional Layer Store %v during release; GC doesn't seem to be supported", err) + logrus.Warnf("Unexpected error by Additional Layer Store %v during release; GC doesn't seem to be supported", err) } // redirectDiffIfAdditionalLayer checks if the passed diff path is Additional Layer and diff -Nru golang-github-containers-storage-1.36.0+ds1/drivers/overlay/randomid.go golang-github-containers-storage-1.37.2+ds1/drivers/overlay/randomid.go --- golang-github-containers-storage-1.36.0+ds1/drivers/overlay/randomid.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/drivers/overlay/randomid.go 2022-04-21 18:58:04.000000000 +0000 @@ -47,7 +47,7 @@ if retryOnError(err) && retries < maxretries { count += n retries++ - logrus.Errorf("error generating version 4 uuid, retrying: %v", err) + logrus.Errorf("Generating version 4 uuid, retrying: %v", err) continue } diff -Nru golang-github-containers-storage-1.36.0+ds1/drivers/template.go golang-github-containers-storage-1.37.2+ds1/drivers/template.go --- golang-github-containers-storage-1.36.0+ds1/drivers/template.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/drivers/template.go 2022-04-21 18:58:04.000000000 +0000 @@ -31,7 +31,7 @@ diff, err := d.Diff(template, templateIDMappings, parent, parentIDMappings, opts.MountLabel) if err != nil { if err2 := d.Remove(id); err2 != nil { - logrus.Errorf("error removing layer %q: %v", id, err2) + logrus.Errorf("Removing layer %q: %v", id, err2) } return err } @@ -44,7 +44,7 @@ } if _, err = d.ApplyDiff(id, parent, applyOptions); err != nil { if err2 := d.Remove(id); err2 != nil { - logrus.Errorf("error removing layer %q: %v", id, err2) + logrus.Errorf("Removing layer %q: %v", id, err2) } return err } diff -Nru golang-github-containers-storage-1.36.0+ds1/go.mod golang-github-containers-storage-1.37.2+ds1/go.mod --- golang-github-containers-storage-1.36.0+ds1/go.mod 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/go.mod 2022-04-21 18:58:04.000000000 +0000 @@ -6,20 +6,19 @@ github.com/BurntSushi/toml v0.4.1 github.com/Microsoft/go-winio v0.5.0 github.com/Microsoft/hcsshim v0.8.22 - github.com/containerd/stargz-snapshotter/estargz v0.8.0 + github.com/containerd/stargz-snapshotter/estargz v0.9.0 github.com/docker/go-units v0.4.0 github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/google/go-intervals v0.0.2 github.com/google/uuid v1.2.0 // indirect github.com/hashicorp/go-multierror v1.1.1 - github.com/json-iterator/go v1.1.11 - github.com/klauspost/compress v1.13.5 + github.com/json-iterator/go v1.1.12 + github.com/klauspost/compress v1.13.6 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.4.1 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.1 // indirect github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/runc v1.0.2 github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 diff -Nru golang-github-containers-storage-1.36.0+ds1/go.sum golang-github-containers-storage-1.37.2+ds1/go.sum --- golang-github-containers-storage-1.36.0+ds1/go.sum 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/go.sum 2022-04-21 18:58:04.000000000 +0000 @@ -31,8 +31,8 @@ github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= -github.com/containerd/stargz-snapshotter/estargz v0.8.0 h1:oA1wx8kTFfImfsT5bScbrZd8gK+WtQnn15q82Djvm0Y= -github.com/containerd/stargz-snapshotter/estargz v0.8.0/go.mod h1:mwIwuwb+D8FX2t45Trwi0hmWmZm5VW7zPP/rekwhWQU= +github.com/containerd/stargz-snapshotter/estargz v0.9.0 h1:PkB6BSTfOKX23erT2GkoUKkJEcXfNcyKskIViK770v8= +github.com/containerd/stargz-snapshotter/estargz v0.9.0/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0= github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -115,15 +115,15 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.13.5 h1:9O69jUPDcsT9fEm74W92rZL9FQY7rCdaXVneq+yyzl4= -github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -148,9 +148,8 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= diff -Nru golang-github-containers-storage-1.36.0+ds1/layers.go golang-github-containers-storage-1.37.2+ds1/layers.go --- golang-github-containers-storage-1.36.0+ds1/layers.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/layers.go 2022-04-21 18:58:04.000000000 +0000 @@ -1557,7 +1557,7 @@ compressor = pgzip.NewWriter(&tsdata) } if err := compressor.SetConcurrency(1024*1024, 1); err != nil { // 1024*1024 is the hard-coded default; we're not changing that - logrus.Infof("error setting compression concurrency threads to 1: %v; ignoring", err) + logrus.Infof("Error setting compression concurrency threads to 1: %v; ignoring", err) } metadata := storage.NewJSONPacker(compressor) uncompressed, err := archive.DecompressStream(defragmented) diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/archive/archive.go golang-github-containers-storage-1.37.2+ds1/pkg/archive/archive.go --- golang-github-containers-storage-1.36.0+ds1/pkg/archive/archive.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/archive/archive.go 2022-04-21 18:58:04.000000000 +0000 @@ -879,7 +879,7 @@ if include != relFilePath { matches, err := pm.IsMatch(relFilePath) if err != nil { - logrus.Errorf("Error matching %s: %v", relFilePath, err) + logrus.Errorf("Matching %s: %v", relFilePath, err) return err } skip = matches diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/chunked/storage_linux.go golang-github-containers-storage-1.37.2+ds1/pkg/chunked/storage_linux.go --- golang-github-containers-storage-1.36.0+ds1/pkg/chunked/storage_linux.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/chunked/storage_linux.go 2022-04-21 18:58:04.000000000 +0000 @@ -345,6 +345,56 @@ return digester.Digest(), nil } +// findFileInOSTreeRepos checks whether the requested file already exist in one of the OSTree repo and copies the file content from there if possible. +// file is the file to look for. +// ostreeRepos is a list of OSTree repos. +// dirfd is an open fd to the destination checkout. +// useHardLinks defines whether the deduplication can be performed using hard links. +func findFileInOSTreeRepos(file *internal.FileMetadata, ostreeRepos []string, dirfd int, useHardLinks bool) (bool, *os.File, int64, error) { + digest, err := digest.Parse(file.Digest) + if err != nil { + return false, nil, 0, nil + } + payloadLink := digest.Encoded() + ".payload-link" + if len(payloadLink) < 2 { + return false, nil, 0, nil + } + + for _, repo := range ostreeRepos { + sourceFile := filepath.Join(repo, "objects", payloadLink[:2], payloadLink[2:]) + st, err := os.Stat(sourceFile) + if err != nil || !st.Mode().IsRegular() { + continue + } + if st.Size() != file.Size { + continue + } + fd, err := unix.Open(sourceFile, unix.O_RDONLY|unix.O_NONBLOCK, 0) + if err != nil { + return false, nil, 0, nil + } + f := os.NewFile(uintptr(fd), "fd") + defer f.Close() + + // check if the open file can be deduplicated with hard links + if useHardLinks && !canDedupFileWithHardLink(file, fd, st) { + continue + } + + dstFile, written, err := copyFileContent(fd, file.Name, dirfd, 0, useHardLinks) + if err != nil { + return false, nil, 0, nil + } + return true, dstFile, written, nil + } + // If hard links deduplication was used and it has failed, try again without hard links. + if useHardLinks { + return findFileInOSTreeRepos(file, ostreeRepos, dirfd, false) + } + + return false, nil, 0, nil +} + // findFileOnTheHost checks whether the requested file already exist on the host and copies the file content from there if possible. // It is currently implemented to look only at the file with the same path. Ideally it can detect the same content also at different // paths. @@ -873,6 +923,9 @@ // modifies the source file as well. useHardLinks := parseBooleanPullOption(&storeOpts, "use_hard_links", false) + // List of OSTree repositories to use for deduplication + ostreeRepos := strings.Split(storeOpts.PullOptions["ostree_repos"], ":") + // Generate the manifest var toc internal.TOC if err := json.Unmarshal(c.manifest, &toc); err != nil { @@ -1009,18 +1062,35 @@ totalChunksSize += r.Size + finalizeFile := func(dstFile *os.File) error { + if dstFile != nil { + defer dstFile.Close() + if err := setFileAttrs(dstFile, mode, &r, options); err != nil { + return err + } + } + return nil + } + found, dstFile, _, err := findFileInOtherLayers(&r, dirfd, otherLayersCache, c.layersTarget, useHardLinks) if err != nil { return output, err } - if dstFile != nil { - if err := setFileAttrs(dstFile, mode, &r, options); err != nil { - dstFile.Close() + if found { + if err := finalizeFile(dstFile); err != nil { return output, err } - dstFile.Close() + continue + } + + found, dstFile, _, err = findFileInOSTreeRepos(&r, ostreeRepos, dirfd, useHardLinks) + if err != nil { + return output, err } if found { + if err := finalizeFile(dstFile); err != nil { + return output, err + } continue } @@ -1029,14 +1099,10 @@ if err != nil { return output, err } - if dstFile != nil { - if err := setFileAttrs(dstFile, mode, &r, options); err != nil { - dstFile.Close() + if found { + if err := finalizeFile(dstFile); err != nil { return output, err } - dstFile.Close() - } - if found { continue } } diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/fileutils/fileutils_unix.go golang-github-containers-storage-1.37.2+ds1/pkg/fileutils/fileutils_unix.go --- golang-github-containers-storage-1.36.0+ds1/pkg/fileutils/fileutils_unix.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/fileutils/fileutils_unix.go 2022-04-21 18:58:04.000000000 +0000 @@ -14,7 +14,7 @@ // reading it via /proc filesystem. func GetTotalUsedFds() int { if fds, err := ioutil.ReadDir(fmt.Sprintf("/proc/%d/fd", os.Getpid())); err != nil { - logrus.Errorf("Error opening /proc/%d/fd: %s", os.Getpid(), err) + logrus.Errorf("%v", err) } else { return len(fds) } diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/idtools/idtools.go golang-github-containers-storage-1.37.2+ds1/pkg/idtools/idtools.go --- golang-github-containers-storage-1.36.0+ds1/pkg/idtools/idtools.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/idtools/idtools.go 2022-04-21 18:58:04.000000000 +0000 @@ -82,7 +82,7 @@ if len(uidMap) == 1 && uidMap[0].Size == 1 { uid = uidMap[0].HostID } else { - uid, err = toHost(0, uidMap) + uid, err = RawToHost(0, uidMap) if err != nil { return -1, -1, err } @@ -90,7 +90,7 @@ if len(gidMap) == 1 && gidMap[0].Size == 1 { gid = gidMap[0].HostID } else { - gid, err = toHost(0, gidMap) + gid, err = RawToHost(0, gidMap) if err != nil { return -1, -1, err } @@ -98,10 +98,14 @@ return uid, gid, nil } -// toContainer takes an id mapping, and uses it to translate a -// host ID to the remapped ID. If no map is provided, then the translation -// assumes a 1-to-1 mapping and returns the passed in id -func toContainer(hostID int, idMap []IDMap) (int, error) { +// RawToContainer takes an id mapping, and uses it to translate a host ID to +// the remapped ID. If no map is provided, then the translation assumes a +// 1-to-1 mapping and returns the passed in id. +// +// If you wish to map a (uid,gid) combination you should use the corresponding +// IDMappings methods, which ensure that you are mapping the correct ID against +// the correct mapping. +func RawToContainer(hostID int, idMap []IDMap) (int, error) { if idMap == nil { return hostID, nil } @@ -114,10 +118,14 @@ return -1, fmt.Errorf("Host ID %d cannot be mapped to a container ID", hostID) } -// toHost takes an id mapping and a remapped ID, and translates the -// ID to the mapped host ID. If no map is provided, then the translation -// assumes a 1-to-1 mapping and returns the passed in id # -func toHost(contID int, idMap []IDMap) (int, error) { +// RawToHost takes an id mapping and a remapped ID, and translates the ID to +// the mapped host ID. If no map is provided, then the translation assumes a +// 1-to-1 mapping and returns the passed in id. +// +// If you wish to map a (uid,gid) combination you should use the corresponding +// IDMappings methods, which ensure that you are mapping the correct ID against +// the correct mapping. +func RawToHost(contID int, idMap []IDMap) (int, error) { if idMap == nil { return contID, nil } @@ -188,25 +196,25 @@ target := i.RootPair() if pair.UID != target.UID { - target.UID, err = toHost(pair.UID, i.uids) + target.UID, err = RawToHost(pair.UID, i.uids) if err != nil { return target, err } } if pair.GID != target.GID { - target.GID, err = toHost(pair.GID, i.gids) + target.GID, err = RawToHost(pair.GID, i.gids) } return target, err } // ToContainer returns the container UID and GID for the host uid and gid func (i *IDMappings) ToContainer(pair IDPair) (int, int, error) { - uid, err := toContainer(pair.UID, i.uids) + uid, err := RawToContainer(pair.UID, i.uids) if err != nil { return -1, -1, err } - gid, err := toContainer(pair.GID, i.gids) + gid, err := RawToContainer(pair.GID, i.gids) return uid, gid, err } diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/lockfile/lockfile_test.go golang-github-containers-storage-1.37.2+ds1/pkg/lockfile/lockfile_test.go --- golang-github-containers-storage-1.36.0+ds1/pkg/lockfile/lockfile_test.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/lockfile/lockfile_test.go 2022-04-21 18:58:04.000000000 +0000 @@ -64,7 +64,7 @@ } go func() { if err = cmd.Run(); err != nil { - logrus.Errorf("error running subTouch: %v", err) + logrus.Errorf("Running subTouch: %v", err) } }() return wc, rc, ec, nil @@ -103,7 +103,7 @@ } go func() { if err = cmd.Run(); err != nil { - logrus.Errorf("error running subLock: %v", err) + logrus.Errorf("Running subLock: %v", err) } }() return wc, rc, nil @@ -142,7 +142,7 @@ } go func() { if err = cmd.Run(); err != nil { - logrus.Errorf("error running subLock: %v", err) + logrus.Errorf("Running subLock: %v", err) } }() return wc, rc, nil @@ -181,7 +181,7 @@ } go func() { if err = cmd.Run(); err != nil { - logrus.Errorf("error running subRLock: %v", err) + logrus.Errorf("Running subRLock: %v", err) } }() return wc, rc, nil diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/lockfile/lockfile_unix.go golang-github-containers-storage-1.37.2+ds1/pkg/lockfile/lockfile_unix.go --- golang-github-containers-storage-1.36.0+ds1/pkg/lockfile/lockfile_unix.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/lockfile/lockfile_unix.go 2022-04-21 18:58:04.000000000 +0000 @@ -36,7 +36,7 @@ // necessary. func openLock(path string, ro bool) (fd int, err error) { if ro { - fd, err = unix.Open(path, os.O_RDONLY|unix.O_CLOEXEC, 0) + fd, err = unix.Open(path, os.O_RDONLY|unix.O_CLOEXEC|os.O_CREATE, 0) } else { fd, err = unix.Open(path, os.O_RDWR|unix.O_CLOEXEC|os.O_CREATE, diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/loopback/attach_loopback.go golang-github-containers-storage-1.37.2+ds1/pkg/loopback/attach_loopback.go --- golang-github-containers-storage-1.36.0+ds1/pkg/loopback/attach_loopback.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/loopback/attach_loopback.go 2022-04-21 18:58:04.000000000 +0000 @@ -43,7 +43,7 @@ var st syscall.Stat_t err = syscall.Fstat(int(sparseFile.Fd()), &st) if err != nil { - logrus.Errorf("Error reading information about loopback file %s: %v", sparseName, err) + logrus.Errorf("Reading information about loopback file %s: %v", sparseName, err) return nil, ErrAttachLoopbackDevice } @@ -68,7 +68,7 @@ // OpenFile adds O_CLOEXEC loopFile, err = os.OpenFile(target, os.O_RDWR, 0644) if err != nil { - logrus.Errorf("Error opening loopback device: %s", err) + logrus.Errorf("Opening loopback device: %s", err) return nil, ErrAttachLoopbackDevice } @@ -90,7 +90,7 @@ // device and inode numbers. dev, ino, err := getLoopbackBackingFile(loopFile) if err != nil { - logrus.Errorf("Error getting loopback backing file: %s", err) + logrus.Errorf("Getting loopback backing file: %s", err) return nil, ErrGetLoopbackBackingFile } if dev != uint64(st.Dev) || ino != st.Ino { @@ -125,7 +125,7 @@ // OpenFile adds O_CLOEXEC sparseFile, err := os.OpenFile(sparseName, os.O_RDWR, 0644) if err != nil { - logrus.Errorf("Error opening sparse file %s: %s", sparseName, err) + logrus.Errorf("Opening sparse file: %v", err) return nil, ErrAttachLoopbackDevice } defer sparseFile.Close() @@ -147,7 +147,7 @@ // If the call failed, then free the loopback device if err := ioctlLoopClrFd(loopFile.Fd()); err != nil { - logrus.Error("Error while cleaning up the loopback device") + logrus.Error("While cleaning up the loopback device") } loopFile.Close() return nil, ErrAttachLoopbackDevice diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/loopback/loopback.go golang-github-containers-storage-1.37.2+ds1/pkg/loopback/loopback.go --- golang-github-containers-storage-1.36.0+ds1/pkg/loopback/loopback.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/loopback/loopback.go 2022-04-21 18:58:04.000000000 +0000 @@ -13,7 +13,7 @@ func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) { loopInfo, err := ioctlLoopGetStatus64(file.Fd()) if err != nil { - logrus.Errorf("Error get loopback backing file: %s", err) + logrus.Errorf("Get loopback backing file: %v", err) return 0, 0, ErrGetLoopbackBackingFile } return loopInfo.loDevice, loopInfo.loInode, nil @@ -22,7 +22,7 @@ // SetCapacity reloads the size for the loopback device. func SetCapacity(file *os.File) error { if err := ioctlLoopSetCapacity(file.Fd(), 0); err != nil { - logrus.Errorf("Error loopbackSetCapacity: %s", err) + logrus.Errorf("loopbackSetCapacity: %s", err) return ErrSetCapacity } return nil diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/parsers/kernel/kernel_unix.go golang-github-containers-storage-1.37.2+ds1/pkg/parsers/kernel/kernel_unix.go --- golang-github-containers-storage-1.36.0+ds1/pkg/parsers/kernel/kernel_unix.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/parsers/kernel/kernel_unix.go 2022-04-21 18:58:04.000000000 +0000 @@ -35,7 +35,7 @@ // the given version. func CheckKernelVersion(k, major, minor int) bool { if v, err := GetKernelVersion(); err != nil { - logrus.Warnf("error getting kernel version: %s", err) + logrus.Warnf("Error getting kernel version: %s", err) } else { if CompareKernelVersion(*v, VersionInfo{Kernel: k, Major: major, Minor: minor}) < 0 { return false diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/system/syscall_unix.go golang-github-containers-storage-1.37.2+ds1/pkg/system/syscall_unix.go --- golang-github-containers-storage-1.36.0+ds1/pkg/system/syscall_unix.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/system/syscall_unix.go 2022-04-21 18:58:04.000000000 +0000 @@ -1,8 +1,11 @@ -// +build linux freebsd +// +build linux freebsd darwin package system -import "golang.org/x/sys/unix" +import ( + "github.com/pkg/errors" + "golang.org/x/sys/unix" +) // Unmount is a platform-specific helper function to call // the unmount syscall. @@ -15,3 +18,8 @@ func CommandLineToArgv(commandLine string) ([]string, error) { return []string{commandLine}, nil } + +// IsEBUSY checks if the specified error is EBUSY. +func IsEBUSY(err error) bool { + return errors.Is(err, unix.EBUSY) +} diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/system/syscall_windows.go golang-github-containers-storage-1.37.2+ds1/pkg/system/syscall_windows.go --- golang-github-containers-storage-1.36.0+ds1/pkg/system/syscall_windows.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/system/syscall_windows.go 2022-04-21 18:58:04.000000000 +0000 @@ -120,3 +120,8 @@ // APIs. return ntuserApiset.Load() == nil } + +// IsEBUSY checks if the specified error is EBUSY. +func IsEBUSY(err error) bool { + return false +} diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/tarlog/tarlogger.go golang-github-containers-storage-1.37.2+ds1/pkg/tarlog/tarlogger.go --- golang-github-containers-storage-1.36.0+ds1/pkg/tarlog/tarlogger.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/tarlog/tarlogger.go 2022-04-21 18:58:04.000000000 +0000 @@ -34,7 +34,7 @@ } // Make sure to avoid writes after the reader has been closed. if err := reader.Close(); err != nil { - logrus.Errorf("error closing tarlogger reader: %v", err) + logrus.Errorf("Closing tarlogger reader: %v", err) } // Unblock the Close(). t.closeMutex.Unlock() diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/unshare/unshare_linux.go golang-github-containers-storage-1.37.2+ds1/pkg/unshare/unshare_linux.go --- golang-github-containers-storage-1.36.0+ds1/pkg/unshare/unshare_linux.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/unshare/unshare_linux.go 2022-04-21 18:58:04.000000000 +0000 @@ -154,7 +154,7 @@ pidString := "" b := new(bytes.Buffer) if _, err := io.Copy(b, pidRead); err != nil { - return errors.Wrapf(err, "error reading child PID") + return errors.Wrapf(err, "Reading child PID") } pidString = b.String() pid, err := strconv.Atoi(pidString) @@ -188,8 +188,8 @@ if len(c.UidMappings) == 0 || len(c.GidMappings) == 0 { uidmap, gidmap, err := GetHostIDMappings("") if err != nil { - fmt.Fprintf(continueWrite, "error reading ID mappings in parent: %v", err) - return errors.Wrapf(err, "error reading ID mappings in parent") + fmt.Fprintf(continueWrite, "Reading ID mappings in parent: %v", err) + return errors.Wrapf(err, "Reading ID mappings in parent") } if len(c.UidMappings) == 0 { c.UidMappings = uidmap @@ -222,8 +222,8 @@ if err == nil { gidmapSet = true } else { - logrus.Warnf("error running newgidmap: %v: %s", err, g.String()) - logrus.Warnf("falling back to single mapping") + logrus.Warnf("Error running newgidmap: %v: %s", err, g.String()) + logrus.Warnf("Falling back to single mapping") g.Reset() g.Write([]byte(fmt.Sprintf("0 %d 1\n", os.Getegid()))) } @@ -271,8 +271,8 @@ if err == nil { uidmapSet = true } else { - logrus.Warnf("error running newuidmap: %v: %s", err, u.String()) - logrus.Warnf("falling back to single mapping") + logrus.Warnf("Error running newuidmap: %v: %s", err, u.String()) + logrus.Warnf("Falling back to single mapping") u.Reset() u.Write([]byte(fmt.Sprintf("0 %d 1\n", os.Geteuid()))) } @@ -407,7 +407,7 @@ // ID and a range size. uidmap, gidmap, err = GetSubIDMappings(me.Username, me.Username) if err != nil { - logrus.Warnf("error reading allowed ID mappings: %v", err) + logrus.Warnf("Reading allowed ID mappings: %v", err) } if len(uidmap) == 0 { logrus.Warnf("Found no UID ranges set aside for user %q in /etc/subuid.", me.Username) @@ -434,13 +434,13 @@ // If we have CAP_SYS_ADMIN, then we don't need to create a new namespace in order to be able // to use unshare(), so don't bother creating a new user namespace at this point. capabilities, err := capability.NewPid(0) - bailOnError(err, "error reading the current capabilities sets") + bailOnError(err, "Reading the current capabilities sets") if capabilities.Get(capability.EFFECTIVE, capability.CAP_SYS_ADMIN) { return } // Read the set of ID mappings that we're currently using. uidmap, gidmap, err = GetHostIDMappings("") - bailOnError(err, "error reading current ID mappings") + bailOnError(err, "Reading current ID mappings") // Just reuse them. for i := range uidmap { uidmap[i].HostID = uidmap[i].ContainerID @@ -463,7 +463,7 @@ if _, present := os.LookupEnv("BUILDAH_ISOLATION"); !present { if err = os.Setenv("BUILDAH_ISOLATION", "rootless"); err != nil { if err := os.Setenv("BUILDAH_ISOLATION", "rootless"); err != nil { - logrus.Errorf("error setting BUILDAH_ISOLATION=rootless in environment: %v", err) + logrus.Errorf("Setting BUILDAH_ISOLATION=rootless in environment: %v", err) os.Exit(1) } } @@ -483,7 +483,7 @@ cmd.GidMappingsEnableSetgroups = true // Finish up. - logrus.Debugf("running %+v with environment %+v, UID map %+v, and GID map %+v", cmd.Cmd.Args, os.Environ(), cmd.UidMappings, cmd.GidMappings) + logrus.Debugf("Running %+v with environment %+v, UID map %+v, and GID map %+v", cmd.Cmd.Args, os.Environ(), cmd.UidMappings, cmd.GidMappings) ExecRunnable(cmd, nil) } @@ -512,7 +512,7 @@ } } logrus.Errorf("%v", err) - logrus.Errorf("(unable to determine exit status)") + logrus.Errorf("(Unable to determine exit status)") exit(1) } exit(0) @@ -523,7 +523,7 @@ var mappings []specs.LinuxIDMapping f, err := os.Open(path) if err != nil { - return nil, errors.Wrapf(err, "error reading ID mappings from %q", path) + return nil, errors.Wrapf(err, "Reading ID mappings from %q", path) } defer f.Close() scanner := bufio.NewScanner(f) @@ -571,7 +571,7 @@ func GetSubIDMappings(user, group string) ([]specs.LinuxIDMapping, []specs.LinuxIDMapping, error) { mappings, err := idtools.NewIDMappings(user, group) if err != nil { - return nil, nil, errors.Wrapf(err, "error reading subuid mappings for user %q and subgid mappings for group %q", user, group) + return nil, nil, errors.Wrapf(err, "Reading subuid mappings for user %q and subgid mappings for group %q", user, group) } var uidmap, gidmap []specs.LinuxIDMapping for _, m := range mappings.UIDs() { diff -Nru golang-github-containers-storage-1.36.0+ds1/pkg/unshare/unshare_test.go golang-github-containers-storage-1.37.2+ds1/pkg/unshare/unshare_test.go --- golang-github-containers-storage-1.36.0+ds1/pkg/unshare/unshare_test.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/pkg/unshare/unshare_test.go 2022-04-21 18:58:04.000000000 +0000 @@ -55,7 +55,7 @@ for name := range CloneFlags { linkTarget, err := os.Readlink("/proc/self/ns/" + name) if err != nil { - logrus.Errorf("error reading link /proc/self/ns/%s: %v", name, err) + logrus.Errorf("Reading link /proc/self/ns/%s: %v", name, err) os.Exit(1) } report.Namespaces[name] = linkTarget @@ -65,31 +65,31 @@ sid, err := unix.Getsid(unix.Getpid()) if err != nil { - logrus.Errorf("error reading current session ID: %v", err) + logrus.Errorf("Reading current session ID: %v", err) os.Exit(1) } report.Sid = sid oomBytes, err := ioutil.ReadFile("/proc/self/oom_score_adj") if err != nil { - logrus.Errorf("error reading current oom_score_adj: %v", err) + logrus.Errorf("Reading current oom_score_adj: %v", err) os.Exit(1) } oomFields := strings.Fields(string(oomBytes)) if len(oomFields) != 1 { - logrus.Errorf("error parsing current oom_score_adj %q: wrong number of fields", string(oomBytes)) + logrus.Errorf("Parsing current oom_score_adj %q: wrong number of fields", string(oomBytes)) os.Exit(1) } oom, err := strconv.Atoi(oomFields[0]) if err != nil { - logrus.Errorf("error parsing current oom_score_adj %q: %v", oomFields[0], err) + logrus.Errorf("Parsing current oom_score_adj %q: %v", oomFields[0], err) os.Exit(1) } report.OOMScoreAdj = oom uidmap, gidmap, err := GetHostIDMappings("") if err != nil { - logrus.Errorf("error reading current ID mappings: %v", err) + logrus.Errorf("Reading current ID mappings: %v", err) os.Exit(1) } report.UIDMappings = append(report.UIDMappings, uidmap...) @@ -123,7 +123,7 @@ for ns := range CloneFlags { linkTarget, err := os.Readlink("/proc/self/ns/" + ns) if err != nil { - t.Fatalf("error reading link /proc/self/ns/%s: %v", ns, err) + t.Fatalf("Reading link /proc/self/ns/%s: %v", ns, err) os.Exit(1) } if ns == name || ns == "user" { // we always create a new user namespace @@ -167,7 +167,7 @@ func TestUnshareSid(t *testing.T) { sid, err := unix.Getsid(unix.Getpid()) if err != nil { - t.Fatalf("error reading current session ID: %v", err) + t.Fatalf("Reading current session ID: %v", err) } for _, same := range []bool{false, true} { var report Report diff -Nru golang-github-containers-storage-1.36.0+ds1/store.go golang-github-containers-storage-1.37.2+ds1/store.go --- golang-github-containers-storage-1.36.0+ds1/store.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/store.go 2022-04-21 18:58:04.000000000 +0000 @@ -23,6 +23,7 @@ "github.com/containers/storage/pkg/parsers" "github.com/containers/storage/pkg/stringid" "github.com/containers/storage/pkg/stringutils" + "github.com/containers/storage/pkg/system" "github.com/containers/storage/types" "github.com/hashicorp/go-multierror" digest "github.com/opencontainers/go-digest" @@ -1131,10 +1132,6 @@ if options.HostGIDMapping && len(layer.GIDMap) != 0 { return false } - // If we don't care about the mapping, it's fine. - if len(options.UIDMap) == 0 && len(options.GIDMap) == 0 { - return true - } // Compare the maps. return reflect.DeepEqual(layer.UIDMap, options.UIDMap) && reflect.DeepEqual(layer.GIDMap, options.GIDMap) } @@ -2502,7 +2499,15 @@ gcpath := filepath.Join(s.GraphRoot(), middleDir, container.ID) wg.Add(1) go func() { - errChan <- os.RemoveAll(gcpath) + var err error + for attempts := 0; attempts < 50; attempts++ { + err = os.RemoveAll(gcpath) + if err == nil || !system.IsEBUSY(err) { + break + } + time.Sleep(time.Millisecond * 100) + } + errChan <- err wg.Done() }() @@ -2825,10 +2830,33 @@ if err != nil { return nil, err } + + // NaiveDiff could cause mounts to happen without a lock, so be safe + // and treat the .Diff operation as a Mount. + s.graphLock.Lock() + defer s.graphLock.Unlock() + + modified, err := s.graphLock.Modified() + if err != nil { + return nil, err + } + + // We need to make sure the home mount is present when the Mount is done. + if modified { + s.graphDriver = nil + s.layerStore = nil + s.graphDriver, err = s.getGraphDriver() + if err != nil { + return nil, err + } + s.lastLoaded = time.Now() + } + for _, s := range append([]ROLayerStore{lstore}, lstores...) { store := s store.RLock() if err := store.ReloadIfChanged(); err != nil { + store.Unlock() return nil, err } if store.Exists(to) { diff -Nru golang-github-containers-storage-1.36.0+ds1/tests/idmaps.bats golang-github-containers-storage-1.37.2+ds1/tests/idmaps.bats --- golang-github-containers-storage-1.36.0+ds1/tests/idmaps.bats 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/tests/idmaps.bats 2022-04-21 18:58:04.000000000 +0000 @@ -313,7 +313,7 @@ for i in $(seq $n) ; do run stat -c %u:%g "$defmapmount"/file$i [ "$status" -eq 0 ] - [ "$output" = ${uidrange[$n]}:${gidrange[$n]} ] + [ "$output" = "0:0" ] done } @@ -372,15 +372,11 @@ [ "$status" -eq 0 ] # Check who owns the parent directories. run storage --debug=false container-parent-owners $container - echo "$output" [ "$status" -eq 0 ] - # Assume that except for root and maybe us, there are no other owners of parent directories of our container's layer. - if ! fgrep -q 'UIDs: [0]' <<< "$output" ; then - fgrep -q 'UIDs: [0, '$(id -u)']' <<< "$output" - fi - if ! fgrep -q 'GIDs: [0]' <<< "$output" ; then - fgrep -q 'GIDs: [0, '$(id -g)']' <<< "$output" - fi + cat <<< "$output" | tr '\n' '_' + # Check there are no unmapped IDs + fgrep -q 'UIDs: []' <<< "$output" + fgrep -q 'GIDs: []' <<< "$output" } @test "idmaps-copy" { diff -Nru golang-github-containers-storage-1.36.0+ds1/types/options.go golang-github-containers-storage-1.37.2+ds1/types/options.go --- golang-github-containers-storage-1.36.0+ds1/types/options.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/types/options.go 2022-04-21 18:58:04.000000000 +0000 @@ -3,14 +3,12 @@ import ( "fmt" "os" - "os/exec" "path/filepath" "strings" "sync" "time" "github.com/BurntSushi/toml" - "github.com/containers/storage/drivers/overlay" cfg "github.com/containers/storage/pkg/config" "github.com/containers/storage/pkg/idtools" "github.com/sirupsen/logrus" @@ -190,28 +188,6 @@ if driver := os.Getenv("STORAGE_DRIVER"); driver != "" { opts.GraphDriverName = driver } - if opts.GraphDriverName == "" || opts.GraphDriverName == overlayDriver { - supported, err := overlay.SupportsNativeOverlay(opts.GraphRoot, rootlessRuntime) - if err != nil { - return opts, err - } - if supported { - opts.GraphDriverName = overlayDriver - } else { - if path, err := exec.LookPath("fuse-overlayfs"); err == nil { - opts.GraphDriverName = overlayDriver - opts.GraphDriverOptions = []string{fmt.Sprintf("overlay.mount_program=%s", path)} - } - } - if opts.GraphDriverName == overlayDriver { - for _, o := range systemOpts.GraphDriverOptions { - if strings.Contains(o, "ignore_chown_errors") { - opts.GraphDriverOptions = append(opts.GraphDriverOptions, o) - break - } - } - } - } if opts.GraphDriverName == "" { opts.GraphDriverName = "vfs" } diff -Nru golang-github-containers-storage-1.36.0+ds1/types/utils.go golang-github-containers-storage-1.37.2+ds1/types/utils.go --- golang-github-containers-storage-1.36.0+ds1/types/utils.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/types/utils.go 2022-04-21 18:58:04.000000000 +0000 @@ -87,7 +87,7 @@ if tmpPerUserDir != "" { if _, err := env.systemLstat(tmpPerUserDir); os.IsNotExist(err) { if err := os.Mkdir(tmpPerUserDir, 0700); err != nil { - logrus.Errorf("failed to create temp directory for user: %v", err) + logrus.Errorf("Failed to create temp directory for user: %v", err) } else { return tmpPerUserDir, nil } diff -Nru golang-github-containers-storage-1.36.0+ds1/userns.go golang-github-containers-storage-1.37.2+ds1/userns.go --- golang-github-containers-storage-1.36.0+ds1/userns.go 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/userns.go 2022-04-21 18:58:04.000000000 +0000 @@ -43,7 +43,7 @@ } mappings, err := idtools.NewIDMappings(username, username) if err != nil { - logrus.Errorf("cannot find mappings for user %q: %v", username, err) + logrus.Errorf("Cannot find mappings for user %q: %v", username, err) } else { uids = getHostIDs(mappings.UIDs()) gids = getHostIDs(mappings.GIDs()) diff -Nru golang-github-containers-storage-1.36.0+ds1/VERSION golang-github-containers-storage-1.37.2+ds1/VERSION --- golang-github-containers-storage-1.36.0+ds1/VERSION 2021-09-22 22:03:10.000000000 +0000 +++ golang-github-containers-storage-1.37.2+ds1/VERSION 2022-04-21 18:58:04.000000000 +0000 @@ -1 +1 @@ -1.36.0 +1.37.2