diff --git a/integration/dockerfiles/Dockerfile_test_issue_mz863 b/integration/dockerfiles/Dockerfile_test_issue_mz863 new file mode 100644 index 000000000..d4b012ca7 --- /dev/null +++ b/integration/dockerfiles/Dockerfile_test_issue_mz863 @@ -0,0 +1,8 @@ +FROM busybox + +# mz863: COPY --chmod must apply the mode to parent directories that the copy +# creates implicitly, matching buildkit. The single file copy path created every +# implicit parent with a fixed 0755 while only the file itself got the chmod. +COPY --chmod=0600 context/foo /dest/foo +COPY --chmod=0705 context/foo /nested/a/b/foo +RUN stat -c '%a %n' /dest /nested /nested/a /nested/a/b diff --git a/pkg/buildcontext/gcs.go b/pkg/buildcontext/gcs.go index 6e10151dd..23422ffc9 100644 --- a/pkg/buildcontext/gcs.go +++ b/pkg/buildcontext/gcs.go @@ -87,7 +87,7 @@ func getTarFromBucket(bucketName, filepathInBucket, directory string) (string, e } defer reader.Close() tarPath := filepath.Join(directory, constants.ContextTar) - if err := util.CreateFile(tarPath, reader, 0o600, 0, 0); err != nil { + if err := util.CreateFile(tarPath, reader, 0o600, 0o755, 0, 0); err != nil { return "", err } logrus.Debugf("Copied tarball %s from GCS bucket %s to %s", constants.ContextTar, bucketName, tarPath) diff --git a/pkg/commands/copy.go b/pkg/commands/copy.go index 6f871e49f..0df5b7745 100644 --- a/pkg/commands/copy.go +++ b/pkg/commands/copy.go @@ -158,7 +158,7 @@ func (c *CopyCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bu } srcFile := strings.NewReader(src.Data) - err = util.CreateFile(destPath, srcFile, chmod.Apply(0o644), uint32(uid), uint32(gid)) + err = util.CreateFile(destPath, srcFile, chmod.Apply(0o644), chmod.Apply(0o755), uint32(uid), uint32(gid)) if err != nil { return fmt.Errorf("creating file: %w", err) } diff --git a/pkg/util/fs_util.go b/pkg/util/fs_util.go index 24a5d0446..e83d6b904 100644 --- a/pkg/util/fs_util.go +++ b/pkg/util/fs_util.go @@ -684,9 +684,9 @@ func resetFileOwnershipIfNotMatching(path string, newUID, newGID uint32) error { } // CreateFile creates a file at path and copies over contents from the reader -func CreateFile(path string, reader io.Reader, perm os.FileMode, uid uint32, gid uint32) error { +func CreateFile(path string, reader io.Reader, perm os.FileMode, dirPerm os.FileMode, uid uint32, gid uint32) error { // Create directory path if it doesn't exist - if err := createParentDirectory(path, int(uid), int(gid)); err != nil { + if err := createParentDirectory(path, int(uid), int(gid), dirPerm); err != nil { return fmt.Errorf("creating parent dir: %w", err) } @@ -736,7 +736,7 @@ func DownloadFileToDest(rawurl, dest string, uid, gid int64, chmod fs.FileMode) return fmt.Errorf("invalid response status %d", resp.StatusCode) } - if err := CreateFile(dest, resp.Body, chmod, uint32(uid), uint32(gid)); err != nil { + if err := CreateFile(dest, resp.Body, chmod, 0o755, uint32(uid), uint32(gid)); err != nil { return err } mTime := time.Time{} @@ -960,7 +960,7 @@ func CopyFile(src, dest string, context FileContext, uid, gid int64, chmod mode. perm = chmod.Apply(fi.Mode()) } - err = CreateFile(dest, srcFile, perm, uint32(uid), uint32(gid)) + err = CreateFile(dest, srcFile, perm, chmod.Apply(0o755), uint32(uid), uint32(gid)) if err != nil { return false, err } @@ -988,7 +988,7 @@ func CopyFileInternal(src, dest string, context FileContext) error { gid := fi.Sys().(*syscall.Stat_t).Gid mode := fi.Mode() - err = CreateFile(dest, srcFile, mode, uid, gid) + err = CreateFile(dest, srcFile, mode, 0o755, uid, gid) if err != nil { return err } @@ -1309,7 +1309,11 @@ func CopyTimestamps(src string, dest string) error { return nil } -func createParentDirectory(path string, uid int, gid int) error { +func createParentDirectory(path string, uid int, gid int, dirPerm ...os.FileMode) error { + perm := os.FileMode(0o755) + if len(dirPerm) > 0 && config.EnvBool("FF_KANIKO_COPY_CHMOD_ON_IMPLICIT_DIRS") { + perm = dirPerm[0] + } baseDir := filepath.Dir(path) if info, err := os.Lstat(baseDir); os.IsNotExist(err) { logrus.Tracef("BaseDir %s for file %s does not exist. Creating.", baseDir, path) @@ -1325,7 +1329,7 @@ func createParentDirectory(path string, uid int, gid int) error { dir := dirs[i] if _, err := os.Lstat(dir); os.IsNotExist(err) { - err = os.Mkdir(dir, 0o755) + err = os.Mkdir(dir, perm) if err != nil { return err }