diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fbef786b1b1..9dca4ac56873 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -98,6 +98,8 @@ Main (unreleased) - Grafana Agent Operator: `config-reloader` container no longer runs as root. (@rootmout) +- Allow agent to start with `module.git` config if cached before. (@hainenber) + ### Bugfixes - Fixed an issue where `loki.process` validation for stage `metric.counter` was diff --git a/component/module/git/git.go b/component/module/git/git.go index 42ac468477de..f086c70c6876 100644 --- a/component/module/git/git.go +++ b/component/module/git/git.go @@ -3,6 +3,7 @@ package git import ( "context" + "errors" "path/filepath" "reflect" "sync" @@ -193,8 +194,13 @@ func (c *Component) Update(args component.Arguments) (err error) { } // Create or update the repo field. + // Failure to update repository makes the module loader temporarily use cached contents on disk + var updateVcsErr vcs.UpdateFailedError if c.repo == nil || !reflect.DeepEqual(repoOpts, c.repoOpts) { r, err := vcs.NewGitRepo(context.Background(), repoPath, repoOpts) + if errors.As(err, &updateVcsErr) { + level.Error(c.log).Log("msg", "failed to update repository", "err", err) + } if err != nil { return err } @@ -220,8 +226,13 @@ func (c *Component) Update(args component.Arguments) (err error) { // controller. pollFile must only be called with c.mut held. func (c *Component) pollFile(ctx context.Context, args Arguments) error { // Make sure our repo is up-to-date. + var updateVcsErr *vcs.UpdateFailedError if err := c.repo.Update(ctx); err != nil { - return err + if errors.As(err, &updateVcsErr) { + level.Error(c.log).Log("msg", "failed to update repository", "err", err) + } else { + return err + } } // Finally, configure our controller. diff --git a/component/module/git/internal/vcs/git.go b/component/module/git/internal/vcs/git.go index 8209190b90da..76959a30b316 100644 --- a/component/module/git/internal/vcs/git.go +++ b/component/module/git/internal/vcs/git.go @@ -58,15 +58,15 @@ func NewGitRepo(ctx context.Context, storagePath string, opts GitRepoOptions) (* } // Fetch the latest contents. This may be a no-op if we just did a clone. - err = repo.FetchContext(ctx, &git.FetchOptions{ + fetchRepoErr := repo.FetchContext(ctx, &git.FetchOptions{ RemoteName: "origin", Force: true, Auth: opts.Auth.Convert(), }) - if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) { - return nil, UpdateFailedError{ + if fetchRepoErr != nil && !errors.Is(fetchRepoErr, git.NoErrAlreadyUpToDate) { + err = UpdateFailedError{ Repository: opts.Repository, - Inner: err, + Inner: fetchRepoErr, } } @@ -92,7 +92,7 @@ func NewGitRepo(ctx context.Context, storagePath string, opts GitRepoOptions) (* opts: opts, repo: repo, workTree: workTree, - }, nil + }, err } func isRepoCloned(dir string) bool { @@ -103,15 +103,16 @@ func isRepoCloned(dir string) bool { // Update updates the repository by fetching new content and re-checking out to // latest version of Revision. func (repo *GitRepo) Update(ctx context.Context) error { - err := repo.repo.FetchContext(ctx, &git.FetchOptions{ + var err error + fetchRepoErr := repo.repo.FetchContext(ctx, &git.FetchOptions{ RemoteName: "origin", Force: true, Auth: repo.opts.Auth.Convert(), }) - if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) { - return UpdateFailedError{ + if fetchRepoErr != nil && !errors.Is(fetchRepoErr, git.NoErrAlreadyUpToDate) { + err = UpdateFailedError{ Repository: repo.opts.Repository, - Inner: err, + Inner: fetchRepoErr, } } @@ -129,7 +130,7 @@ func (repo *GitRepo) Update(ctx context.Context) error { return err } - return nil + return err } // ReadFile returns a file from the repository specified by path.