Skip to content

Commit 1dc85e5

Browse files
agaudreaultreggie-kgithub-actions[bot]dependabot[bot]renovate[bot]
authored
fix(engine): always preserve sync status for hooks (#25692)
Signed-off-by: reggie-k <[email protected]> Signed-off-by: Alexandre Gaudreault <[email protected]> Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Signed-off-by: dependabot[bot] <[email protected]> Signed-off-by: Afzal Ansari <[email protected]> Signed-off-by: Julie Vogelman <[email protected]> Signed-off-by: Michael Crenshaw <[email protected]> Co-authored-by: Regina Voloshin <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: reggie-k <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Afzal Ansari <[email protected]> Co-authored-by: Blake Pettersson <[email protected]> Co-authored-by: Julie Vogelman <[email protected]> Co-authored-by: Michael Crenshaw <[email protected]>
1 parent 0114636 commit 1dc85e5

File tree

5 files changed

+43
-43
lines changed

5 files changed

+43
-43
lines changed

gitops-engine/pkg/sync/sync_context.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ func (sc *syncContext) Sync() {
457457
// No need to perform a dry-run on the namespace creation, because if it fails we stop anyway
458458
sc.log.WithValues("task", nsCreateTask).Info("Creating namespace")
459459
if sc.runTasks(nsSyncTasks, false) == failed {
460-
sc.setOperationFailed(syncTasks{}, nsSyncTasks, "the namespace failed to apply")
460+
sc.executeSyncFailPhase(syncTasks{}, nsSyncTasks, "the namespace failed to apply")
461461
return
462462
}
463463

@@ -485,9 +485,9 @@ func (sc *syncContext) Sync() {
485485
// update the hook's result
486486
operationState, message, err := sc.getOperationPhase(task.liveObj)
487487
if err != nil {
488-
sc.setResourceResult(task, "", common.OperationError, fmt.Sprintf("failed to get resource health: %v", err))
488+
sc.setResourceResult(task, task.syncStatus, common.OperationError, fmt.Sprintf("failed to get resource health: %v", err))
489489
} else {
490-
sc.setResourceResult(task, "", operationState, message)
490+
sc.setResourceResult(task, task.syncStatus, operationState, message)
491491
}
492492
} else {
493493
// this must be calculated on the live object
@@ -557,7 +557,7 @@ func (sc *syncContext) Sync() {
557557
// if there are any completed but unsuccessful tasks, sync is a failure.
558558
if tasks.Any(func(t *syncTask) bool { return t.completed() && !t.successful() }) {
559559
sc.deleteHooks(hooksPendingDeletionFailed)
560-
sc.setOperationFailed(syncFailTasks, syncFailedTasks, "one or more synchronization tasks completed unsuccessfully")
560+
sc.executeSyncFailPhase(syncFailTasks, syncFailedTasks, "one or more synchronization tasks completed unsuccessfully")
561561
return
562562
}
563563

@@ -610,7 +610,7 @@ func (sc *syncContext) Sync() {
610610
case failed:
611611
syncFailedTasks, _ := tasks.Split(func(t *syncTask) bool { return t.syncStatus == common.ResultCodeSyncFailed })
612612
sc.deleteHooks(hooksPendingDeletionFailed)
613-
sc.setOperationFailed(syncFailTasks, syncFailedTasks, "one or more objects failed to apply")
613+
sc.executeSyncFailPhase(syncFailTasks, syncFailedTasks, "one or more objects failed to apply")
614614
case successful:
615615
if remainingTasks.Len() == 0 {
616616
// delete all completed hooks which have appropriate delete policy
@@ -731,7 +731,7 @@ func (sc *syncContext) deleteHooks(hooksPendingDeletion syncTasks) {
731731
for _, task := range hooksPendingDeletion {
732732
err := sc.deleteResource(task)
733733
if err != nil && !apierrors.IsNotFound(err) {
734-
sc.setResourceResult(task, "", common.OperationError, fmt.Sprintf("failed to delete resource: %v", err))
734+
sc.setResourceResult(task, task.syncStatus, common.OperationError, fmt.Sprintf("failed to delete resource: %v", err))
735735
}
736736
}
737737
}
@@ -747,7 +747,7 @@ func (sc *syncContext) GetState() (common.OperationPhase, string, []common.Resou
747747
return sc.phase, sc.message, resourceRes
748748
}
749749

750-
func (sc *syncContext) setOperationFailed(syncFailTasks, syncFailedTasks syncTasks, message string) {
750+
func (sc *syncContext) executeSyncFailPhase(syncFailTasks, syncFailedTasks syncTasks, message string) {
751751
errorMessageFactory := func(tasks syncTasks, message string) string {
752752
messages := tasks.Map(func(task *syncTask) string {
753753
return task.message
@@ -1323,13 +1323,13 @@ func (sc *syncContext) Terminate() {
13231323
if phase == common.OperationRunning {
13241324
err := sc.deleteResource(task)
13251325
if err != nil && !apierrors.IsNotFound(err) {
1326-
sc.setResourceResult(task, "", common.OperationFailed, fmt.Sprintf("Failed to delete: %v", err))
1326+
sc.setResourceResult(task, task.syncStatus, common.OperationFailed, fmt.Sprintf("Failed to delete: %v", err))
13271327
terminateSuccessful = false
13281328
} else {
1329-
sc.setResourceResult(task, "", common.OperationSucceeded, "Deleted")
1329+
sc.setResourceResult(task, task.syncStatus, common.OperationSucceeded, "Deleted")
13301330
}
13311331
} else {
1332-
sc.setResourceResult(task, "", phase, msg)
1332+
sc.setResourceResult(task, task.syncStatus, phase, msg)
13331333
}
13341334
}
13351335
if terminateSuccessful {

gitops-engine/pkg/sync/sync_context_test.go

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1951,36 +1951,36 @@ func TestSyncContext_GetDeleteOptions_WithPrunePropagationPolicy(t *testing.T) {
19511951
assert.Equal(t, metav1.DeletePropagationBackground, *opts.PropagationPolicy)
19521952
}
19531953

1954-
func TestSetOperationFailed(t *testing.T) {
1954+
func TestExecuteSyncFailPhase(t *testing.T) {
19551955
sc := syncContext{}
19561956
sc.log = textlogger.NewLogger(textlogger.NewConfig()).WithValues("application", "fake-app")
19571957

19581958
tasks := make([]*syncTask, 0)
19591959
tasks = append(tasks, &syncTask{message: "namespace not found"})
19601960

1961-
sc.setOperationFailed(nil, tasks, "one or more objects failed to apply")
1961+
sc.executeSyncFailPhase(nil, tasks, "one or more objects failed to apply")
19621962

19631963
assert.Equal(t, "one or more objects failed to apply, reason: namespace not found", sc.message)
19641964
}
19651965

1966-
func TestSetOperationFailedDuplicatedMessages(t *testing.T) {
1966+
func TestExecuteSyncFailPhase_DuplicatedMessages(t *testing.T) {
19671967
sc := syncContext{}
19681968
sc.log = textlogger.NewLogger(textlogger.NewConfig()).WithValues("application", "fake-app")
19691969

19701970
tasks := make([]*syncTask, 0)
19711971
tasks = append(tasks, &syncTask{message: "namespace not found"})
19721972
tasks = append(tasks, &syncTask{message: "namespace not found"})
19731973

1974-
sc.setOperationFailed(nil, tasks, "one or more objects failed to apply")
1974+
sc.executeSyncFailPhase(nil, tasks, "one or more objects failed to apply")
19751975

19761976
assert.Equal(t, "one or more objects failed to apply, reason: namespace not found", sc.message)
19771977
}
19781978

1979-
func TestSetOperationFailedNoTasks(t *testing.T) {
1979+
func TestExecuteSyncFailPhase_NoTasks(t *testing.T) {
19801980
sc := syncContext{}
19811981
sc.log = textlogger.NewLogger(textlogger.NewConfig()).WithValues("application", "fake-app")
19821982

1983-
sc.setOperationFailed(nil, nil, "one or more objects failed to apply")
1983+
sc.executeSyncFailPhase(nil, nil, "one or more objects failed to apply")
19841984

19851985
assert.Equal(t, "one or more objects failed to apply", sc.message)
19861986
}
@@ -2223,15 +2223,15 @@ func TestWaitForCleanUpBeforeNextWave(t *testing.T) {
22232223

22242224
var phase synccommon.OperationPhase
22252225
var msg string
2226-
var result []synccommon.ResourceSyncResult
2226+
var results []synccommon.ResourceSyncResult
22272227

22282228
// 1st sync should prune only pod3
22292229
syncCtx.Sync()
2230-
phase, _, result = syncCtx.GetState()
2230+
phase, _, results = syncCtx.GetState()
22312231
assert.Equal(t, synccommon.OperationRunning, phase)
2232-
assert.Len(t, result, 1)
2233-
assert.Equal(t, "pod-3", result[0].ResourceKey.Name)
2234-
assert.Equal(t, synccommon.ResultCodePruned, result[0].Status)
2232+
assert.Len(t, results, 1)
2233+
assert.Equal(t, "pod-3", results[0].ResourceKey.Name)
2234+
assert.Equal(t, synccommon.ResultCodePruned, results[0].Status)
22352235

22362236
// simulate successful delete of pod3
22372237
syncCtx.resources = groupResources(ReconciliationResult{
@@ -2241,22 +2241,22 @@ func TestWaitForCleanUpBeforeNextWave(t *testing.T) {
22412241

22422242
// next sync should prune only pod2
22432243
syncCtx.Sync()
2244-
phase, _, result = syncCtx.GetState()
2244+
phase, _, results = syncCtx.GetState()
22452245
assert.Equal(t, synccommon.OperationRunning, phase)
2246-
assert.Len(t, result, 2)
2247-
assert.Equal(t, "pod-2", result[1].ResourceKey.Name)
2248-
assert.Equal(t, synccommon.ResultCodePruned, result[1].Status)
2246+
assert.Len(t, results, 2)
2247+
assert.Equal(t, "pod-2", results[1].ResourceKey.Name)
2248+
assert.Equal(t, synccommon.ResultCodePruned, results[1].Status)
22492249

22502250
// add delete timestamp on pod2 to simulate pending delete
22512251
pod2.SetDeletionTimestamp(&metav1.Time{Time: time.Now()})
22522252

22532253
// next sync should wait for deletion of pod2 from cluster,
22542254
// it should not move to next wave and prune pod1
22552255
syncCtx.Sync()
2256-
phase, msg, result = syncCtx.GetState()
2256+
phase, msg, results = syncCtx.GetState()
22572257
assert.Equal(t, synccommon.OperationRunning, phase)
22582258
assert.Equal(t, "waiting for deletion of /Pod/pod-2", msg)
2259-
assert.Len(t, result, 2)
2259+
assert.Len(t, results, 2)
22602260

22612261
// simulate successful delete of pod2
22622262
syncCtx.resources = groupResources(ReconciliationResult{
@@ -2267,15 +2267,15 @@ func TestWaitForCleanUpBeforeNextWave(t *testing.T) {
22672267
// next sync should proceed with next wave
22682268
// i.e deletion of pod1
22692269
syncCtx.Sync()
2270-
phase, _, result = syncCtx.GetState()
2270+
phase, _, results = syncCtx.GetState()
22712271
assert.Equal(t, synccommon.OperationSucceeded, phase)
2272-
assert.Len(t, result, 3)
2273-
assert.Equal(t, "pod-3", result[0].ResourceKey.Name)
2274-
assert.Equal(t, "pod-2", result[1].ResourceKey.Name)
2275-
assert.Equal(t, "pod-1", result[2].ResourceKey.Name)
2276-
assert.Equal(t, synccommon.ResultCodePruned, result[0].Status)
2277-
assert.Equal(t, synccommon.ResultCodePruned, result[1].Status)
2278-
assert.Equal(t, synccommon.ResultCodePruned, result[2].Status)
2272+
assert.Len(t, results, 3)
2273+
assert.Equal(t, "pod-3", results[0].ResourceKey.Name)
2274+
assert.Equal(t, "pod-2", results[1].ResourceKey.Name)
2275+
assert.Equal(t, "pod-1", results[2].ResourceKey.Name)
2276+
assert.Equal(t, synccommon.ResultCodePruned, results[0].Status)
2277+
assert.Equal(t, synccommon.ResultCodePruned, results[1].Status)
2278+
assert.Equal(t, synccommon.ResultCodePruned, results[2].Status)
22792279
}
22802280

22812281
func BenchmarkSync(b *testing.B) {

test/e2e/cli_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func TestCliAppCommand(t *testing.T) {
4444
require.NoError(t, err)
4545
vars := map[string]any{"Name": ctx.AppName(), "Namespace": DeploymentNamespace()}
4646
assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} pod Synced Progressing pod/pod created`, vars))
47-
assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} hook Succeeded Sync pod/hook created`, vars))
47+
assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} hook Succeeded Synced Sync pod/hook created`, vars))
4848
}).
4949
Then().
5050
Expect(OperationPhaseIs(OperationSucceeded)).
@@ -88,7 +88,7 @@ func TestNormalArgoCDCommandsExecuteOverPluginsWithSameName(t *testing.T) {
8888

8989
vars := map[string]any{"Name": ctx.AppName(), "Namespace": DeploymentNamespace()}
9090
assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} pod Synced Progressing pod/pod created`, vars))
91-
assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} hook Succeeded Sync pod/hook created`, vars))
91+
assert.Contains(t, NormalizeOutput(output), Tmpl(t, `Pod {{.Namespace}} hook Succeeded Synced Sync pod/hook created`, vars))
9292
}).
9393
Then().
9494
Expect(OperationPhaseIs(OperationSucceeded)).

test/e2e/helm_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func TestHelmHooksAreCreated(t *testing.T) {
3131
Expect(OperationPhaseIs(OperationSucceeded)).
3232
Expect(HealthIs(health.HealthStatusHealthy)).
3333
Expect(SyncStatusIs(SyncStatusCodeSynced)).
34-
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: fixture.DeploymentNamespace(), Name: "hook", Message: "pod/hook created", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, HookType: HookTypePreSync, HookPhase: OperationSucceeded, SyncPhase: SyncPhasePreSync}))
34+
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: fixture.DeploymentNamespace(), Name: "hook", Message: "pod/hook created", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, HookType: HookTypePreSync, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhasePreSync}))
3535
}
3636

3737
// make sure we treat Helm weights as a sync wave

test/e2e/hook_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func testHookSuccessful(t *testing.T, hookType HookType) {
4949
Expect(ResourceSyncStatusIs("Pod", "pod", SyncStatusCodeSynced)).
5050
Expect(ResourceHealthIs("Pod", "pod", health.HealthStatusHealthy)).
5151
Expect(ResourceResultNumbering(2)).
52-
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Name: "hook", Message: "pod/hook created", HookType: hookType, HookPhase: OperationSucceeded, SyncPhase: SyncPhase(hookType)}))
52+
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Name: "hook", Message: "pod/hook created", HookType: hookType, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhase(hookType)}))
5353
}
5454

5555
func TestPreDeleteHook(t *testing.T) {
@@ -246,7 +246,7 @@ spec:
246246
CreateApp().
247247
Sync().
248248
Then().
249-
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Name: "sync-fail-hook", Message: "pod/sync-fail-hook created", HookType: HookTypeSyncFail, HookPhase: OperationSucceeded, SyncPhase: SyncPhaseSyncFail})).
249+
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Name: "sync-fail-hook", Message: "pod/sync-fail-hook created", HookType: HookTypeSyncFail, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhaseSyncFail})).
250250
Expect(OperationPhaseIs(OperationFailed))
251251
}
252252

@@ -293,8 +293,8 @@ spec:
293293
CreateApp().
294294
Sync().
295295
Then().
296-
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Name: "successful-sync-fail-hook", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Message: "pod/successful-sync-fail-hook created", HookType: HookTypeSyncFail, HookPhase: OperationSucceeded, SyncPhase: SyncPhaseSyncFail})).
297-
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Name: "failed-sync-fail-hook", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Message: `container "main" failed with exit code 1`, HookType: HookTypeSyncFail, HookPhase: OperationFailed, SyncPhase: SyncPhaseSyncFail})).
296+
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Name: "successful-sync-fail-hook", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Message: "pod/successful-sync-fail-hook created", HookType: HookTypeSyncFail, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhaseSyncFail})).
297+
Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Name: "failed-sync-fail-hook", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Message: `container "main" failed with exit code 1`, HookType: HookTypeSyncFail, Status: ResultCodeSynced, HookPhase: OperationFailed, SyncPhase: SyncPhaseSyncFail})).
298298
Expect(OperationPhaseIs(OperationFailed))
299299
}
300300

@@ -522,5 +522,5 @@ func testHookFinalizer(t *testing.T, hookType HookType) {
522522
Expect(ResourceSyncStatusIs("Pod", "pod", SyncStatusCodeSynced)).
523523
Expect(ResourceHealthIs("Pod", "pod", health.HealthStatusHealthy)).
524524
Expect(ResourceResultNumbering(2)).
525-
Expect(ResourceResultIs(ResourceResult{Group: "batch", Version: "v1", Kind: "Job", Namespace: DeploymentNamespace(), Name: "hook", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Message: "Resource has finalizer", HookType: hookType, HookPhase: OperationSucceeded, SyncPhase: SyncPhase(hookType)}))
525+
Expect(ResourceResultIs(ResourceResult{Group: "batch", Version: "v1", Kind: "Job", Namespace: DeploymentNamespace(), Name: "hook", Images: []string{"quay.io/argoprojlabs/argocd-e2e-container:0.1"}, Message: "Resource has finalizer", HookType: hookType, Status: ResultCodeSynced, HookPhase: OperationSucceeded, SyncPhase: SyncPhase(hookType)}))
526526
}

0 commit comments

Comments
 (0)