Skip to content

Commit a31bf96

Browse files
Merge branch 'release-2.11' of github.com:codefresh-io/argo-cd into release-2.11
2 parents f09e338 + c787eab commit a31bf96

File tree

14 files changed

+1019
-723
lines changed

14 files changed

+1019
-723
lines changed

assets/swagger.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9302,6 +9302,13 @@
93029302
"comparedTo": {
93039303
"$ref": "#/definitions/v1alpha1ComparedTo"
93049304
},
9305+
"manifestsChanged": {
9306+
"type": "object",
9307+
"title": "ManifestsChanged indicates whether the manifests have changed base on argocd.argoproj.io/manifest-generate-paths annotation",
9308+
"additionalProperties": {
9309+
"type": "boolean"
9310+
}
9311+
},
93059312
"revision": {
93069313
"type": "string",
93079314
"title": "Revision contains information about the revision the comparison has been performed to"

controller/appcontroller.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"math"
99
"math/rand"
1010
"net/http"
11+
"os"
1112
"reflect"
1213
"runtime/debug"
1314
"sort"
@@ -1959,8 +1960,11 @@ func alreadyAttemptedSync(app *appv1.Application, commitSHA string, commitSHAsMS
19591960
return false, ""
19601961
}
19611962
} else {
1962-
if app.Status.OperationState.SyncResult.Revision != commitSHA {
1963-
return false, ""
1963+
manifestsChangedMap := app.Status.Sync.ManifestsChanged
1964+
if os.Getenv("PERSIST_CHANGE_REVISIONS") != "1" || manifestsChangedMap[commitSHA] {
1965+
if app.Status.OperationState.SyncResult.Revision != commitSHA {
1966+
return false, ""
1967+
}
19641968
}
19651969
}
19661970

controller/appcontroller_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"errors"
7+
"os"
78
"testing"
89
"time"
910

@@ -1929,3 +1930,54 @@ func TestAddControllerNamespace(t *testing.T) {
19291930
assert.Equal(t, test.FakeArgoCDNamespace, updatedApp.Status.ControllerNamespace)
19301931
})
19311932
}
1933+
1934+
func TestAlreadyAttemptSync(t *testing.T) {
1935+
app := newFakeApp()
1936+
t.Run("same manifest with sync result, with disabled flag", func(t *testing.T) {
1937+
1938+
manifestChangedMap := make(map[string]bool)
1939+
manifestChangedMap["sha"] = false
1940+
1941+
app.Status.Sync.ManifestsChanged = manifestChangedMap
1942+
1943+
attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false)
1944+
assert.False(t, attempted)
1945+
})
1946+
1947+
t.Run("same manifest with sync result, with enabled flag", func(t *testing.T) {
1948+
1949+
_ = os.Setenv("PERSIST_CHANGE_REVISIONS", "1")
1950+
1951+
manifestChangedMap := make(map[string]bool)
1952+
manifestChangedMap["sha"] = false
1953+
1954+
app.Status.Sync.ManifestsChanged = manifestChangedMap
1955+
1956+
attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false)
1957+
assert.True(t, attempted)
1958+
})
1959+
1960+
t.Run("different manifest with sync result, with disabled flag", func(t *testing.T) {
1961+
1962+
manifestChangedMap := make(map[string]bool)
1963+
manifestChangedMap["sha"] = true
1964+
1965+
app.Status.Sync.ManifestsChanged = manifestChangedMap
1966+
1967+
attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false)
1968+
assert.False(t, attempted)
1969+
})
1970+
1971+
t.Run("different manifest with sync result, with enabled flag", func(t *testing.T) {
1972+
1973+
_ = os.Setenv("PERSIST_CHANGE_REVISIONS", "1")
1974+
1975+
manifestChangedMap := make(map[string]bool)
1976+
manifestChangedMap["sha"] = true
1977+
1978+
app.Status.Sync.ManifestsChanged = manifestChangedMap
1979+
1980+
attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false)
1981+
assert.False(t, attempted)
1982+
})
1983+
}

controller/hook.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func (ctrl *ApplicationController) executePostDeleteHooks(app *v1alpha1.Applicat
5151
revisions = append(revisions, src.TargetRevision)
5252
}
5353

54-
targets, _, err := ctrl.appStateManager.GetRepoObjs(app, app.Spec.GetSources(), appLabelKey, revisions, false, false, false, proj)
54+
targets, _, _, err := ctrl.appStateManager.GetRepoObjs(app, app.Spec.GetSources(), appLabelKey, revisions, false, false, false, proj)
5555
if err != nil {
5656
return false, err
5757
}

controller/state.go

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8+
"os"
89
"reflect"
910
"strings"
1011
goSync "sync"
@@ -73,7 +74,7 @@ type managedResource struct {
7374
type AppStateManager interface {
7475
CompareAppState(app *v1alpha1.Application, project *v1alpha1.AppProject, revisions []string, sources []v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localObjects []string, hasMultipleSources bool) (*comparisonResult, error)
7576
SyncAppState(app *v1alpha1.Application, state *v1alpha1.OperationState)
76-
GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, error)
77+
GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, map[string]bool, error)
7778
}
7879

7980
// comparisonResult holds the state of an application after the reconciliation
@@ -126,51 +127,51 @@ type appStateManager struct {
126127
// task to the repo-server. It returns the list of generated manifests as unstructured
127128
// objects. It also returns the full response from all calls to the repo server as the
128129
// second argument.
129-
func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, error) {
130+
func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, map[string]bool, error) {
130131
ts := stats.NewTimingStats()
131132
helmRepos, err := m.db.ListHelmRepositories(context.Background())
132133
if err != nil {
133-
return nil, nil, fmt.Errorf("failed to list Helm repositories: %w", err)
134+
return nil, nil, nil, fmt.Errorf("failed to list Helm repositories: %w", err)
134135
}
135136
permittedHelmRepos, err := argo.GetPermittedRepos(proj, helmRepos)
136137
if err != nil {
137-
return nil, nil, fmt.Errorf("failed to get permitted Helm repositories for project %q: %w", proj.Name, err)
138+
return nil, nil, nil, fmt.Errorf("failed to get permitted Helm repositories for project %q: %w", proj.Name, err)
138139
}
139140

140141
ts.AddCheckpoint("repo_ms")
141142
helmRepositoryCredentials, err := m.db.GetAllHelmRepositoryCredentials(context.Background())
142143
if err != nil {
143-
return nil, nil, fmt.Errorf("failed to get Helm credentials: %w", err)
144+
return nil, nil, nil, fmt.Errorf("failed to get Helm credentials: %w", err)
144145
}
145146
permittedHelmCredentials, err := argo.GetPermittedReposCredentials(proj, helmRepositoryCredentials)
146147
if err != nil {
147-
return nil, nil, fmt.Errorf("failed to get permitted Helm credentials for project %q: %w", proj.Name, err)
148+
return nil, nil, nil, fmt.Errorf("failed to get permitted Helm credentials for project %q: %w", proj.Name, err)
148149
}
149150

150151
enabledSourceTypes, err := m.settingsMgr.GetEnabledSourceTypes()
151152
if err != nil {
152-
return nil, nil, fmt.Errorf("failed to get enabled source types: %w", err)
153+
return nil, nil, nil, fmt.Errorf("failed to get enabled source types: %w", err)
153154
}
154155
ts.AddCheckpoint("plugins_ms")
155156

156157
kustomizeSettings, err := m.settingsMgr.GetKustomizeSettings()
157158
if err != nil {
158-
return nil, nil, fmt.Errorf("failed to get Kustomize settings: %w", err)
159+
return nil, nil, nil, fmt.Errorf("failed to get Kustomize settings: %w", err)
159160
}
160161

161162
helmOptions, err := m.settingsMgr.GetHelmSettings()
162163
if err != nil {
163-
return nil, nil, fmt.Errorf("failed to get Helm settings: %w", err)
164+
return nil, nil, nil, fmt.Errorf("failed to get Helm settings: %w", err)
164165
}
165166

166167
ts.AddCheckpoint("build_options_ms")
167168
serverVersion, apiResources, err := m.liveStateCache.GetVersionsInfo(app.Spec.Destination.Server)
168169
if err != nil {
169-
return nil, nil, fmt.Errorf("failed to get cluster version for cluster %q: %w", app.Spec.Destination.Server, err)
170+
return nil, nil, nil, fmt.Errorf("failed to get cluster version for cluster %q: %w", app.Spec.Destination.Server, err)
170171
}
171172
conn, repoClient, err := m.repoClientset.NewRepoServerClient()
172173
if err != nil {
173-
return nil, nil, fmt.Errorf("failed to connect to repo server: %w", err)
174+
return nil, nil, nil, fmt.Errorf("failed to connect to repo server: %w", err)
174175
}
175176
defer io.Close(conn)
176177

@@ -180,21 +181,23 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
180181
// Store the map of all sources having ref field into a map for applications with sources field
181182
refSources, err := argo.GetRefSources(context.Background(), app.Spec, m.db)
182183
if err != nil {
183-
return nil, nil, fmt.Errorf("failed to get ref sources: %v", err)
184+
return nil, nil, nil, fmt.Errorf("failed to get ref sources: %v", err)
184185
}
185186

187+
manifestsChanges := make(map[string]bool)
188+
186189
for i, source := range sources {
187190
if len(revisions) < len(sources) || revisions[i] == "" {
188191
revisions[i] = source.TargetRevision
189192
}
190193
ts.AddCheckpoint("helm_ms")
191194
repo, err := m.db.GetRepository(context.Background(), source.RepoURL)
192195
if err != nil {
193-
return nil, nil, fmt.Errorf("failed to get repo %q: %w", source.RepoURL, err)
196+
return nil, nil, nil, fmt.Errorf("failed to get repo %q: %w", source.RepoURL, err)
194197
}
195198
kustomizeOptions, err := kustomizeSettings.GetOptions(source, m.settingsMgr.GetKustomizeSetNamespaceEnabled())
196199
if err != nil {
197-
return nil, nil, fmt.Errorf("failed to get Kustomize options for source %d of %d: %w", i+1, len(sources), err)
200+
return nil, nil, nil, fmt.Errorf("failed to get Kustomize options for source %d of %d: %w", i+1, len(sources), err)
198201
}
199202

200203
syncedRevision := app.Status.Sync.Revision
@@ -209,7 +212,7 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
209212
val, ok := app.Annotations[v1alpha1.AnnotationKeyManifestGeneratePaths]
210213
if !source.IsHelm() && syncedRevision != "" && ok && val != "" {
211214
// Validate the manifest-generate-path annotation to avoid generating manifests if it has not changed.
212-
_, err = repoClient.UpdateRevisionForPaths(context.Background(), &apiclient.UpdateRevisionForPathsRequest{
215+
updateRevisionResponse, err := repoClient.UpdateRevisionForPaths(context.Background(), &apiclient.UpdateRevisionForPathsRequest{
213216
Repo: repo,
214217
Revision: revisions[i],
215218
SyncedRevision: syncedRevision,
@@ -224,8 +227,13 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
224227
RefSources: refSources,
225228
HasMultipleSources: app.Spec.HasMultipleSources(),
226229
})
230+
231+
// not need to change, if we already found at least one cached revision that has no changes
232+
if updateRevisionResponse != nil && os.Getenv("PERSIST_CHANGE_REVISIONS") == "1" {
233+
manifestsChanges[syncedRevision] = updateRevisionResponse.Changes
234+
}
227235
if err != nil {
228-
return nil, nil, fmt.Errorf("failed to compare revisions for source %d of %d: %w", i+1, len(sources), err)
236+
return nil, nil, nil, fmt.Errorf("failed to compare revisions for source %d of %d: %w", i+1, len(sources), err)
229237
}
230238
}
231239

@@ -256,13 +264,13 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
256264
ApplicationMetadata: &app.ObjectMeta,
257265
})
258266
if err != nil {
259-
return nil, nil, fmt.Errorf("failed to generate manifest for source %d of %d: %w", i+1, len(sources), err)
267+
return nil, nil, nil, fmt.Errorf("failed to generate manifest for source %d of %d: %w", i+1, len(sources), err)
260268
}
261269

262270
targetObj, err := unmarshalManifests(manifestInfo.GetCompiledManifests())
263271

264272
if err != nil {
265-
return nil, nil, fmt.Errorf("failed to unmarshal manifests for source %d of %d: %w", i+1, len(sources), err)
273+
return nil, nil, nil, fmt.Errorf("failed to unmarshal manifests for source %d of %d: %w", i+1, len(sources), err)
266274
}
267275
targetObjs = append(targetObjs, targetObj...)
268276

@@ -276,7 +284,7 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
276284
}
277285
logCtx = logCtx.WithField("time_ms", time.Since(ts.StartTime).Milliseconds())
278286
logCtx.Info("GetRepoObjs stats")
279-
return targetObjs, manifestInfos, nil
287+
return targetObjs, manifestInfos, manifestsChanges, nil
280288
}
281289

282290
func unmarshalManifests(manifests []string) ([]*unstructured.Unstructured, error) {
@@ -444,6 +452,8 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
444452
var manifestInfos []*apiclient.ManifestResponse
445453
targetNsExists := false
446454

455+
var manifestChanged map[string]bool
456+
447457
if len(localManifests) == 0 {
448458
// If the length of revisions is not same as the length of sources,
449459
// we take the revisions from the sources directly for all the sources.
@@ -454,7 +464,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
454464
}
455465
}
456466

457-
targetObjs, manifestInfos, err = m.GetRepoObjs(app, sources, appLabelKey, revisions, noCache, noRevisionCache, verifySignature, project)
467+
targetObjs, manifestInfos, manifestChanged, err = m.GetRepoObjs(app, sources, appLabelKey, revisions, noCache, noRevisionCache, verifySignature, project)
458468
if err != nil {
459469
targetObjs = make([]*unstructured.Unstructured, 0)
460470
msg := fmt.Sprintf("Failed to load target state: %s", err.Error())
@@ -828,8 +838,9 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
828838
Sources: sources,
829839
IgnoreDifferences: app.Spec.IgnoreDifferences,
830840
},
831-
Status: syncCode,
832-
Revisions: manifestRevisions,
841+
Status: syncCode,
842+
Revisions: manifestRevisions,
843+
ManifestsChanged: manifestChanged,
833844
}
834845
} else {
835846
syncStatus = v1alpha1.SyncStatus{
@@ -838,8 +849,9 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
838849
Source: app.Spec.GetSource(),
839850
IgnoreDifferences: app.Spec.IgnoreDifferences,
840851
},
841-
Status: syncCode,
842-
Revision: revision,
852+
Status: syncCode,
853+
Revision: revision,
854+
ManifestsChanged: manifestChanged,
843855
}
844856
}
845857

manifests/core-install.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5036,6 +5036,13 @@ spec:
50365036
required:
50375037
- destination
50385038
type: object
5039+
manifestsChanged:
5040+
additionalProperties:
5041+
type: boolean
5042+
description: ManifestsChanged indicates whether the manifests
5043+
have changed base on argocd.argoproj.io/manifest-generate-paths
5044+
annotation
5045+
type: object
50395046
revision:
50405047
description: Revision contains information about the revision
50415048
the comparison has been performed to

manifests/crds/application-crd.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5035,6 +5035,13 @@ spec:
50355035
required:
50365036
- destination
50375037
type: object
5038+
manifestsChanged:
5039+
additionalProperties:
5040+
type: boolean
5041+
description: ManifestsChanged indicates whether the manifests
5042+
have changed base on argocd.argoproj.io/manifest-generate-paths
5043+
annotation
5044+
type: object
50385045
revision:
50395046
description: Revision contains information about the revision
50405047
the comparison has been performed to

manifests/ha/install.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5036,6 +5036,13 @@ spec:
50365036
required:
50375037
- destination
50385038
type: object
5039+
manifestsChanged:
5040+
additionalProperties:
5041+
type: boolean
5042+
description: ManifestsChanged indicates whether the manifests
5043+
have changed base on argocd.argoproj.io/manifest-generate-paths
5044+
annotation
5045+
type: object
50395046
revision:
50405047
description: Revision contains information about the revision
50415048
the comparison has been performed to

manifests/install.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5036,6 +5036,13 @@ spec:
50365036
required:
50375037
- destination
50385038
type: object
5039+
manifestsChanged:
5040+
additionalProperties:
5041+
type: boolean
5042+
description: ManifestsChanged indicates whether the manifests
5043+
have changed base on argocd.argoproj.io/manifest-generate-paths
5044+
annotation
5045+
type: object
50395046
revision:
50405047
description: Revision contains information about the revision
50415048
the comparison has been performed to

0 commit comments

Comments
 (0)