From b433ddd6bb98ccfff9d42f6d880ce5c5f597a6d9 Mon Sep 17 00:00:00 2001 From: Quan Zhang Date: Tue, 31 Oct 2023 16:29:23 -0400 Subject: [PATCH] fix: fix `COPY` command error due to missing but ignored files (#2812) Fixes https://github.com/GoogleContainerTools/kaniko/issues/1598. This commit puts `context.ExcludesFile` before `os.Lstat` to avoid the `COPY` command error due to missing but ignored files. --- pkg/commands/copy_test.go | 55 +++++++++++++++++++++++++++++++++++++++ pkg/util/fs_util.go | 8 +++--- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/pkg/commands/copy_test.go b/pkg/commands/copy_test.go index 0504df423..3eba9c6b2 100755 --- a/pkg/commands/copy_test.go +++ b/pkg/commands/copy_test.go @@ -20,6 +20,7 @@ import ( "archive/tar" "fmt" "io" + "io/fs" "io/ioutil" "os" "path/filepath" @@ -461,6 +462,60 @@ func TestCopyCommand_ExecuteCommand_Extended(t *testing.T) { } }) + t.Run("copy dir to another dir - with ignored files", func(t *testing.T) { + testDir, srcDir := setupDirs(t) + defer os.RemoveAll(testDir) + ignoredFile := "bam.txt" + srcFiles, err := ioutil.ReadDir(filepath.Join(testDir, srcDir)) + if err != nil { + t.Fatal(err) + } + expected := map[string]fs.FileInfo{} + for _, sf := range srcFiles { + if sf.Name() == ignoredFile { + continue + } + expected[sf.Name()] = sf + } + + cmd := CopyCommand{ + cmd: &instructions.CopyCommand{ + SourcesAndDest: instructions.SourcesAndDest{SourcePaths: []string{srcDir}, DestPath: "dest"}, + }, + fileContext: util.FileContext{ + Root: testDir, + ExcludedFiles: []string{filepath.Join(srcDir, ignoredFile)}}, + } + + cfg := &v1.Config{ + Cmd: nil, + Env: []string{}, + WorkingDir: testDir, + } + + err = cmd.ExecuteCommand(cfg, dockerfile.NewBuildArgs([]string{})) + if err != nil { + t.Fatal(err) + } + testutil.CheckNoError(t, err) + // Check if "dest" dir exists with contents of srcDir + actual, err := ioutil.ReadDir(filepath.Join(testDir, "dest")) + if err != nil { + t.Fatal(err) + } + + if len(actual) != len(expected) { + t.Errorf("%v files are expected to be copied, but got %v", len(expected), len(actual)) + } + for _, f := range actual { + if f.Name() == ignoredFile { + t.Errorf("file %v is expected to be ignored, but copied", f.Name()) + } + testutil.CheckDeepEqual(t, expected[f.Name()].Name(), f.Name()) + testutil.CheckDeepEqual(t, expected[f.Name()].Mode(), f.Mode()) + } + }) + t.Run("copy file to a dir", func(t *testing.T) { testDir, srcDir := setupDirs(t) defer os.RemoveAll(testDir) diff --git a/pkg/util/fs_util.go b/pkg/util/fs_util.go index b57799b8f..441e1b414 100644 --- a/pkg/util/fs_util.go +++ b/pkg/util/fs_util.go @@ -663,14 +663,14 @@ func CopyDir(src, dest string, context FileContext, uid, gid int64) ([]string, e var copiedFiles []string for _, file := range files { fullPath := filepath.Join(src, file) - fi, err := os.Lstat(fullPath) - if err != nil { - return nil, errors.Wrap(err, "copying dir") - } if context.ExcludesFile(fullPath) { logrus.Debugf("%s found in .dockerignore, ignoring", src) continue } + fi, err := os.Lstat(fullPath) + if err != nil { + return nil, errors.Wrap(err, "copying dir") + } destPath := filepath.Join(dest, file) if fi.IsDir() { logrus.Tracef("Creating directory %s", destPath)