From 40af3704cc97e72eaf22dde2c58e6769db853001 Mon Sep 17 00:00:00 2001 From: Somefive Date: Tue, 11 Oct 2022 20:03:36 +0800 Subject: [PATCH] Fix: prevent rerun application while upgrading due to old apprev lack app workflow Signed-off-by: Somefive --- .../v1alpha2/application/revision.go | 23 ++++++++++++++++++- .../v1alpha2/application/revision_test.go | 21 +++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/pkg/controller/core.oam.dev/v1alpha2/application/revision.go b/pkg/controller/core.oam.dev/v1alpha2/application/revision.go index 3d772110d82..016e051e7ea 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" @@ -535,6 +537,25 @@ func deepEqualWorkflow(old, new workflowv1alpha1.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 @@ -552,7 +573,7 @@ func deepEqualAppInRevision(old, new *v1beta1.ApplicationRevision) bool { return false } } - return apiequality.Semantic.DeepEqual(old.Spec.Application.Spec, new.Spec.Application.Spec) + 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 5cb4130e090..d21a4e96e50 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" @@ -1085,3 +1088,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)) +}