go.mod: update osbuild/images to v0.156.0

tag v0.155.0
Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com>

Changes with 0.155.0

----------------
  * Fedora 43: add shadow-utils when LockRoot is enabled, update cloud-init service name (osbuild/images#1618)
    * Author: Achilleas Koutsou, Reviewers: Gianluca Zuccarelli, Michael Vogt
  * Update osbuild dependency commit ID to latest (osbuild/images#1609)
    * Author: SchutzBot, Reviewers: Achilleas Koutsou, Simon de Vlieger, Tomáš Hozza
  * Update snapshots to 20250626 (osbuild/images#1623)
    * Author: SchutzBot, Reviewers: Achilleas Koutsou, Simon de Vlieger
  * distro/rhel9: xz compress azure-cvm image type [HMS-8587] (osbuild/images#1620)
    * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza
  * distro/rhel: introduce new image type: Azure SAP Apps [HMS-8738] (osbuild/images#1612)
    * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza
  * distro/rhel: move ansible-core to sap_extras_pkgset (osbuild/images#1624)
    * Author: Achilleas Koutsou, Reviewers: Brian C. Lane, Tomáš Hozza
  * github/create-tag: allow passing the version when run manually (osbuild/images#1621)
    * Author: Achilleas Koutsou, Reviewers: Lukáš Zapletal, Tomáš Hozza
  * rhel9: move image-config into pure YAML (HMS-8593) (osbuild/images#1616)
    * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Simon de Vlieger
  * test: split manifest checksums into separate files (osbuild/images#1625)
    * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza

— Somewhere on the Internet, 2025-06-30

---

tag v0.156.0
Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com>

Changes with 0.156.0

----------------
  * Many: delete repositories for EOL distributions (HMS-7044) (osbuild/images#1607)
    * Author: Tomáš Hozza, Reviewers: Michael Vogt, Simon de Vlieger
  * RHSM/facts: add 'image-builder CLI' API type (osbuild/images#1640)
    * Author: Tomáš Hozza, Reviewers: Brian C. Lane, Simon de Vlieger
  * Update dependencies 2025-06-29 (osbuild/images#1628)
    * Author: SchutzBot, Reviewers: Simon de Vlieger, Tomáš Hozza
  * Update osbuild dependency commit ID to latest (osbuild/images#1627)
    * Author: SchutzBot, Reviewers: Simon de Vlieger, Tomáš Hozza
  * [RFC] image: drop `InstallWeakDeps` from image.DiskImage (osbuild/images#1642)
    * Author: Michael Vogt, Reviewers: Brian C. Lane, Simon de Vlieger, Tomáš Hozza
  * build(deps): bump the go-deps group across 1 directory with 3 updates (osbuild/images#1632)
    * Author: dependabot[bot], Reviewers: SchutzBot, Tomáš Hozza
  * distro/rhel10: xz compress azure-cvm image type (osbuild/images#1638)
    * Author: Achilleas Koutsou, Reviewers: Brian C. Lane, Simon de Vlieger
  * distro: cleanup/refactor distro/{defs,generic} (HMS-8744) (osbuild/images#1570)
    * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza
  * distro: remove some hardcoded values from generic/images.go (osbuild/images#1636)
    * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza
  * distro: small tweaks for the YAML based imagetypes (osbuild/images#1622)
    * Author: Michael Vogt, Reviewers: Brian C. Lane, Simon de Vlieger
  * fedora/wsl: packages and locale (osbuild/images#1635)
    * Author: Simon de Vlieger, Reviewers: Michael Vogt, Tomáš Hozza
  * image/many: make compression more generic (osbuild/images#1634)
    * Author: Simon de Vlieger, Reviewers: Brian C. Lane, Michael Vogt
  * manifest: handle content template name with spaces (osbuild/images#1641)
    * Author: Bryttanie, Reviewers: Brian C. Lane, Michael Vogt, Tomáš Hozza
  * many: implement gzip (osbuild/images#1633)
    * Author: Simon de Vlieger, Reviewers: Michael Vogt, Tomáš Hozza
  * rhel/azure: set GRUB_TERMINAL based on architecture [RHEL-91383] (osbuild/images#1626)
    * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza

— Somewhere on the Internet, 2025-07-07

---
This commit is contained in:
Achilleas Koutsou 2025-07-10 16:14:25 +02:00
parent 60c5f10af8
commit 3fd7092db5
1486 changed files with 124742 additions and 82516 deletions

View file

@ -517,7 +517,7 @@ func (a *Driver) isParent(id, parent string) bool {
if parent == "" && len(parents) > 0 {
return false
}
return !(len(parents) > 0 && parent != parents[0])
return len(parents) == 0 || parent == parents[0]
}
// Diff produces an archive of the changes between the specified
@ -778,6 +778,6 @@ func (a *Driver) SupportsShifting() bool {
}
// Dedup performs deduplication of the driver's storage.
func (d *Driver) Dedup(req graphdriver.DedupArgs) (graphdriver.DedupResult, error) {
func (a *Driver) Dedup(req graphdriver.DedupArgs) (graphdriver.DedupResult, error) {
return graphdriver.DedupResult{}, nil
}

View file

@ -1,4 +1,4 @@
//go:build linux && !btrfs_noversion && cgo
//go:build linux && cgo
package btrfs

View file

@ -1,14 +0,0 @@
//go:build linux && btrfs_noversion && cgo
package btrfs
// TODO(vbatts) remove this work-around once supported linux distros are on
// btrfs utilities of >= 3.16.1
func btrfsBuildVersion() string {
return "-"
}
func btrfsLibVersion() int {
return -1
}

View file

@ -36,8 +36,8 @@ func (c *platformChowner) LChown(path string, info os.FileInfo, toHost, toContai
}
i := inode{
Dev: uint64(st.Dev),
Ino: uint64(st.Ino),
Dev: uint64(st.Dev), //nolint:unconvert
Ino: st.Ino,
}
c.mutex.Lock()

View file

@ -40,7 +40,7 @@ const (
)
// CopyRegularToFile copies the content of a file to another
func CopyRegularToFile(srcPath string, dstFile *os.File, fileinfo os.FileInfo, copyWithFileRange, copyWithFileClone *bool) error { // nolint: revive,golint
func CopyRegularToFile(srcPath string, dstFile *os.File, fileinfo os.FileInfo, copyWithFileRange, copyWithFileClone *bool) error { //nolint: revive
srcFile, err := os.Open(srcPath)
if err != nil {
return err
@ -72,7 +72,7 @@ func CopyRegularToFile(srcPath string, dstFile *os.File, fileinfo os.FileInfo, c
}
// CopyRegular copies the content of a file to another
func CopyRegular(srcPath, dstPath string, fileinfo os.FileInfo, copyWithFileRange, copyWithFileClone *bool) error { // nolint: revive,golint
func CopyRegular(srcPath, dstPath string, fileinfo os.FileInfo, copyWithFileRange, copyWithFileClone *bool) error { //nolint: revive
// If the destination file already exists, we shouldn't blow it away
dstFile, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, fileinfo.Mode())
if err != nil {
@ -160,7 +160,10 @@ func DirCopy(srcDir, dstDir string, copyMode Mode, copyXattrs bool) error {
switch mode := f.Mode(); {
case mode.IsRegular():
id := fileID{dev: uint64(stat.Dev), ino: stat.Ino}
id := fileID{
dev: uint64(stat.Dev), //nolint:unconvert
ino: stat.Ino,
}
if copyMode == Hardlink {
isHardlink = true
if err2 := os.Link(srcPath, dstPath); err2 != nil {
@ -242,12 +245,11 @@ func DirCopy(srcDir, dstDir string, copyMode Mode, copyXattrs bool) error {
}
// system.Chtimes doesn't support a NOFOLLOW flag atm
// nolint: unconvert
if f.IsDir() {
dirsToSetMtimes.PushFront(&dirMtimeInfo{dstPath: &dstPath, stat: stat})
} else if !isSymlink {
aTime := time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec))
mTime := time.Unix(int64(stat.Mtim.Sec), int64(stat.Mtim.Nsec))
aTime := time.Unix(stat.Atim.Unix())
mTime := time.Unix(stat.Mtim.Unix())
if err := system.Chtimes(dstPath, aTime, mTime); err != nil {
return err
}

View file

@ -24,7 +24,7 @@ func DirCopy(srcDir, dstDir string, _ Mode, _ bool) error {
}
// CopyRegularToFile copies the content of a file to another
func CopyRegularToFile(srcPath string, dstFile *os.File, fileinfo os.FileInfo, copyWithFileRange, copyWithFileClone *bool) error { //nolint: revive,golint // "func name will be used as copy.CopyRegularToFile by other packages, and that stutters"
func CopyRegularToFile(srcPath string, dstFile *os.File, fileinfo os.FileInfo, copyWithFileRange, copyWithFileClone *bool) error { //nolint: revive // "func name will be used as copy.CopyRegularToFile by other packages, and that stutters"
f, err := os.Open(srcPath)
if err != nil {
return err
@ -35,6 +35,6 @@ func CopyRegularToFile(srcPath string, dstFile *os.File, fileinfo os.FileInfo, c
}
// CopyRegular copies the content of a file to another
func CopyRegular(srcPath, dstPath string, fileinfo os.FileInfo, copyWithFileRange, copyWithFileClone *bool) error { //nolint:revive,golint // "func name will be used as copy.CopyRegular by other packages, and that stutters"
func CopyRegular(srcPath, dstPath string, fileinfo os.FileInfo, copyWithFileRange, copyWithFileClone *bool) error { //nolint:revive // "func name will be used as copy.CopyRegular by other packages, and that stutters"
return chrootarchive.NewArchiver(nil).CopyWithTar(srcPath, dstPath)
}

View file

@ -54,8 +54,8 @@ type MountOpts struct {
// Mount label is the MAC Labels to assign to mount point (SELINUX)
MountLabel string
// UidMaps & GidMaps are the User Namespace mappings to be assigned to content in the mount point
UidMaps []idtools.IDMap //nolint: revive,golint
GidMaps []idtools.IDMap //nolint: revive,golint
UidMaps []idtools.IDMap //nolint: revive
GidMaps []idtools.IDMap //nolint: revive
Options []string
// Volatile specifies whether the container storage can be optimized
@ -79,7 +79,7 @@ type ApplyDiffOpts struct {
type ApplyDiffWithDifferOpts struct {
ApplyDiffOpts
Flags map[string]interface{}
Flags map[string]any
}
// DedupArgs contains the information to perform storage deduplication.
@ -222,7 +222,7 @@ type DriverWithDifferOutput struct {
RootDirMode *os.FileMode
// Artifacts is a collection of additional artifacts
// generated by the differ that the storage driver can use.
Artifacts map[string]interface{}
Artifacts map[string]any
}
type DifferOutputFormat int

View file

@ -259,7 +259,7 @@ func supportsIdmappedLowerLayers(home string) (bool, error) {
}
defer cleanupFunc()
if err := idmap.CreateIDMappedMount(lowerDir, lowerMappedDir, int(pid)); err != nil {
if err := idmap.CreateIDMappedMount(lowerDir, lowerMappedDir, pid); err != nil {
return false, fmt.Errorf("create mapped mount: %w", err)
}
defer func() {

View file

@ -42,7 +42,7 @@ func getComposefsBlob(dataDir string) string {
return filepath.Join(dataDir, "composefs.blob")
}
func generateComposeFsBlob(verityDigests map[string]string, toc interface{}, composefsDir string) error {
func generateComposeFsBlob(verityDigests map[string]string, toc any, composefsDir string) error {
if err := os.MkdirAll(composefsDir, 0o700); err != nil {
return err
}
@ -53,7 +53,7 @@ func generateComposeFsBlob(verityDigests map[string]string, toc interface{}, com
}
destFile := getComposefsBlob(composefsDir)
writerJson, err := getComposeFsHelper()
writerJSON, err := getComposeFsHelper()
if err != nil {
return fmt.Errorf("failed to find mkcomposefs: %w", err)
}
@ -74,7 +74,7 @@ func generateComposeFsBlob(verityDigests map[string]string, toc interface{}, com
defer outFile.Close()
errBuf := &bytes.Buffer{}
cmd := exec.Command(writerJson, "--from-file", "-", "-")
cmd := exec.Command(writerJSON, "--from-file", "-", "-")
cmd.Stderr = errBuf
cmd.Stdin = dumpReader
cmd.Stdout = outFile

View file

@ -36,7 +36,6 @@ import (
"github.com/containers/storage/pkg/system"
"github.com/containers/storage/pkg/unshare"
units "github.com/docker/go-units"
"github.com/hashicorp/go-multierror"
digest "github.com/opencontainers/go-digest"
"github.com/opencontainers/selinux/go-selinux"
"github.com/opencontainers/selinux/go-selinux/label"
@ -131,6 +130,9 @@ type Driver struct {
usingMetacopy bool
usingComposefs bool
stagingDirsLocksMutex sync.Mutex
// stagingDirsLocks access is not thread safe, it is required that callers take
// stagingDirsLocksMutex on each access to guard against concurrent map writes.
stagingDirsLocks map[string]*lockfile.LockFile
supportsIDMappedMounts *bool
@ -419,7 +421,7 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
if !opts.skipMountHome {
if err := mount.MakePrivate(home); err != nil {
return nil, err
return nil, fmt.Errorf("overlay: failed to make mount private: %w", err)
}
}
@ -429,17 +431,18 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
}
d := &Driver{
name: "overlay",
home: home,
imageStore: options.ImageStore,
runhome: runhome,
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(fileSystemType)),
supportsDType: supportsDType,
usingMetacopy: usingMetacopy,
supportsVolatile: supportsVolatile,
usingComposefs: opts.useComposefs,
options: *opts,
stagingDirsLocks: make(map[string]*lockfile.LockFile),
name: "overlay",
home: home,
imageStore: options.ImageStore,
runhome: runhome,
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(fileSystemType)),
supportsDType: supportsDType,
usingMetacopy: usingMetacopy,
supportsVolatile: supportsVolatile,
usingComposefs: opts.useComposefs,
options: *opts,
stagingDirsLocksMutex: sync.Mutex{},
stagingDirsLocks: make(map[string]*lockfile.LockFile),
}
d.naiveDiff = graphdriver.NewNaiveDiffDriver(d, graphdriver.NewNaiveLayerIDMapUpdater(d))
@ -489,7 +492,7 @@ func parseOptions(options []string) (*overlayOptions, error) {
if err != nil {
return nil, err
}
o.quota.Inodes = uint64(inodes)
o.quota.Inodes = inodes
case "imagestore", "additionalimagestore":
logrus.Debugf("overlay: imagestore=%s", val)
// Additional read only image stores to use for lower paths
@ -640,6 +643,8 @@ func SupportsNativeOverlay(home, runhome string) (bool, error) {
case "true":
logrus.Debugf("overlay: storage already configured with a mount-program")
return false, nil
case "false":
// Do nothing.
default:
needsMountProgram, err := scanForMountProgramIndicators(home)
if err != nil && !os.IsNotExist(err) {
@ -653,7 +658,6 @@ func SupportsNativeOverlay(home, runhome string) (bool, error) {
}
// fall through to check if we find ourselves needing to use a
// mount program now
case "false":
}
for _, dir := range []string{home, runhome} {
@ -868,10 +872,12 @@ func (d *Driver) Cleanup() error {
// pruneStagingDirectories cleans up any staging directory that was leaked.
// It returns whether any staging directory is still present.
func (d *Driver) pruneStagingDirectories() bool {
d.stagingDirsLocksMutex.Lock()
for _, lock := range d.stagingDirsLocks {
lock.Unlock()
}
d.stagingDirsLocks = make(map[string]*lockfile.LockFile)
clear(d.stagingDirsLocks)
d.stagingDirsLocksMutex.Unlock()
anyPresent := false
@ -1157,7 +1163,7 @@ func (d *Driver) parseStorageOpt(storageOpt map[string]string, driver *Driver) e
if err != nil {
return err
}
driver.options.quota.Inodes = uint64(inodes)
driver.options.quota.Inodes = inodes
default:
return fmt.Errorf("unknown option %s", key)
}
@ -1343,7 +1349,7 @@ func (d *Driver) recreateSymlinks() error {
return err
}
// Keep looping as long as we take some corrective action in each iteration
var errs *multierror.Error
var errs error
madeProgress := true
iterations := 0
for madeProgress {
@ -1359,7 +1365,7 @@ func (d *Driver) recreateSymlinks() error {
// Read the "link" file under each layer to get the name of the symlink
data, err := os.ReadFile(path.Join(d.dir(dir.Name()), "link"))
if err != nil {
errs = multierror.Append(errs, fmt.Errorf("reading name of symlink for %q: %w", dir.Name(), err))
errs = errors.Join(errs, fmt.Errorf("reading name of symlink for %q: %w", dir.Name(), err))
continue
}
linkPath := path.Join(d.home, linkDir, strings.Trim(string(data), "\n"))
@ -1368,12 +1374,12 @@ func (d *Driver) recreateSymlinks() error {
err = fileutils.Lexists(linkPath)
if err != nil && os.IsNotExist(err) {
if err := os.Symlink(path.Join("..", dir.Name(), "diff"), linkPath); err != nil {
errs = multierror.Append(errs, err)
errs = errors.Join(errs, err)
continue
}
madeProgress = true
} else if err != nil {
errs = multierror.Append(errs, err)
errs = errors.Join(errs, err)
continue
}
}
@ -1384,7 +1390,7 @@ func (d *Driver) recreateSymlinks() error {
// that each symlink we have corresponds to one.
links, err := os.ReadDir(linkDirFullPath)
if err != nil {
errs = multierror.Append(errs, err)
errs = errors.Join(errs, err)
continue
}
// Go through all of the symlinks in the "l" directory
@ -1392,16 +1398,16 @@ func (d *Driver) recreateSymlinks() error {
// Read the symlink's target, which should be "../$layer/diff"
target, err := os.Readlink(filepath.Join(linkDirFullPath, link.Name()))
if err != nil {
errs = multierror.Append(errs, err)
errs = errors.Join(errs, err)
continue
}
targetComponents := strings.Split(target, string(os.PathSeparator))
if len(targetComponents) != 3 || targetComponents[0] != ".." || targetComponents[2] != "diff" {
errs = multierror.Append(errs, fmt.Errorf("link target of %q looks weird: %q", link, target))
errs = errors.Join(errs, fmt.Errorf("link target of %q looks weird: %q", link, target))
// force the link to be recreated on the next pass
if err := os.Remove(filepath.Join(linkDirFullPath, link.Name())); err != nil {
if !os.IsNotExist(err) {
errs = multierror.Append(errs, fmt.Errorf("removing link %q: %w", link, err))
errs = errors.Join(errs, fmt.Errorf("removing link %q: %w", link, err))
} // else dont report any error, but also dont set madeProgress.
continue
}
@ -1417,7 +1423,7 @@ func (d *Driver) recreateSymlinks() error {
// NOTE: If two or more links point to the same target, we will update linkFile
// with every value of link.Name(), and set madeProgress = true every time.
if err := os.WriteFile(linkFile, []byte(link.Name()), 0o644); err != nil {
errs = multierror.Append(errs, fmt.Errorf("correcting link for layer %s: %w", targetID, err))
errs = errors.Join(errs, fmt.Errorf("correcting link for layer %s: %w", targetID, err))
continue
}
madeProgress = true
@ -1425,14 +1431,11 @@ func (d *Driver) recreateSymlinks() error {
}
iterations++
if iterations >= maxIterations {
errs = multierror.Append(errs, fmt.Errorf("reached %d iterations in overlay graph drivers recreateSymlink, giving up", iterations))
errs = errors.Join(errs, fmt.Errorf("reached %d iterations in overlay graph drivers recreateSymlink, giving up", iterations))
break
}
}
if errs != nil {
return errs.ErrorOrNil()
}
return nil
return errs
}
// Get creates and mounts the required file system for the given id and returns the mount path.
@ -1548,7 +1551,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
permsKnown := false
st, err := os.Stat(filepath.Join(dir, nameWithSuffix("diff", diffN)))
if err == nil {
perms = os.FileMode(st.Mode())
perms = st.Mode()
permsKnown = true
}
for err == nil {
@ -1563,7 +1566,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
if err != nil {
return "", err
}
idmappedMountProcessPid = int(pid)
idmappedMountProcessPid = pid
defer cleanupFunc()
}
@ -1635,7 +1638,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
lower = path.Join(p, d.name, l)
if st2, err2 := os.Stat(lower); err2 == nil {
if !permsKnown {
perms = os.FileMode(st2.Mode())
perms = st2.Mode()
permsKnown = true
}
break
@ -1656,7 +1659,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
}
} else {
if !permsKnown {
perms = os.FileMode(st.Mode())
perms = st.Mode()
permsKnown = true
}
lower = newpath
@ -2103,17 +2106,16 @@ func (g *overlayFileGetter) Get(path string) (io.ReadCloser, error) {
return nil, fmt.Errorf("%s: %w", path, os.ErrNotExist)
}
func (g *overlayFileGetter) Close() error {
var errs *multierror.Error
func (g *overlayFileGetter) Close() (errs error) {
for _, f := range g.composefsMounts {
if err := f.Close(); err != nil {
errs = multierror.Append(errs, err)
errs = errors.Join(errs, err)
}
if err := unix.Rmdir(f.Name()); err != nil {
errs = multierror.Append(errs, err)
errs = errors.Join(errs, err)
}
}
return errs.ErrorOrNil()
return errs
}
// newStagingDir creates a new staging directory and returns the path to it.
@ -2173,10 +2175,12 @@ func (d *Driver) DiffGetter(id string) (_ graphdriver.FileGetCloser, Err error)
func (d *Driver) CleanupStagingDirectory(stagingDirectory string) error {
parentStagingDir := filepath.Dir(stagingDirectory)
d.stagingDirsLocksMutex.Lock()
if lock, ok := d.stagingDirsLocks[parentStagingDir]; ok {
delete(d.stagingDirsLocks, parentStagingDir)
lock.Unlock()
}
d.stagingDirsLocksMutex.Unlock()
return os.RemoveAll(parentStagingDir)
}
@ -2235,11 +2239,15 @@ func (d *Driver) ApplyDiffWithDiffer(options *graphdriver.ApplyDiffWithDifferOpt
}
defer func() {
if errRet != nil {
d.stagingDirsLocksMutex.Lock()
delete(d.stagingDirsLocks, layerDir)
d.stagingDirsLocksMutex.Unlock()
lock.Unlock()
}
}()
d.stagingDirsLocksMutex.Lock()
d.stagingDirsLocks[layerDir] = lock
d.stagingDirsLocksMutex.Unlock()
lock.Lock()
logrus.Debugf("Applying differ in %s", applyDir)
@ -2271,10 +2279,12 @@ func (d *Driver) ApplyDiffFromStagingDirectory(id, parent string, diffOutput *gr
parentStagingDir := filepath.Dir(stagingDirectory)
defer func() {
d.stagingDirsLocksMutex.Lock()
if lock, ok := d.stagingDirsLocks[parentStagingDir]; ok {
delete(d.stagingDirsLocks, parentStagingDir)
lock.Unlock()
}
d.stagingDirsLocksMutex.Unlock()
}()
diffPath, err := d.getDiffPath(id)
@ -2495,7 +2505,7 @@ func (d *Driver) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMapp
perms = *d.options.forceMask
} else {
if err == nil {
perms = os.FileMode(st.Mode())
perms = st.Mode()
}
}
for err == nil {

View file

@ -190,7 +190,8 @@ func NewControl(basePath string) (*Control, error) {
}
// SetQuota - assign a unique project id to directory and set the quota limits
// for that project id
// for that project id.
// targetPath must exist, must be a directory, and must be empty.
func (q *Control) SetQuota(targetPath string, quota Quota) error {
var projectID uint32
value, ok := q.quotas.Load(targetPath)
@ -200,10 +201,20 @@ func (q *Control) SetQuota(targetPath string, quota Quota) error {
if !ok {
projectID = q.nextProjectID
// The directory we are setting an ID on must be empty, as
// the ID will not be propagated to pre-existing subdirectories.
dents, err := os.ReadDir(targetPath)
if err != nil {
return fmt.Errorf("reading directory %s: %w", targetPath, err)
}
if len(dents) > 0 {
return fmt.Errorf("can only set project ID on empty directories, %s is not empty", targetPath)
}
//
// assign project id to new container directory
//
err := setProjectID(targetPath, projectID)
err = setProjectID(targetPath, projectID)
if err != nil {
return err
}