From c15d0e4e0fe71f4e9b47f8e6f05e9a4cebc431de Mon Sep 17 00:00:00 2001 From: Somefive Date: Fri, 14 Oct 2022 22:16:51 +0800 Subject: [PATCH] Fix: prevent rerun application while upgrading due to old apprev lack app workflow (#4865) Signed-off-by: Somefive Signed-off-by: Somefive --- .../v1alpha2/application/revision.go | 24 +++++++++++++++++-- .../v1alpha2/application/revision_test.go | 21 ++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/pkg/controller/core.oam.dev/v1alpha2/application/revision.go b/pkg/controller/core.oam.dev/v1alpha2/application/revision.go index ac988df2a..976e70253 100644 --- a/pkg/controller/core.oam.dev/v1alpha2/application/revision.go +++ b/pkg/controller/core.oam.dev/v1alpha2/application/revision.go @@ -23,6 +23,8 @@ import ( "sort" "strings" + "github.com/hashicorp/go-version" + "github.com/kubevela/pkg/util/k8s" "github.com/pkg/errors" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -522,6 +524,25 @@ func deepEqualWorkflow(old, new v1alpha1.Workflow) bool { return apiequality.Semantic.DeepEqual(old.Steps, new.Steps) } +const velaVersionNumberToCompareWorkflow = "v1.5.7" + +func deepEqualAppSpec(old, new *v1beta1.Application) bool { + oldSpec, newSpec := old.Spec.DeepCopy(), new.Spec.DeepCopy() + // legacy code: KubeVela version before v1.5.7 & v1.6.0-alpha.4 does not + // record workflow in application spec in application revision. The comparison + // need to bypass the equality check of workflow to prevent unintended rerun + curVerNum := k8s.GetAnnotation(old, oam.AnnotationKubeVelaVersion) + publishVersion := k8s.GetAnnotation(old, oam.AnnotationPublishVersion) + if publishVersion == "" && curVerNum != "" { + cmpVer, _ := version.NewVersion(velaVersionNumberToCompareWorkflow) + if curVer, err := version.NewVersion(curVerNum); err == nil && curVer.LessThan(cmpVer) { + oldSpec.Workflow = nil + newSpec.Workflow = nil + } + } + return apiequality.Semantic.DeepEqual(oldSpec, newSpec) +} + func deepEqualAppInRevision(old, new *v1beta1.ApplicationRevision) bool { if len(old.Spec.Policies) != len(new.Spec.Policies) { return false @@ -539,8 +560,7 @@ func deepEqualAppInRevision(old, new *v1beta1.ApplicationRevision) bool { return false } } - return apiequality.Semantic.DeepEqual(filterSkipAffectAppRevTrait(old.Spec.Application.Spec, old.Spec.TraitDefinitions), - filterSkipAffectAppRevTrait(new.Spec.Application.Spec, new.Spec.TraitDefinitions)) + return deepEqualAppSpec(&old.Spec.Application, &new.Spec.Application) } // HandleComponentsRevision manages Component revisions diff --git a/pkg/controller/core.oam.dev/v1alpha2/application/revision_test.go b/pkg/controller/core.oam.dev/v1alpha2/application/revision_test.go index 4ed06d686..a90062c8c 100644 --- a/pkg/controller/core.oam.dev/v1alpha2/application/revision_test.go +++ b/pkg/controller/core.oam.dev/v1alpha2/application/revision_test.go @@ -22,10 +22,13 @@ import ( "fmt" "reflect" "strconv" + "testing" "time" + workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/stretchr/testify/require" "github.com/google/go-cmp/cmp" appsv1 "k8s.io/api/apps/v1" @@ -1171,3 +1174,21 @@ status: {} }()).Should(BeTrue()) }) }) + +func TestDeepEqualAppInRevision(t *testing.T) { + oldRev := &v1beta1.ApplicationRevision{} + newRev := &v1beta1.ApplicationRevision{} + newRev.Spec.Application.Spec.Workflow = &v1beta1.Workflow{ + Steps: []workflowv1alpha1.WorkflowStep{{ + WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ + Type: "deploy", + Name: "deploy", + }, + }}, + } + require.False(t, deepEqualAppInRevision(oldRev, newRev)) + metav1.SetMetaDataAnnotation(&oldRev.Spec.Application.ObjectMeta, oam.AnnotationKubeVelaVersion, "v1.6.0-alpha.5") + require.False(t, deepEqualAppInRevision(oldRev, newRev)) + metav1.SetMetaDataAnnotation(&oldRev.Spec.Application.ObjectMeta, oam.AnnotationKubeVelaVersion, "v1.5.0") + require.True(t, deepEqualAppInRevision(oldRev, newRev)) +}