From 6dcba5ef110349ea8ef004ff215bb0f621b70f25 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Jan 2023 15:55:05 +0800 Subject: [PATCH] [Backport release-1.7] Fix: conflict while using gc policy and shared-resource policy concurrently (#5333) * Fix: conflict while using gc policy and shared-resource policy concurrently Signed-off-by: Somefive (cherry picked from commit f8239be21e41c9eb00de033dbcbcfa4416b872a7) * Fix: github ci Signed-off-by: Somefive (cherry picked from commit 72e54e5f9052a2cb17d2827b9b610a70a6431a59) Co-authored-by: Somefive --- .github/workflows/apiserver-test.yml | 2 + .github/workflows/unit-test.yml | 2 + .../defwithtemplate/k8s-update-strategy.yaml | 77 +++++++++++++++++++ pkg/resourcekeeper/gc.go | 1 + .../multicluster_test.go | 21 +++++ .../testdata/app/app-gc-shared.yaml | 26 +++++++ 6 files changed, 129 insertions(+) create mode 100644 charts/vela-minimal/templates/defwithtemplate/k8s-update-strategy.yaml create mode 100644 test/e2e-multicluster-test/testdata/app/app-gc-shared.yaml diff --git a/.github/workflows/apiserver-test.yml b/.github/workflows/apiserver-test.yml index 8a38fa0c7..383cb5c0b 100644 --- a/.github/workflows/apiserver-test.yml +++ b/.github/workflows/apiserver-test.yml @@ -64,6 +64,8 @@ jobs: - name: Install ginkgo run: | + sudo sed -i 's/azure\.//' /etc/apt/sources.list + sudo apt-get update sudo apt-get install -y golang-ginkgo-dev - name: Start MongoDB diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index e0535a8df..a7965d8cb 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -61,6 +61,8 @@ jobs: - name: Install ginkgo run: | + sudo sed -i 's/azure\.//' /etc/apt/sources.list + sudo apt-get update sudo apt-get install -y golang-ginkgo-dev - name: Setup K3d diff --git a/charts/vela-minimal/templates/defwithtemplate/k8s-update-strategy.yaml b/charts/vela-minimal/templates/defwithtemplate/k8s-update-strategy.yaml new file mode 100644 index 000000000..3558e9b01 --- /dev/null +++ b/charts/vela-minimal/templates/defwithtemplate/k8s-update-strategy.yaml @@ -0,0 +1,77 @@ +# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file. +# Definition source cue file: vela-templates/definitions/internal/k8s-update-strategy.cue +apiVersion: core.oam.dev/v1beta1 +kind: TraitDefinition +metadata: + annotations: + definition.oam.dev/alias: "" + definition.oam.dev/description: Set k8s update strategy for Deployment/DaemonSet/StatefulSet + name: k8s-update-strategy + namespace: {{ include "systemDefinitionNamespace" . }} +spec: + appliesToWorkloads: + - deployments.apps + - statefulsets.apps + - daemonsets.apps + conflictsWith: [] + podDisruptive: false + schematic: + cue: + template: | + patch: spec: { + if parameter.targetKind == "Deployment" && parameter.strategy.type != "OnDelete" { + // +patchStrategy=retainKeys + strategy: { + type: parameter.strategy.type + if parameter.strategy.type == "RollingUpdate" { + rollingUpdate: { + maxSurge: parameter.strategy.rollingStrategy.maxSurge + maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable + } + } + } + } + + if parameter.targetKind == "StatefulSet" && parameter.strategy.type != "Recreate" { + // +patchStrategy=retainKeys + updateStrategy: { + type: parameter.strategy.type + if parameter.strategy.type == "RollingUpdate" { + rollingUpdate: partition: parameter.strategy.rollingStrategy.partition + } + } + } + + if parameter.targetKind == "DaemonSet" && parameter.strategy.type != "Recreate" { + // +patchStrategy=retainKeys + updateStrategy: { + type: parameter.strategy.type + if parameter.strategy.type == "RollingUpdate" { + rollingUpdate: { + maxSurge: parameter.strategy.rollingStrategy.maxSurge + maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable + } + } + } + } + + } + parameter: { + // +usage=Specify the apiVersion of target + targetAPIVersion: *"apps/v1" | string + // +usage=Specify the kind of target + targetKind: *"Deployment" | "StatefulSet" | "DaemonSet" + // +usage=Specify the strategy of update + strategy: { + // +usage=Specify the strategy type + type: *"RollingUpdate" | "Recreate" | "OnDelete" + // +usage=Specify the parameters of rollong update strategy + rollingStrategy?: { + maxSurge: *"25%" | string + maxUnavailable: *"25%" | string + partition: *0 | int + } + } + } + workloadRefPath: "" + diff --git a/pkg/resourcekeeper/gc.go b/pkg/resourcekeeper/gc.go index 5b8808f85..947dabe67 100644 --- a/pkg/resourcekeeper/gc.go +++ b/pkg/resourcekeeper/gc.go @@ -371,6 +371,7 @@ func DeleteManagedResourceInApplication(ctx context.Context, cli client.Client, } return nil } + util.RemoveAnnotations(obj, []string{oam.AnnotationAppSharedBy}) } if mr.SkipGC || hasOrphanFinalizer(app) { if labels := obj.GetLabels(); labels != nil { diff --git a/test/e2e-multicluster-test/multicluster_test.go b/test/e2e-multicluster-test/multicluster_test.go index 4cefaaa08..c9d83f76a 100644 --- a/test/e2e-multicluster-test/multicluster_test.go +++ b/test/e2e-multicluster-test/multicluster_test.go @@ -912,5 +912,26 @@ var _ = Describe("Test multicluster scenario", func() { g.Expect(cnt).Should(Equal(1)) }).WithTimeout(30 * time.Second).WithPolling(2 * time.Second).Should(Succeed()) }) + + It("Test application with gc policy and shared-resource policy", func() { + app := &v1beta1.Application{} + bs, err := os.ReadFile("./testdata/app/app-gc-shared.yaml") + Expect(err).Should(Succeed()) + Expect(yaml.Unmarshal(bs, app)).Should(Succeed()) + app.SetNamespace(namespace) + Expect(k8sClient.Create(hubCtx, app)).Should(Succeed()) + appKey := client.ObjectKeyFromObject(app) + Eventually(func(g Gomega) { + g.Expect(k8sClient.Get(hubCtx, appKey, app)).Should(Succeed()) + g.Expect(app.Status.Phase).Should(Equal(common.ApplicationRunning)) + g.Expect(k8sClient.Get(hubCtx, appKey, &corev1.ConfigMap{})).Should(Succeed()) + }).WithTimeout(10 * time.Second).Should(Succeed()) + Expect(k8sClient.Get(hubCtx, appKey, app)).Should(Succeed()) + Expect(k8sClient.Delete(hubCtx, app)).Should(Succeed()) + Eventually(func(g Gomega) { + g.Expect(kerrors.IsNotFound(k8sClient.Get(hubCtx, appKey, app))).Should(BeTrue()) + g.Expect(k8sClient.Get(hubCtx, appKey, &corev1.ConfigMap{})).Should(Succeed()) + }).WithTimeout(10 * time.Second).Should(Succeed()) + }) }) }) diff --git a/test/e2e-multicluster-test/testdata/app/app-gc-shared.yaml b/test/e2e-multicluster-test/testdata/app/app-gc-shared.yaml new file mode 100644 index 000000000..700b73c76 --- /dev/null +++ b/test/e2e-multicluster-test/testdata/app/app-gc-shared.yaml @@ -0,0 +1,26 @@ +apiVersion: core.oam.dev/v1beta1 +kind: Application +metadata: + name: app-gc-shared +spec: + components: + - type: k8s-objects + name: app-gc-shared + properties: + objects: + - apiVersion: v1 + kind: ConfigMap + policies: + - name: gc-policy + type: garbage-collect + properties: + rules: + - selector: + resourceTypes: ["ConfigMap"] + strategy: never + - name: shared-policy + type: shared-resource + properties: + rules: + - selector: + resourceTypes: ["ConfigMap"] \ No newline at end of file