diff --git a/go.mod b/go.mod index 6fe5ee5198a0..08a771f0ff4c 100644 --- a/go.mod +++ b/go.mod @@ -69,7 +69,7 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/spdx/tools-golang v0.5.3 github.com/stretchr/testify v1.9.0 - github.com/tonistiigi/fsutil v0.0.0-20241003195857-3f140a1299b0 + github.com/tonistiigi/fsutil v0.0.0-20241028165955-397af5306b5c github.com/tonistiigi/go-actions-cache v0.0.0-20240327122527-58651d5e11d6 github.com/tonistiigi/go-archvariant v1.0.0 github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4 diff --git a/go.sum b/go.sum index da5a84c23519..a74a758d5e76 100644 --- a/go.sum +++ b/go.sum @@ -383,8 +383,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tonistiigi/dchapes-mode v0.0.0-20241001053921-ca0759fec205 h1:eUk79E1w8yMtXeHSzjKorxuC8qJOnyXQnLaJehxpJaI= github.com/tonistiigi/dchapes-mode v0.0.0-20241001053921-ca0759fec205/go.mod h1:3Iuxbr0P7D3zUzBMAZB+ois3h/et0shEz0qApgHYGpY= -github.com/tonistiigi/fsutil v0.0.0-20241003195857-3f140a1299b0 h1:H9++AiQUqjwrOMA/DOpWhxWp3JLyyT+MN4sRPbMmwoY= -github.com/tonistiigi/fsutil v0.0.0-20241003195857-3f140a1299b0/go.mod h1:Dl/9oEjK7IqnjAm21Okx/XIxUCFJzvh+XdVHUlBwXTw= +github.com/tonistiigi/fsutil v0.0.0-20241028165955-397af5306b5c h1:bQLsfX+uEPZUjyR2qmoJs5F8Z57bPVmF3IsUf22Xo9Y= +github.com/tonistiigi/fsutil v0.0.0-20241028165955-397af5306b5c/go.mod h1:Dl/9oEjK7IqnjAm21Okx/XIxUCFJzvh+XdVHUlBwXTw= github.com/tonistiigi/go-actions-cache v0.0.0-20240327122527-58651d5e11d6 h1:XFG/Wmm5dFYoqUiVChLumRjRzJm0P9k/qDMhxLqdupU= github.com/tonistiigi/go-actions-cache v0.0.0-20240327122527-58651d5e11d6/go.mod h1:anhKd3mnC1shAbQj1Q4IJ+w6xqezxnyDYlx/yKa7IXM= github.com/tonistiigi/go-archvariant v1.0.0 h1:5LC1eDWiBNflnTF1prCiX09yfNHIxDC/aukdhCdTyb0= diff --git a/solver/llbsolver/file/backend.go b/solver/llbsolver/file/backend.go index 2c529a43a22d..1d4abb36aa84 100644 --- a/solver/llbsolver/file/backend.go +++ b/solver/llbsolver/file/backend.go @@ -46,7 +46,7 @@ func mkdir(d string, action *pb.FileActionMkDir, user *copy.User, idmap *idtools } if action.MakeParents { - if err := copy.MkdirAll(p, os.FileMode(action.Mode)&0777, ch, timestampToTime(action.Timestamp)); err != nil { + if _, err := copy.MkdirAll(p, os.FileMode(action.Mode)&0777, ch, timestampToTime(action.Timestamp)); err != nil { return err } } else { diff --git a/solver/llbsolver/file/unpack.go b/solver/llbsolver/file/unpack.go index 59275b6e2dba..ff167e324de0 100644 --- a/solver/llbsolver/file/unpack.go +++ b/solver/llbsolver/file/unpack.go @@ -25,7 +25,7 @@ func unpack(srcRoot string, src string, destRoot string, dest string, ch copy.Ch if err != nil { return false, err } - if err := copy.MkdirAll(dest, 0755, ch, tm); err != nil { + if _, err := copy.MkdirAll(dest, 0755, ch, tm); err != nil { return false, err } diff --git a/vendor/github.com/tonistiigi/fsutil/copy/copy.go b/vendor/github.com/tonistiigi/fsutil/copy/copy.go index c2b1ab97d080..f24e77f88417 100644 --- a/vendor/github.com/tonistiigi/fsutil/copy/copy.go +++ b/vendor/github.com/tonistiigi/fsutil/copy/copy.go @@ -6,6 +6,7 @@ import ( "path" "path/filepath" "runtime" + "slices" "strings" "sync" "time" @@ -79,8 +80,10 @@ func Copy(ctx context.Context, srcRoot, src, dstRoot, dst string, opts ...Opt) e if err != nil { return err } - if err := MkdirAll(ensureDstPath, 0755, ci.Chown, ci.Utime); err != nil { + if createdDirs, err := MkdirAll(ensureDstPath, 0755, ci.Chown, ci.Utime); err != nil { return err + } else { + defer fixCreatedParentDirs(createdDirs, ci.Utime) } } @@ -120,10 +123,11 @@ func Copy(ctx context.Context, srcRoot, src, dstRoot, dst string, opts ...Opt) e if err != nil { return err } - dst, err := c.prepareTargetDir(srcFollowed, src, dst, ci.CopyDirContents) + dst, createdDirs, err := c.prepareTargetDir(srcFollowed, src, dst, ci.CopyDirContents) if err != nil { return err } + defer fixCreatedParentDirs(createdDirs, ci.Utime) if err := c.copy(ctx, srcFollowed, "", dst, false, patternmatcher.MatchInfo{}, patternmatcher.MatchInfo{}); err != nil { return err } @@ -132,16 +136,16 @@ func Copy(ctx context.Context, srcRoot, src, dstRoot, dst string, opts ...Opt) e return nil } -func (c *copier) prepareTargetDir(srcFollowed, src, destPath string, copyDirContents bool) (string, error) { +func (c *copier) prepareTargetDir(srcFollowed, src, destPath string, copyDirContents bool) (string, []string, error) { fiSrc, err := os.Lstat(srcFollowed) if err != nil { - return "", err + return "", nil, err } fiDest, err := os.Stat(destPath) if err != nil { if !os.IsNotExist(err) { - return "", errors.Wrap(err, "failed to lstat destination path") + return "", nil, errors.Wrap(err, "failed to lstat destination path") } } @@ -154,11 +158,14 @@ func (c *copier) prepareTargetDir(srcFollowed, src, destPath string, copyDirCont if copyDirContents && fiSrc.IsDir() && fiDest == nil { target = destPath } - if err := MkdirAll(target, 0755, c.chown, c.utime); err != nil { - return "", err + var createdDirs []string + if dirs, err := MkdirAll(target, 0755, c.chown, c.utime); err != nil { + return "", nil, err + } else { + createdDirs = dirs } - return destPath, nil + return destPath, createdDirs, nil } type User struct { @@ -689,3 +696,15 @@ func rel(basepath, targpath string) (string, error) { } return filepath.Rel(basepath, targpath) } + +func fixCreatedParentDirs(dirs []string, tm *time.Time) error { + slices.Reverse(dirs) + for _, d := range dirs { + if tm != nil { + if err := Utimes(d, tm); err != nil { + return err + } + } + } + return nil +} diff --git a/vendor/github.com/tonistiigi/fsutil/copy/mkdir.go b/vendor/github.com/tonistiigi/fsutil/copy/mkdir.go index 9553c08be307..b19c2c61370d 100644 --- a/vendor/github.com/tonistiigi/fsutil/copy/mkdir.go +++ b/vendor/github.com/tonistiigi/fsutil/copy/mkdir.go @@ -7,14 +7,14 @@ import ( ) // MkdirAll is forked os.MkdirAll -func MkdirAll(path string, perm os.FileMode, user Chowner, tm *time.Time) error { +func MkdirAll(path string, perm os.FileMode, user Chowner, tm *time.Time) ([]string, error) { // Fast path: if we can tell whether path is a directory or file, stop with success or error. dir, err := os.Stat(path) if err == nil { if dir.IsDir() { - return nil + return nil, nil } - return &os.PathError{Op: "mkdir", Path: path, Err: syscall.ENOTDIR} + return nil, &os.PathError{Op: "mkdir", Path: path, Err: syscall.ENOTDIR} } // Slow path: make sure parent exists and then call Mkdir for path. @@ -28,17 +28,19 @@ func MkdirAll(path string, perm os.FileMode, user Chowner, tm *time.Time) error j-- } + var createdDirs []string + if j > 1 { // Create parent. - err = MkdirAll(fixRootDirectory(path[:j-1]), perm, user, tm) + createdDirs, err = MkdirAll(fixRootDirectory(path[:j-1]), perm, user, tm) if err != nil { - return err + return nil, err } } dir, err1 := os.Lstat(path) if err1 == nil && dir.IsDir() { - return nil + return createdDirs, nil } // Parent now exists; invoke Mkdir and use its result. @@ -48,18 +50,19 @@ func MkdirAll(path string, perm os.FileMode, user Chowner, tm *time.Time) error // double-checking that directory doesn't exist. dir, err1 := os.Lstat(path) if err1 == nil && dir.IsDir() { - return nil + return createdDirs, nil } - return err + return nil, err } + createdDirs = append(createdDirs, path) if err := Chown(path, nil, user); err != nil { - return err + return nil, err } if err := Utimes(path, tm); err != nil { - return err + return nil, err } - return nil + return createdDirs, nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index 63283fa967d0..7316cbdd48ca 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -752,7 +752,7 @@ github.com/stretchr/testify/require # github.com/tonistiigi/dchapes-mode v0.0.0-20241001053921-ca0759fec205 ## explicit; go 1.21 github.com/tonistiigi/dchapes-mode -# github.com/tonistiigi/fsutil v0.0.0-20241003195857-3f140a1299b0 +# github.com/tonistiigi/fsutil v0.0.0-20241028165955-397af5306b5c ## explicit; go 1.21 github.com/tonistiigi/fsutil github.com/tonistiigi/fsutil/copy