You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2020/03/25 11:33:37 UTC

[camel-k] branch master updated: Fix #1364: only delete direct children of the integration during gc

This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git


The following commit(s) were added to refs/heads/master by this push:
     new dcb2b27  Fix #1364: only delete direct children of the integration during gc
dcb2b27 is described below

commit dcb2b27f3e2f16fa2b4825759db19072d8520c77
Author: Nicola Ferraro <ni...@gmail.com>
AuthorDate: Tue Mar 24 15:15:37 2020 +0100

    Fix #1364: only delete direct children of the integration during gc
---
 pkg/trait/gc.go | 66 +++++++++++++++++----------------------------------------
 1 file changed, 20 insertions(+), 46 deletions(-)

diff --git a/pkg/trait/gc.go b/pkg/trait/gc.go
index 2c42cc9..5823b13 100644
--- a/pkg/trait/gc.go
+++ b/pkg/trait/gc.go
@@ -22,6 +22,7 @@ import (
 	"path/filepath"
 	"regexp"
 	"strconv"
+	"strings"
 	"sync"
 	"time"
 
@@ -31,7 +32,6 @@ import (
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/selection"
-	"k8s.io/apimachinery/pkg/util/sets"
 	"k8s.io/client-go/discovery"
 	"k8s.io/client-go/discovery/cached/disk"
 	"k8s.io/client-go/discovery/cached/memory"
@@ -135,45 +135,15 @@ func (t *garbageCollectorTrait) garbageCollectResources(e *Environment) {
 		Add(*integration).
 		Add(*generation)
 
-	collectionGVKs, deletableGVKs, err := t.getDeletableTypes(e)
+	deletableGVKs, err := t.getDeletableTypes(e)
 	if err != nil {
 		t.L.ForIntegration(e.Integration).Errorf(err, "cannot discover GVK types")
 		return
 	}
 
-	t.deleteAllOf(collectionGVKs, e, selector)
-	// TODO: DeleteCollection is currently not supported for Service resources, so we have to keep
-	// client-side collection deletion around until it becomes supported.
 	t.deleteEachOf(deletableGVKs, e, selector)
 }
 
-func (t *garbageCollectorTrait) deleteAllOf(gvks map[schema.GroupVersionKind]struct{}, e *Environment, selector labels.Selector) {
-	for gvk := range gvks {
-		err := e.Client.DeleteAllOf(context.TODO(),
-			&unstructured.Unstructured{
-				Object: map[string]interface{}{
-					"apiVersion": gvk.GroupVersion().String(),
-					"kind":       gvk.Kind,
-					"metadata": map[string]interface{}{
-						"namespace": e.Integration.Namespace,
-					},
-				},
-			},
-			// FIXME: The unstructured client doesn't take the namespace option into account
-			//controller.InNamespace(e.Integration.Namespace),
-			util.MatchingSelector{Selector: selector},
-			client.PropagationPolicy(metav1.DeletePropagationBackground),
-		)
-		if err != nil {
-			if !k8serrors.IsForbidden(err) {
-				t.L.ForIntegration(e.Integration).Errorf(err, "cannot delete child resources: %v", gvk)
-			}
-		} else {
-			t.L.ForIntegration(e.Integration).Debugf("child resources deleted: %v", gvk)
-		}
-	}
-}
-
 func (t *garbageCollectorTrait) deleteEachOf(gvks map[schema.GroupVersionKind]struct{}, e *Environment, selector labels.Selector) {
 	for gvk := range gvks {
 		resources := unstructured.UnstructuredList{
@@ -195,6 +165,9 @@ func (t *garbageCollectorTrait) deleteEachOf(gvks map[schema.GroupVersionKind]st
 
 		for _, resource := range resources.Items {
 			r := resource
+			if !t.canBeDeleted(e, r) {
+				continue
+			}
 			err := t.Client.Delete(context.TODO(), &r, client.PropagationPolicy(metav1.DeletePropagationBackground))
 			if err != nil {
 				// The resource may have already been deleted
@@ -208,25 +181,34 @@ func (t *garbageCollectorTrait) deleteEachOf(gvks map[schema.GroupVersionKind]st
 	}
 }
 
-func (t *garbageCollectorTrait) getDeletableTypes(e *Environment) (map[schema.GroupVersionKind]struct{}, map[schema.GroupVersionKind]struct{}, error) {
+func (t *garbageCollectorTrait) canBeDeleted(e *Environment, u unstructured.Unstructured) bool {
+	// Only delete direct children of the integration, otherwise we can affect the behavior of external controllers (i.e. Knative)
+	for _, o := range u.GetOwnerReferences() {
+		if o.Kind == v1.IntegrationKind && strings.HasPrefix(o.APIVersion, v1.SchemeGroupVersion.Group) && o.Name == e.Integration.Name {
+			return true
+		}
+	}
+	return false
+}
+
+func (t *garbageCollectorTrait) getDeletableTypes(e *Environment) (map[schema.GroupVersionKind]struct{}, error) {
 	// We rely on the discovery API to retrieve all the resources GVK,
 	// that results in an unbounded set that can impact garbage collection latency when scaling up.
 	discoveryClient, err := t.discoveryClient(e)
 	if err != nil {
-		return nil, nil, err
+		return nil, err
 	}
 	resources, err := discoveryClient.ServerPreferredNamespacedResources()
 	// Swallow group discovery errors, e.g., Knative serving exposes
 	// an aggregated API for custom.metrics.k8s.io that requires special
 	// authentication scheme while discovering preferred resources
 	if err != nil && !discovery.IsGroupDiscoveryFailedError(err) {
-		return nil, nil, err
+		return nil, err
 	}
 
-	// We only take types that support the "delete" and "deletecollection" verbs,
+	// We only take types that support the "delete" verb,
 	// to prevents from performing queries that we know are going to return "MethodNotAllowed".
-	return groupVersionKinds(discovery.FilteredBy(discovery.SupportsAllVerbs{Verbs: []string{"deletecollection"}}, resources)),
-		groupVersionKinds(discovery.FilteredBy(supportsDeleteVerbOnly{}, resources)),
+	return groupVersionKinds(discovery.FilteredBy(discovery.SupportsAllVerbs{Verbs: []string{"delete"}}, resources)),
 		nil
 }
 
@@ -240,14 +222,6 @@ func groupVersionKinds(rls []*metav1.APIResourceList) map[schema.GroupVersionKin
 	return GVKs
 }
 
-// supportsDeleteVerbOnly is a predicate matching a resource if it supports the delete verb, but not deletecollection.
-type supportsDeleteVerbOnly struct{}
-
-func (p supportsDeleteVerbOnly) Match(groupVersion string, r *metav1.APIResource) bool {
-	verbs := sets.NewString([]string(r.Verbs)...)
-	return verbs.Has("delete") && !verbs.Has("deletecollection")
-}
-
 func (t *garbageCollectorTrait) discoveryClient(e *Environment) (discovery.DiscoveryInterface, error) {
 	discoveryClientLock.Lock()
 	defer discoveryClientLock.Unlock()