Feat: support custom cascading gc policy (#6059)

This commit is contained in:
Somefive 2023-06-01 10:12:10 +08:00 committed by GitHub
parent e215b18a3e
commit 1a6dafafde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 115 additions and 9 deletions

View File

@ -80,12 +80,6 @@ jobs:
go install github.com/onsi/ginkgo/v2/ginkgo go install github.com/onsi/ginkgo/v2/ginkgo
go get github.com/onsi/gomega/... go get github.com/onsi/gomega/...
- name: Setup KinD
run: |
go install sigs.k8s.io/kind@v0.19.0
kind delete cluster --name kind || true
kind create cluster --name kind --image=kindest/node:v1.26.4
- name: Load image - name: Load image
run: | run: |
mkdir -p $HOME/tmp/ mkdir -p $HOME/tmp/

View File

@ -17,7 +17,9 @@ limitations under the License.
package v1alpha1 package v1alpha1
import ( import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/controller-runtime/pkg/client"
) )
const ( const (
@ -58,6 +60,7 @@ const (
type GarbageCollectPolicyRule struct { type GarbageCollectPolicyRule struct {
Selector ResourcePolicyRuleSelector `json:"selector"` Selector ResourcePolicyRuleSelector `json:"selector"`
Strategy GarbageCollectStrategy `json:"strategy"` Strategy GarbageCollectStrategy `json:"strategy"`
Propagation *GarbageCollectPropagation `json:"propagation"`
} }
// GarbageCollectStrategy the strategy for target resource to recycle // GarbageCollectStrategy the strategy for target resource to recycle
@ -73,6 +76,16 @@ const (
GarbageCollectStrategyOnAppUpdate GarbageCollectStrategy = "onAppUpdate" GarbageCollectStrategyOnAppUpdate GarbageCollectStrategy = "onAppUpdate"
) )
// GarbageCollectPropagation the deletion propagation setting similar to metav1.DeletionPropagation
type GarbageCollectPropagation string
const (
// GarbageCollectPropagationOrphan orphan child resources while deleting target resources
GarbageCollectPropagationOrphan = "orphan"
// GarbageCollectPropagationCascading delete child resources in background while deleting target resources
GarbageCollectPropagationCascading = "cascading"
)
// Type the type name of the policy // Type the type name of the policy
func (in *GarbageCollectPolicySpec) Type() string { func (in *GarbageCollectPolicySpec) Type() string {
return GarbageCollectPolicyType return GarbageCollectPolicyType
@ -87,3 +100,18 @@ func (in *GarbageCollectPolicySpec) FindStrategy(manifest *unstructured.Unstruct
} }
return nil return nil
} }
// FindDeleteOption find delete option for target resource
func (in *GarbageCollectPolicySpec) FindDeleteOption(manifest *unstructured.Unstructured) []client.DeleteOption {
for _, rule := range in.Rules {
if rule.Selector.Match(manifest) && rule.Propagation != nil {
switch *rule.Propagation {
case GarbageCollectPropagationOrphan:
return []client.DeleteOption{client.PropagationPolicy(metav1.DeletePropagationOrphan)}
case GarbageCollectPropagationCascading:
return []client.DeleteOption{client.PropagationPolicy(metav1.DeletePropagationBackground)}
}
}
}
return nil
}

View File

@ -314,6 +314,11 @@ func (in *EnvTraitPatch) DeepCopy() *EnvTraitPatch {
func (in *GarbageCollectPolicyRule) DeepCopyInto(out *GarbageCollectPolicyRule) { func (in *GarbageCollectPolicyRule) DeepCopyInto(out *GarbageCollectPolicyRule) {
*out = *in *out = *in
in.Selector.DeepCopyInto(&out.Selector) in.Selector.DeepCopyInto(&out.Selector)
if in.Propagation != nil {
in, out := &in.Propagation, &out.Propagation
*out = new(GarbageCollectPropagation)
**out = **in
}
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GarbageCollectPolicyRule. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GarbageCollectPolicyRule.

View File

@ -16,6 +16,8 @@ spec:
selector: #ResourcePolicyRuleSelector selector: #ResourcePolicyRuleSelector
// +usage=Specify the strategy for target resource to recycle // +usage=Specify the strategy for target resource to recycle
strategy: *"onAppUpdate" | "onAppDelete" | "never" strategy: *"onAppUpdate" | "onAppDelete" | "never"
// +usage=Specify the deletion propagation strategy for target resource to delete
propagation?: "orphan" | "cascading"
} }
#ResourcePolicyRuleSelector: { #ResourcePolicyRuleSelector: {

View File

@ -43,6 +43,7 @@ import (
"github.com/oam-dev/kubevela/pkg/multicluster" "github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/oam" "github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/util" "github.com/oam-dev/kubevela/pkg/oam/util"
"github.com/oam-dev/kubevela/pkg/policy"
"github.com/oam-dev/kubevela/pkg/resourcetracker" "github.com/oam-dev/kubevela/pkg/resourcetracker"
"github.com/oam-dev/kubevela/pkg/utils" "github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/apply" "github.com/oam-dev/kubevela/pkg/utils/apply"
@ -405,7 +406,11 @@ func DeleteManagedResourceInApplication(ctx context.Context, cli client.Client,
} }
return errors.Wrapf(cli.Update(_ctx, obj), "failed to remove owner labels for resource while skipping gc") return errors.Wrapf(cli.Update(_ctx, obj), "failed to remove owner labels for resource while skipping gc")
} }
if err := cli.Delete(_ctx, obj); err != nil && !kerrors.IsNotFound(err) { var opts []client.DeleteOption
if garbageCollectPolicy, _ := policy.ParsePolicy[v1alpha1.GarbageCollectPolicySpec](app); garbageCollectPolicy != nil {
opts = garbageCollectPolicy.FindDeleteOption(obj)
}
if err := cli.Delete(_ctx, obj, opts...); err != nil && !kerrors.IsNotFound(err) {
return errors.Wrapf(err, "failed to delete resource %s", mr.ResourceKey()) return errors.Wrapf(err, "failed to delete resource %s", mr.ResourceKey())
} }
return nil return nil

View File

@ -1304,5 +1304,37 @@ var _ = Describe("Test multicluster scenario", func() {
Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: "fake-app"}, _fapp)).Should(Succeed()) Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: "fake-app"}, _fapp)).Should(Succeed())
Expect(string(_fapp.Status.Phase)).Should(Equal("unknown")) Expect(string(_fapp.Status.Phase)).Should(Equal("unknown"))
}) })
It("Test application with garbage-collect propagation setting", func() {
ctx := context.Background()
app := &v1beta1.Application{}
bs, err := os.ReadFile("./testdata/app/app-with-custom-gc-propagation.yaml")
Expect(err).Should(Succeed())
Expect(yaml.Unmarshal(bs, app)).Should(Succeed())
app.SetNamespace(namespace)
Eventually(func(g Gomega) {
g.Expect(k8sClient.Create(ctx, app)).Should(Succeed())
}).WithPolling(2 * time.Second).WithTimeout(5 * time.Second).Should(Succeed())
appKey := client.ObjectKeyFromObject(app)
Eventually(func(g Gomega) {
_app := &v1beta1.Application{}
g.Expect(k8sClient.Get(ctx, appKey, _app)).Should(Succeed())
g.Expect(_app.Status.Phase).Should(Equal(common.ApplicationRunning))
}).WithPolling(2 * time.Second).WithTimeout(20 * time.Second).Should(Succeed())
By("Deleting")
_app := &v1beta1.Application{}
Expect(k8sClient.Get(ctx, appKey, _app)).Should(Succeed())
Expect(k8sClient.Delete(ctx, _app)).Should(Succeed())
Eventually(func(g Gomega) {
_app := &v1beta1.Application{}
g.Expect(kerrors.IsNotFound(k8sClient.Get(ctx, appKey, _app))).Should(BeTrue())
}).WithPolling(2 * time.Second).WithTimeout(20 * time.Second).Should(Succeed())
Eventually(func(g Gomega) {
pods := &corev1.PodList{}
g.Expect(k8sClient.List(ctx, pods, client.InNamespace(namespace))).Should(Succeed())
g.Expect(len(pods.Items)).Should(Equal(1))
g.Expect(pods.Items[0].Name).Should(ContainSubstring("orphan"))
}).WithPolling(2 * time.Second).WithTimeout(20 * time.Second).Should(Succeed())
})
}) })
}) })

View File

@ -0,0 +1,38 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: gc-propagation
spec:
components:
- type: webservice
name: orphan-gc
properties:
image: busybox
cmd:
- sleep
- '1000000'
- type: k8s-objects
name: cascading-gc
properties:
objects:
- apiVersion: batch/v1
kind: Job
spec:
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
policies:
- type: garbage-collect
properties:
rules:
- selector:
componentNames: ["orphan-gc"]
propagation: orphan
- selector:
componentNames: ["cascading-gc"]
propagation: cascading

View File

@ -12,6 +12,8 @@ template: {
selector: #ResourcePolicyRuleSelector selector: #ResourcePolicyRuleSelector
// +usage=Specify the strategy for target resource to recycle // +usage=Specify the strategy for target resource to recycle
strategy: *"onAppUpdate" | "onAppDelete" | "never" strategy: *"onAppUpdate" | "onAppDelete" | "never"
// +usage=Specify the deletion propagation strategy for target resource to delete
propagation?: "orphan" | "cascading"
} }
#ResourcePolicyRuleSelector: { #ResourcePolicyRuleSelector: {