From 494150d81aa6668953407547c3fa6915514cbe0c Mon Sep 17 00:00:00 2001 From: Jeremy Farrell Date: Tue, 5 Sep 2023 20:54:31 -0600 Subject: [PATCH] fix(helm): Cannot add plugins with git fsmonitor daemon enabled Added parameter to optionally ignore any directories in a list. This allows the vcs_installer to skip the .git directory that causes issues when fsmonitor = true in your gitconfig. Signed-off-by: Jeremy Farrell --- internal/third_party/dep/fs/fs.go | 11 +++++++---- internal/third_party/dep/fs/fs_test.go | 25 ++++++++++++++++++------- pkg/plugin/installer/http_installer.go | 2 +- pkg/plugin/installer/vcs_installer.go | 2 +- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/internal/third_party/dep/fs/fs.go b/internal/third_party/dep/fs/fs.go index 4e4eacc60..a1a0758e1 100644 --- a/internal/third_party/dep/fs/fs.go +++ b/internal/third_party/dep/fs/fs.go @@ -33,6 +33,7 @@ package fs import ( "io" + "k8s.io/utils/strings/slices" "os" "path/filepath" "runtime" @@ -67,7 +68,7 @@ func RenameWithFallback(src, dst string) error { func renameByCopy(src, dst string) error { var cerr error if dir, _ := IsDir(src); dir { - cerr = CopyDir(src, dst) + cerr = CopyDir(src, dst, []string{}) if cerr != nil { cerr = errors.Wrap(cerr, "copying directory failed") } @@ -92,7 +93,7 @@ var ( // CopyDir recursively copies a directory tree, attempting to preserve permissions. // Source directory must exist, destination directory must *not* exist. -func CopyDir(src, dst string) error { +func CopyDir(src, dst string, dirs_to_ignore []string) error { src = filepath.Clean(src) dst = filepath.Clean(dst) @@ -128,8 +129,10 @@ func CopyDir(src, dst string) error { dstPath := filepath.Join(dst, entry.Name()) if entry.IsDir() { - if err = CopyDir(srcPath, dstPath); err != nil { - return errors.Wrap(err, "copying directory failed") + if !slices.Contains(dirs_to_ignore, entry.Name()) { + if err = CopyDir(srcPath, dstPath, dirs_to_ignore); err != nil { + return errors.Wrap(err, "copying directory failed") + } } } else { // This will include symlinks, which is what we want when diff --git a/internal/third_party/dep/fs/fs_test.go b/internal/third_party/dep/fs/fs_test.go index d42c3f110..87f03c535 100644 --- a/internal/third_party/dep/fs/fs_test.go +++ b/internal/third_party/dep/fs/fs_test.go @@ -92,6 +92,7 @@ func TestCopyDir(t *testing.T) { fi os.FileInfo }{ {path: "myfile", contents: "hello world"}, + {path: filepath.Join(".git", "file"), contents: ".git file"}, {path: filepath.Join("subdir", "file"), contents: "subdir file"}, } @@ -120,13 +121,13 @@ func TestCopyDir(t *testing.T) { } destdir := filepath.Join(dir, "dest") - if err := CopyDir(srcdir, destdir); err != nil { + if err := CopyDir(srcdir, destdir, []string{}); err != nil { t.Fatal(err) } // Compare copy against structure indicated in 'files' for _, file := range files { - fn := filepath.Join(srcdir, file.path) + fn := filepath.Join(destdir, file.path) dn := filepath.Dir(fn) dirOK, err := IsDir(dn) if err != nil { @@ -155,6 +156,16 @@ func TestCopyDir(t *testing.T) { file.path, file.fi.Mode(), fn, gotinfo.Mode()) } } + os.RemoveAll(destdir) + if err := CopyDir(srcdir, destdir, []string{".git"}); err != nil { + t.Fatal(err) + } + destdirGit := filepath.Join(destdir, ".git") + dirOK, _ := IsDir(destdirGit) + + if dirOK { + t.Fatalf("expected %s to not be copied", destdirGit) + } } func TestCopyDirFail_SrcInaccessible(t *testing.T) { @@ -183,7 +194,7 @@ func TestCopyDirFail_SrcInaccessible(t *testing.T) { dir := t.TempDir() dstdir = filepath.Join(dir, "dst") - if err := CopyDir(srcdir, dstdir); err == nil { + if err := CopyDir(srcdir, dstdir, []string{}); err == nil { t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir) } } @@ -218,7 +229,7 @@ func TestCopyDirFail_DstInaccessible(t *testing.T) { }) defer cleanup() - if err := CopyDir(srcdir, dstdir); err == nil { + if err := CopyDir(srcdir, dstdir, []string{}); err == nil { t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir) } } @@ -236,7 +247,7 @@ func TestCopyDirFail_SrcIsNotDir(t *testing.T) { dstdir = filepath.Join(dir, "dst") - if err = CopyDir(srcdir, dstdir); err == nil { + if err = CopyDir(srcdir, dstdir, []string{}); err == nil { t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir) } @@ -262,7 +273,7 @@ func TestCopyDirFail_DstExists(t *testing.T) { t.Fatal(err) } - if err = CopyDir(srcdir, dstdir); err == nil { + if err = CopyDir(srcdir, dstdir, []string{}); err == nil { t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir) } @@ -312,7 +323,7 @@ func TestCopyDirFailOpen(t *testing.T) { dstdir = filepath.Join(dir, "dst") - if err = CopyDir(srcdir, dstdir); err == nil { + if err = CopyDir(srcdir, dstdir, []string{}); err == nil { t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir) } } diff --git a/pkg/plugin/installer/http_installer.go b/pkg/plugin/installer/http_installer.go index 49274f83c..341bed8e2 100644 --- a/pkg/plugin/installer/http_installer.go +++ b/pkg/plugin/installer/http_installer.go @@ -145,7 +145,7 @@ func (i *HTTPInstaller) Install() error { } debug("copying %s to %s", src, i.Path()) - return fs.CopyDir(src, i.Path()) + return fs.CopyDir(src, i.Path(), []string{}) } // Update updates a local repository diff --git a/pkg/plugin/installer/vcs_installer.go b/pkg/plugin/installer/vcs_installer.go index f7df5b322..5a7906981 100644 --- a/pkg/plugin/installer/vcs_installer.go +++ b/pkg/plugin/installer/vcs_installer.go @@ -89,7 +89,7 @@ func (i *VCSInstaller) Install() error { } debug("copying %s to %s", i.Repo.LocalPath(), i.Path()) - return fs.CopyDir(i.Repo.LocalPath(), i.Path()) + return fs.CopyDir(i.Repo.LocalPath(), i.Path(), []string{".git"}) } // Update updates a remote repository