From 46b089c440f992c49a8e22d8da28044306306ccf Mon Sep 17 00:00:00 2001 From: Varsha Prasad Narsing Date: Tue, 12 Sep 2023 18:55:46 -0400 Subject: [PATCH] [fix] Fix issue with cascading deletion of image unpack pods Signed-off-by: Varsha Prasad Narsing --- api/v1alpha2/bundledeployment_types.go | 5 +- api/v1alpha2/zz_generated.deepcopy.go | 3 +- cmd/core/main.go | 3 ++ .../bundledeployment/bundledeployment.go | 48 ++++++++++++++++++- internal/controllers/v1alpha2/source/image.go | 2 +- internal/source/image.go | 2 +- .../core.rukpak.io_bundledeployments.yaml | 15 +++++- 7 files changed, 72 insertions(+), 6 deletions(-) diff --git a/api/v1alpha2/bundledeployment_types.go b/api/v1alpha2/bundledeployment_types.go index 04332c18..67a7d71c 100644 --- a/api/v1alpha2/bundledeployment_types.go +++ b/api/v1alpha2/bundledeployment_types.go @@ -52,8 +52,11 @@ const ( // +kubebuilder:object:root=true // +kubebuilder:subresource:status // +kubebuilder:resource:scope=Cluster,shortName={"bd","bds"} -// BundleDeployment is the Schema for the bundledeployments API +// +kubebuilder:printcolumn:name="Install State",type=string,JSONPath=`.status.conditions[?(.type=="Installed")].reason` +// +kubebuilder:printcolumn:name=Age,type=date,JSONPath=`.metadata.creationTimestamp` // +kubebuilder:storageversion + +// BundleDeployment is the Schema for the bundledeployments API type BundleDeployment struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` diff --git a/api/v1alpha2/zz_generated.deepcopy.go b/api/v1alpha2/zz_generated.deepcopy.go index 85c4faea..37f5ff16 100644 --- a/api/v1alpha2/zz_generated.deepcopy.go +++ b/api/v1alpha2/zz_generated.deepcopy.go @@ -23,7 +23,7 @@ package v1alpha2 import ( "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -141,6 +141,7 @@ func (in *BundleDeploymentSpec) DeepCopyInto(out *BundleDeploymentSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + in.Config.DeepCopyInto(&out.Config) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleDeploymentSpec. diff --git a/cmd/core/main.go b/cmd/core/main.go index 19a97a03..b8bc6496 100644 --- a/cmd/core/main.go +++ b/cmd/core/main.go @@ -118,6 +118,7 @@ func main() { dependentSelector := labels.NewSelector().Add(*dependentRequirement) cfg := ctrl.GetConfigOrDie() + fmt.Println("systemNs:!!!!", systemNamespace) if systemNamespace == "" { systemNamespace = util.PodNamespace() } @@ -126,6 +127,7 @@ func main() { opts.Scheme = scheme opts.Namespace = systemNamespace }) + fmt.Println("systemNsCluster!!!!!!!", systemNsCluster) if err != nil { setupLog.Error(err, "unable to create system namespace cluster") os.Exit(1) @@ -260,6 +262,7 @@ func main() { // } if err := v1alpha2bd.SetupWithManager(mgr, + systemNsCluster.GetCache(), v1alpha2bd.WithUnpacker(defaultUnpacker), v1alpha2bd.WithValidators(v1alpha2validators.NewDefaultValidator()), v1alpha2bd.WithDeployer(deployer)); err != nil { diff --git a/internal/controllers/v1alpha2/controllers/bundledeployment/bundledeployment.go b/internal/controllers/v1alpha2/controllers/bundledeployment/bundledeployment.go index 18f8d421..676800fd 100644 --- a/internal/controllers/v1alpha2/controllers/bundledeployment/bundledeployment.go +++ b/internal/controllers/v1alpha2/controllers/bundledeployment/bundledeployment.go @@ -23,7 +23,12 @@ import ( "sync" "time" + "github.com/go-logr/logr" "github.com/operator-framework/rukpak/api/v1alpha2" + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client/apiutil" + "sigs.k8s.io/controller-runtime/pkg/reconcile" v1alpha2deployer "github.com/operator-framework/rukpak/internal/controllers/v1alpha2/deployer" v1alpha2source "github.com/operator-framework/rukpak/internal/controllers/v1alpha2/source" @@ -35,6 +40,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" apimacherrors "k8s.io/apimachinery/pkg/util/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/client-go/tools/record" @@ -45,6 +51,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/source" + crsource "sigs.k8s.io/controller-runtime/pkg/source" ) // BundleDeploymentReconciler reconciles a BundleDeployment object @@ -280,7 +287,7 @@ func (b *bundleDeploymentReconciler) validateConfig() error { return utilerrors.NewAggregate(errs) } -func SetupWithManager(mgr manager.Manager, opts ...Option) error { +func SetupWithManager(mgr manager.Manager, systemNsCache cache.Cache, opts ...Option) error { bd := &bundleDeploymentReconciler{ Client: mgr.GetClient(), dynamicWatchGVKs: map[schema.GroupVersionKind]struct{}{}, @@ -294,9 +301,11 @@ func SetupWithManager(mgr manager.Manager, opts ...Option) error { } controllerName := fmt.Sprintf("controller-bundledeployment.%s", v1alpha2.BundleDeploymentGVK.Version) + l := mgr.GetLogger().WithName(controllerName) controller, err := ctrl.NewControllerManagedBy(mgr). Named(controllerName). For(&v1alpha2.BundleDeployment{}). + Watches(crsource.NewKindWithCache(&corev1.Pod{}, systemNsCache), MapOwnerToBundleDeploymentHandler(context.Background(), mgr.GetClient(), l, &v1alpha2.BundleDeployment{})). Build(bd) if err != nil { return err @@ -304,3 +313,40 @@ func SetupWithManager(mgr manager.Manager, opts ...Option) error { bd.controller = controller return nil } + +// MapOwnerToBundleDeploymentHandler is a handler implementation that finds an owner reference in the event object that +// references the provided owner. If a reference for the provided owner is found this handler enqueues a request for that owner to be reconciled. +func MapOwnerToBundleDeploymentHandler(ctx context.Context, cl client.Client, log logr.Logger, owner client.Object) handler.EventHandler { + return handler.EnqueueRequestsFromMapFunc(func(obj client.Object) []reconcile.Request { + ownerGVK, err := apiutil.GVKForObject(owner, cl.Scheme()) + if err != nil { + log.Error(err, "map ownee to owner: lookup GVK for owner") + return nil + } + type ownerInfo struct { + key types.NamespacedName + gvk schema.GroupVersionKind + } + var oi *ownerInfo + + for _, ref := range obj.GetOwnerReferences() { + gv, err := schema.ParseGroupVersion(ref.APIVersion) + if err != nil { + log.Error(err, fmt.Sprintf("map ownee to owner: parse ownee's owner reference group version %q", ref.APIVersion)) + return nil + } + refGVK := gv.WithKind(ref.Kind) + if refGVK == ownerGVK && ref.Controller != nil && *ref.Controller { + oi = &ownerInfo{ + key: types.NamespacedName{Name: ref.Name}, + gvk: ownerGVK, + } + break + } + } + if oi == nil { + return nil + } + return []reconcile.Request{{NamespacedName: oi.key}} + }) +} diff --git a/internal/controllers/v1alpha2/source/image.go b/internal/controllers/v1alpha2/source/image.go index a38a12f8..9174d2e4 100644 --- a/internal/controllers/v1alpha2/source/image.go +++ b/internal/controllers/v1alpha2/source/image.go @@ -190,7 +190,7 @@ func (i *Image) getDesiredPodApplyConfig(bdName string, bundleSrc *v1alpha2.Bund WithOwnerReferences(v1.OwnerReference(). WithName(bdName). WithKind(v1alpha2.BundleDeploymentKind). - WithAPIVersion(v1alpha2.BundleDeploymentGVK.Version). + WithAPIVersion(v1alpha2.BundleDeploymentGVK.GroupVersion().String()). WithUID(opts.BundleDeploymentUID). WithController(true). WithBlockOwnerDeletion(true), diff --git a/internal/source/image.go b/internal/source/image.go index e0b34a36..6386c94e 100644 --- a/internal/source/image.go +++ b/internal/source/image.go @@ -129,7 +129,7 @@ func (i *Image) getDesiredPodApplyConfig(bundle *rukpakv1alpha1.Bundle) *applyco WithAPIVersion(bundle.APIVersion). WithUID(bundle.UID). WithController(true). - WithBlockOwnerDeletion(true), + WithBlockOwnerDeletion(false), ). WithSpec(applyconfigurationcorev1.PodSpec(). WithAutomountServiceAccountToken(false). diff --git a/manifests/base/apis/crds/core.rukpak.io_bundledeployments.yaml b/manifests/base/apis/crds/core.rukpak.io_bundledeployments.yaml index 590a1ac4..221a4a68 100644 --- a/manifests/base/apis/crds/core.rukpak.io_bundledeployments.yaml +++ b/manifests/base/apis/crds/core.rukpak.io_bundledeployments.yaml @@ -359,7 +359,14 @@ spec: type: object served: true storage: false - - name: v1alpha2 + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(.type=="Installed")].reason + name: Install State + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 schema: openAPIV3Schema: description: BundleDeployment is the Schema for the bundledeployments API @@ -379,6 +386,12 @@ spec: spec: description: BundleDeploymentSpec defines the desired state of BundleDeployment properties: + config: + description: 'Config is provisioner specific configurations TODO: + This should be become deployer specific. Should move to helm deployer + configuration.' + type: object + x-kubernetes-preserve-unknown-fields: true format: description: Format refers to the bundle type which is being passed through the bundle deployment API.