From d881ebd1b242ebfce089b84d6c1a4007e8f58652 Mon Sep 17 00:00:00 2001 From: Leela Venkaiah G Date: Tue, 21 Dec 2021 09:32:13 +0530 Subject: [PATCH] fix: implement topolvm controller mutate function - controller-util's `CreateOrUpdate` accepts a mutate function - when topolvm controller deployment is being created, mutate the existing (~new) deployment to have desired deployment state - when reconciled for update, mutate function will only set/change spec of concerned fields to have desired deployment. Signed-off-by: Leela Venkaiah G --- controllers/topolvm_controller.go | 47 +++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/controllers/topolvm_controller.go b/controllers/topolvm_controller.go index 4643baf13..989c183b5 100644 --- a/controllers/topolvm_controller.go +++ b/controllers/topolvm_controller.go @@ -33,43 +33,51 @@ func (c topolvmController) getName() string { func (c topolvmController) ensureCreated(r *LVMClusterReconciler, ctx context.Context, lvmCluster *lvmv1alpha1.LVMCluster) error { // get the desired state of topolvm controller deployment - controllerDeployment := getControllerDeployment(lvmCluster) + desiredDeployment := getControllerDeployment(lvmCluster) + existingDeployment := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: desiredDeployment.Name, + Namespace: desiredDeployment.Namespace, + }, + } - result, err := cutil.CreateOrUpdate(ctx, r.Client, controllerDeployment, func() error { return nil }) + result, err := cutil.CreateOrUpdate(ctx, r.Client, existingDeployment, func() error { + return c.setTopolvmControllerDesiredState(existingDeployment, desiredDeployment) + }) if err != nil { - r.Log.Error(err, "csi controller reconcile failure", "name", controllerDeployment.Name) + r.Log.Error(err, "csi controller reconcile failure", "name", desiredDeployment.Name) return err } else { - r.Log.Info("csi controller", "operation", result, "name", controllerDeployment.Name) + r.Log.Info("csi controller", "operation", result, "name", desiredDeployment.Name) } return nil } func (c topolvmController) ensureDeleted(r *LVMClusterReconciler, ctx context.Context, lvmCluster *lvmv1alpha1.LVMCluster) error { - controllerDeployment := &appsv1.Deployment{} - err := r.Client.Get(ctx, types.NamespacedName{Name: TopolvmControllerDeploymentName, Namespace: lvmCluster.Namespace}, controllerDeployment) + existingDeployment := &appsv1.Deployment{} + err := r.Client.Get(ctx, types.NamespacedName{Name: TopolvmControllerDeploymentName, Namespace: lvmCluster.Namespace}, existingDeployment) if err != nil { // already deleted in previous reconcile if errors.IsNotFound(err) { - r.Log.Info("csi controller deleted", "TopolvmController", controllerDeployment.Name) + r.Log.Info("csi controller deleted", "TopolvmController", existingDeployment.Name) return nil } - r.Log.Error(err, "failed to retrieve csi controller deployment", "TopolvmController", controllerDeployment.Name) + r.Log.Error(err, "failed to retrieve csi controller deployment", "TopolvmController", existingDeployment.Name) return err } // if not deleted, initiate deletion - if controllerDeployment.GetDeletionTimestamp().IsZero() { - if err = r.Client.Delete(ctx, controllerDeployment); err != nil { - r.Log.Error(err, "failed to delete topolvm controller deployment", "TopolvmController", controllerDeployment.Name) + if existingDeployment.GetDeletionTimestamp().IsZero() { + if err = r.Client.Delete(ctx, existingDeployment); err != nil { + r.Log.Error(err, "failed to delete topolvm controller deployment", "TopolvmController", existingDeployment.Name) return err } } else { // set deletion in-progress for next reconcile to confirm deletion - return fmt.Errorf("topolvm controller deployment %s is already marked for deletion", controllerDeployment.Name) + return fmt.Errorf("topolvm controller deployment %s is already marked for deletion", existingDeployment.Name) } return nil @@ -80,6 +88,21 @@ func (c topolvmController) updateStatus(r *LVMClusterReconciler, ctx context.Con return nil } +func (c topolvmController) setTopolvmControllerDesiredState(existing, desired *appsv1.Deployment) error { + + // at creation, deep copy desired deployment into existing + if existing.CreationTimestamp.IsZero() { + desired.DeepCopyInto(existing) + return nil + } + + // for update, topolvm controller is interested in only updating container images + // labels, volumes, service account etc can remain unchanged + existing.Spec.Template.Spec.Containers = desired.Spec.Template.Spec.Containers + + return nil +} + func getControllerDeployment(lvmCluster *lvmv1alpha1.LVMCluster) *appsv1.Deployment { // Topolvm CSI Controller Deployment