Skip to content

Conversation

alexymantha
Copy link
Member

@alexymantha alexymantha commented Sep 22, 2023

Adds a new function to the repo-server that compares 2 revisions and updates the cache with the new revision if no changes are detected. This leverages the manifest-generate-paths annotation that is already used by the webhook to determine what should be compared. The behaviour of doing the comparison and updating the cache is very similar to what is done with the webhooks.

The goal is to avoid unnecessary manifest generation when a new commit does not change any files in an application, it will reuse the already generated manifest instead.

The implementation is based on what was discussed here: https://cloud-native.slack.com/archives/C04SURUPDL2/p1686849819036059

Closes #14242

Checklist:

  • Either (a) I've created an enhancement proposal and discussed it with the community, (b) this is a bug fix, or (c) this does not need to be in the release notes.
  • The title of the PR states what changed and the related issues number (used for the release note).
  • The title of the PR conforms to the Toolchain Guide
  • I've included "Closes [ISSUE #]" or "Fixes [ISSUE #]" in the description to automatically close the associated issue.
  • I've updated both the CLI and UI to expose my feature, or I plan to submit a second PR with them.
  • Does this PR require documentation updates?
  • I've updated documentation as required by this PR.
  • Optional. My organization is added to USERS.md.
  • I have signed off all my commits as required by DCO
  • I have written unit and/or e2e tests for my change. PRs without these are unlikely to be merged.
  • My build is green (troubleshooting builds).
  • My new feature complies with the feature status guidelines.
  • I have added a brief description of why this PR is necessary and/or what this PR solves.

@codecov
Copy link

codecov bot commented Sep 22, 2023

Codecov Report

Attention: Patch coverage is 81.87500% with 29 lines in your changes are missing coverage. Please review.

Project coverage is 49.35%. Comparing base (f87897c) to head (37fdd8f).
Report is 18 commits behind head on master.

❗ Current head 37fdd8f differs from pull request most recent head 755bdc1. Consider uploading reports for the commit 755bdc1 to get more accurate results

Files Patch % Lines
reposerver/repository/repository.go 67.90% 19 Missing and 7 partials ⚠️
controller/state.go 85.71% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #15636      +/-   ##
==========================================
- Coverage   49.73%   49.35%   -0.38%     
==========================================
  Files         274      274              
  Lines       48948    48282     -666     
==========================================
- Hits        24343    23831     -512     
+ Misses      22230    22102     -128     
+ Partials     2375     2349      -26     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@crenshaw-dev
Copy link
Member

This is looking very cool btw. lmk if you need any help!

@alexymantha alexymantha force-pushed the enforce-manifest-generate-path branch 6 times, most recently from 3c917f8 to 89023d6 Compare September 27, 2023 20:35
@@ -364,70 +364,6 @@ func (a *ArgoCDWebhookHandler) storePreviouslyCachedManifests(app *v1alpha1.Appl
return nil
}

func getAppRefreshPaths(app *v1alpha1.Application) []string {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to the app/path so it can be reused in the repo-server

@alexymantha alexymantha marked this pull request as ready for review September 27, 2023 20:58
@alexymantha alexymantha requested review from a team as code owners September 27, 2023 20:58
@alexymantha
Copy link
Member Author

Thanks @crenshaw-dev! I think it's ready for a first round of reviews

I'm also working on gathering some stats to see the performance improvements that this provides for monorepos. I will update as soon as I have some data

@alexymantha alexymantha force-pushed the enforce-manifest-generate-path branch from 3c57949 to af8b9bd Compare October 3, 2023 18:17
@alexymantha alexymantha requested a review from a team as a code owner October 3, 2023 18:17
@alexymantha alexymantha force-pushed the enforce-manifest-generate-path branch 7 times, most recently from 766c74c to b3dfd50 Compare October 3, 2023 18:29
Signed-off-by: Alexy Mantha <alexy@mantha.dev>
Copy link
Member

@pasha-codefresh pasha-codefresh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked it locally, works really fine! Great job!

err := s.cache.SetNewRevisionManifests(newRev, oldRev, request.ApplicationSource, request.RefSources, request, request.Namespace, request.TrackingMethod, request.AppLabelKey, request.AppName, repoRefs)
if err != nil {
if err == cache.ErrCacheMiss {
log.WithFields(log.Fields{"application": request.AppName, "appNamespace": request.Namespace}).Debugf("manifest cache miss during comparison for application %s in repo %s from revision %s", request.AppName, request.GetRepo().Repo, oldRev)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was running some test locally and I got the following error.

The test was

  • create an app with the annotation and without auto-sync
  • Sync it to HEAD (08484ff536ba26aecf0103476e223297459c2fd3)
  • Commit to HEAD outside the path (4bf66a93e785b7af4e56d33ec13cbf344072a8b8)
  • Manual Refresh (15:02:57)
  • Manual Sync (15:07:04)
argocd-repo-server time="2024-02-28T15:02:57Z" level=debug msg="manifest cache updated for application app2 in repo https://github.com/agaudreault/gitops-tests from revision 08484ff536ba26aecf0103476e223297459c2fd3 to revision 4bf66a93e785b7af4e56d33ec13cbf344072a8b8" appNamespace=dev application=app2
argocd-repo-server time="2024-02-28T15:07:04Z" level=debug msg="no changes found for application app2 in repo https://github.com/agaudreault/gitops-tests from revision 08484ff536ba26aecf0103476e223297459c2fd3 to revision 4bf66a93e785b7af4e56d33ec13cbf344072a8b8" appNamespace=dev application=app2
argocd-repo-server time="2024-02-28T15:07:04Z" level=warning msg="error updating cached revision for repo https://github.com/agaudreault/gitops-tests with revision 4bf66a93e785b7af4e56d33ec13cbf344072a8b8: manifest cache move error for app2: ERR no such key" appNamespace=dev application=app2

I wonder if we should handle the warning in a different way. From what I understand, it will warn for cache miss as long as the app differs from the HEAD, which will be a lot.

The overall behaviour works as expected and the manifests are not regenerated during the manual refresh or sync.
The application status.operationState.sync.revision will be 4bf66a, but the value of status.operationState.syncResult.revision and status.sync.revision will be 08484f (what is displayed in the UI)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm you're right, that was previously caught by err == cache.ErrCacheMiss but digging into the code it looks like, unlike the Get, the new Rename for the Redis cache does not handle the cache miss and instead returns the raw Redis error. It seems to be an inconsistency because the other caches (like the in-memory) do return ErrCacheMiss on a miss, I'll see if I can update the Redis cache to handle the miss properly

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the cache miss in cache/redis.go

_, err = repoClient.UpdateRevisionForPaths(context.Background(), &apiclient.UpdateRevisionForPathsRequest{
Repo: repo,
Revision: revisions[i],
SyncedRevision: app.Status.Sync.Revision,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it is multi-source, app.Status.Sync.Revision[i] should be used everywhere in the loop.

@alexymantha alexymantha force-pushed the enforce-manifest-generate-path branch from a4c576a to 8aac2af Compare March 28, 2024 22:28
Signed-off-by: Alexy Mantha <alexy@mantha.dev>
Signed-off-by: Alexy Mantha <alexy@mantha.dev>
Copy link
Member

@crenshaw-dev crenshaw-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few small things, I think. Testing now.

}

message UpdateRevisionForPathsResponse {
bool changes = 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we should just drop this field. It's not used anywhere besides the unit test. If what we really need from the API call is the side effect (updating the cache key), then we should probably just test for the side-effect.

Comment on lines +2761 to +2764
}

// Update revision in refSource
if request.HasMultipleSources && request.ApplicationSource.Helm != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
// Update revision in refSource
if request.HasMultipleSources && request.ApplicationSource.Helm != nil {
// Update revision in refSource

Can we simplify like this?

Comment on lines +708 to +709
// returns the meta-data for the commit
func (m *nativeGitClient) ChangedFiles(revision string, targetRevision string) ([]string, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// returns the meta-data for the commit
func (m *nativeGitClient) ChangedFiles(revision string, targetRevision string) ([]string, error) {
// ChangedFiles returns a list of files changed between two revisions
func (m *nativeGitClient) ChangedFiles(revision string, targetRevision string) ([]string, error) {

Copy link
Member

@crenshaw-dev crenshaw-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something else I noticed is that the feature won't work for skipping unrelated changes in external Helm values files. The referenced git repo's source revision is part of the Helm chart source's cache key, so when that SHA changes, the Helm chart source contents get re-generated. The Helm chart source generation code doesn't make any accommodations for the manifest-generate-path annotation.

I'll merge for now to get the change into 2.11 (overall it looks and behaves great). I'd just request a follow-up PR for the nitpicks (if they're accurate) and a docs PR to note that the shortcut doesn't work for external Helm values files.

@crenshaw-dev crenshaw-dev merged commit 4e46a5e into argoproj:master Apr 4, 2024
crenshaw-dev pushed a commit that referenced this pull request Apr 7, 2024
…17761)

* cleanup

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* update docs

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

---------

Signed-off-by: Alexy Mantha <alexy@mantha.dev>
mkieweg pushed a commit to mkieweg/argo-cd that referenced this pull request Jun 11, 2024
…roj#14242) (argoproj#15636)

* squash commits

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* Update util/git/client.go

Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fix error message

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* add git client options

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* Update generated code

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* run fmt

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fix tests

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* failed gen

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* tweak logs and rename cache

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* validate revisions

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fix tests

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fix tests

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fmt

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fix linting

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fixes from review

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* generate

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fix

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* use log context

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

---------

Signed-off-by: Alexy Mantha <alexy@mantha.dev>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
mkieweg pushed a commit to mkieweg/argo-cd that referenced this pull request Jun 11, 2024
…#15636) (argoproj#17761)

* cleanup

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* update docs

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

---------

Signed-off-by: Alexy Mantha <alexy@mantha.dev>
Hariharasuthan99 pushed a commit to AmadeusITGroup/argo-cd that referenced this pull request Jun 16, 2024
…roj#14242) (argoproj#15636)

* squash commits

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* Update util/git/client.go

Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fix error message

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* add git client options

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* Update generated code

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* run fmt

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fix tests

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* failed gen

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* tweak logs and rename cache

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* validate revisions

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fix tests

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fix tests

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fmt

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fix linting

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fixes from review

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* generate

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* fix

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* use log context

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

---------

Signed-off-by: Alexy Mantha <alexy@mantha.dev>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Hariharasuthan99 pushed a commit to AmadeusITGroup/argo-cd that referenced this pull request Jun 16, 2024
…#15636) (argoproj#17761)

* cleanup

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

* update docs

Signed-off-by: Alexy Mantha <alexy@mantha.dev>

---------

Signed-off-by: Alexy Mantha <alexy@mantha.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Status: Completed
Development

Successfully merging this pull request may close these issues.

Honor manifest-generate-paths annotation during CompareWithLatest
7 participants