From 315858a04ed20ba31481908c8bb78058eea5103d Mon Sep 17 00:00:00 2001 From: hainenber Date: Sat, 1 Jun 2024 16:50:34 +0700 Subject: [PATCH] fix(import/git): fix panic when use non-existent revision on remote Signed-off-by: hainenber --- CHANGELOG.md | 2 + internal/runtime/import_git_test.go | 66 +++++++++++++++++++ .../internal/importsource/import_git.go | 6 +- 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c543ea778a..aa79358cc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,8 @@ Main (unreleased) cluster instance to another could have a staleness marker inserted and result in a gap in metrics (@thampiotr) +- Fix panic when `import.git` are given with revision non-existent on remote repo. (@hainenber) + ### Other changes - `pyroscope.ebpf`, `pyroscope.java`, `pyroscope.scrape`, `pyroscope.write` and `discovery.process` components are now GA. (@korniltsev) diff --git a/internal/runtime/import_git_test.go b/internal/runtime/import_git_test.go index 912f28e808..ed3ffe3b5d 100644 --- a/internal/runtime/import_git_test.go +++ b/internal/runtime/import_git_test.go @@ -317,3 +317,69 @@ const contentsMore = `declare "add" { value = argument.a.value + argument.b.value + 1 } }` + +func TestNoPanicWithNonexistentRevision(t *testing.T) { + testRepo := t.TempDir() + + main := ` +import.git "testImport" { + repository = "` + testRepo + `" + path = "math.alloy" + pull_frequency = "1s" + revision = "nonexistent" +} + +testImport.add "cc" { + a = 1 + b = 1 +} +` + runGit(t, testRepo, "init", testRepo) + + runGit(t, testRepo, "checkout", "-b", "testor") + + math := filepath.Join(testRepo, "math.alloy") + err := os.WriteFile(math, []byte(contents), 0666) + require.NoError(t, err) + + runGit(t, testRepo, "add", ".") + + runGit(t, testRepo, "commit", "-m \"test\"") + + defer verifyNoGoroutineLeaks(t) + ctrl, f := setup(t, main) + err = ctrl.LoadSource(f, nil) + require.NoError(t, err) + ctx, cancel := context.WithCancel(context.Background()) + + var wg sync.WaitGroup + defer func() { + cancel() + wg.Wait() + }() + + wg.Add(1) + go func() { + defer wg.Done() + ctrl.Run(ctx) + }() + + // Check for initial condition + require.Eventually(t, func() bool { + export := getExport[map[string]interface{}](t, ctrl, "", "testImport.add.cc") + return export["sum"] == 2 + }, 5*time.Second, 100*time.Millisecond) + + err = os.WriteFile(math, []byte(contentsMore), 0666) + require.NoError(t, err) + + runGit(t, testRepo, "add", ".") + + runGit(t, testRepo, "commit", "-m \"test2\"") + + // Check for final condition. + require.Eventually(t, func() bool { + export := getExport[map[string]interface{}](t, ctrl, "", "testImport.add.cc") + return export["sum"] == 3 + }, 5*time.Second, 100*time.Millisecond) +} diff --git a/internal/runtime/internal/importsource/import_git.go b/internal/runtime/internal/importsource/import_git.go index 2ab507f720..7c7978f941 100644 --- a/internal/runtime/internal/importsource/import_git.go +++ b/internal/runtime/internal/importsource/import_git.go @@ -10,6 +10,7 @@ import ( "sync" "time" + "github.com/go-git/go-git/v5/plumbing" "github.com/go-kit/log" "github.com/grafana/alloy/internal/component" @@ -194,11 +195,12 @@ func (im *ImportGit) Update(args component.Arguments) (err error) { if im.repo == nil || !reflect.DeepEqual(repoOpts, im.repoOpts) { r, err := vcs.NewGitRepo(context.Background(), repoPath, repoOpts) if err != nil { + if errors.Is(err, plumbing.ErrReferenceNotFound) || !errors.As(err, &vcs.UpdateFailedError{}) { + return err + } if errors.As(err, &vcs.UpdateFailedError{}) { level.Error(im.log).Log("msg", "failed to update repository", "err", err) im.updateHealth(err) - } else { - return err } } im.repo = r