Skip to content

Commit 7475ea8

Browse files
authored
Execute git clean partially when drift detection for every app is done (#5312)
* Execute git clean partially when drift detection for every app is done Signed-off-by: Yoshiki Fujikane <[email protected]> * Rename to CleanPath Signed-off-by: Yoshiki Fujikane <[email protected]> * Add test for the outside dir pattern Signed-off-by: Yoshiki Fujikane <[email protected]> --------- Signed-off-by: Yoshiki Fujikane <[email protected]>
1 parent 5898f42 commit 7475ea8

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed

pkg/app/piped/driftdetector/kubernetes/detector.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,23 @@ func (d *detector) check(ctx context.Context) {
169169
if err := d.checkApplication(ctx, app, gitRepo, headCommit); err != nil {
170170
d.logger.Error(fmt.Sprintf("failed to check application: %s", app.Id), zap.Error(err))
171171
}
172+
173+
// Reset the app dir to the head commit.
174+
// Some tools may create temporary files locally to render manifests.
175+
// The detector reuses the same located local repository and it causes unexpected behavior by reusing such temporary files.
176+
// So regularly run git clean on the app dir after each detection.
177+
d.logger.Info("cleaning partially cloned repository",
178+
zap.String("repo-id", repoID),
179+
zap.String("app-id", app.Id),
180+
zap.String("app-path", app.GitPath.Path),
181+
)
182+
if err := gitRepo.CleanPath(ctx, app.GitPath.Path); err != nil {
183+
d.logger.Error("failed to clean partially cloned repository",
184+
zap.String("repo-id", repoID),
185+
zap.String("app-id", app.Id),
186+
zap.String("app-path", app.GitPath.Path),
187+
zap.Error(err))
188+
}
172189
}
173190
}
174191
}

pkg/git/gittest/git.mock.go

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/git/repo.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type Repo interface {
4343
Checkout(ctx context.Context, commitish string) error
4444
CheckoutPullRequest(ctx context.Context, number int, branch string) error
4545
Clean() error
46+
CleanPath(ctx context.Context, relativePath string) error
4647

4748
Pull(ctx context.Context, branch string) error
4849
MergeRemoteBranch(ctx context.Context, branch, commit, mergeCommitMessage string) error
@@ -259,6 +260,15 @@ func (r repo) Clean() error {
259260
return os.RemoveAll(r.dir)
260261
}
261262

263+
// CleanPath deletes data in the given relative path in the repo with git clean.
264+
func (r repo) CleanPath(ctx context.Context, relativePath string) error {
265+
out, err := r.runGitCommand(ctx, "clean", "-f", relativePath)
266+
if err != nil {
267+
return formatCommandError(err, out)
268+
}
269+
return nil
270+
}
271+
262272
func (r *repo) checkoutNewBranch(ctx context.Context, branch string) error {
263273
out, err := r.runGitCommand(ctx, "checkout", "-b", branch)
264274
if err != nil {

pkg/git/repo_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,68 @@ func TestGetCommitForRev(t *testing.T) {
279279
require.NoError(t, err)
280280
assert.Equal(t, commits[0].Hash, commit.Hash)
281281
}
282+
283+
func TestCleanPath(t *testing.T) {
284+
faker, err := newFaker()
285+
require.NoError(t, err)
286+
defer faker.clean()
287+
288+
var (
289+
org = "test-repo-org"
290+
repoName = "repo-clean-path"
291+
ctx = context.Background()
292+
)
293+
294+
err = faker.makeRepo(org, repoName)
295+
require.NoError(t, err)
296+
r := &repo{
297+
dir: faker.repoDir(org, repoName),
298+
gitPath: faker.gitPath,
299+
}
300+
301+
// create two directories and a file in each
302+
// repo-clean-path/part1/new-file.txt
303+
// repo-clean-path/part2/new-file.txt
304+
dirs := []string{"part1", "part2"}
305+
for _, dir := range dirs {
306+
partDir := filepath.Join(r.dir, dir)
307+
err = os.MkdirAll(partDir, os.ModePerm)
308+
require.NoError(t, err)
309+
310+
path := filepath.Join(partDir, "new-file.txt")
311+
err = os.WriteFile(path, []byte("content"), os.ModePerm)
312+
require.NoError(t, err)
313+
}
314+
315+
// create other dir outside the repo
316+
// repo-clean-path/outside-dir/new-file.txt
317+
outsideDir := filepath.Join(r.dir, "..", "outside-dir")
318+
require.NoError(t, err)
319+
320+
err = os.MkdirAll(outsideDir, os.ModePerm)
321+
require.NoError(t, err)
322+
323+
path := filepath.Join(outsideDir, "new-file.txt")
324+
err = os.WriteFile(path, []byte("content"), os.ModePerm)
325+
require.NoError(t, err)
326+
327+
// clean the repo-dir/part1
328+
err = r.CleanPath(ctx, "part1")
329+
require.NoError(t, err)
330+
331+
// check the repo-dir/part1 is removed
332+
_, err = os.Stat(filepath.Join(r.dir, "part1"))
333+
assert.True(t, os.IsNotExist(err))
334+
335+
// check the repo-dir/part2 is still there
336+
_, err = os.Stat(filepath.Join(r.dir, "part2"))
337+
assert.NoError(t, err)
338+
339+
// check the outside dir can't be cleaned with relative path
340+
err = r.CleanPath(ctx, "../outside-dir")
341+
require.Error(t, err)
342+
343+
// check the outside dir can't be cleaned with relative path
344+
err = r.CleanPath(ctx, outsideDir)
345+
require.Error(t, err)
346+
}

0 commit comments

Comments
 (0)