@@ -23,6 +23,7 @@ import (
23
23
"strings"
24
24
"time"
25
25
26
+ appsv1 "k8s.io/api/apps/v1"
26
27
authorizationv1 "k8s.io/api/authorization/v1"
27
28
corev1 "k8s.io/api/core/v1"
28
29
rbacv1 "k8s.io/api/rbac/v1"
@@ -179,7 +180,7 @@ func (r *NamespaceScopeReconciler) UpdateConfigMap(instance *operatorv1.Namespac
179
180
}
180
181
klog .Infof ("Created ConfigMap %s" , cmKey .String ())
181
182
182
- if err := r .RestartPods (instance .Spec .RestartLabels , instance .Namespace ); err != nil {
183
+ if err := r .RestartPods (instance .Spec .RestartLabels , cm , instance .Namespace ); err != nil {
183
184
return err
184
185
}
185
186
return nil
@@ -209,7 +210,7 @@ func (r *NamespaceScopeReconciler) UpdateConfigMap(instance *operatorv1.Namespac
209
210
210
211
// When the configmap updated, restart all the pods with the RestartLabels
211
212
if restartpod {
212
- if err := r .RestartPods (instance .Spec .RestartLabels , instance .Namespace ); err != nil {
213
+ if err := r .RestartPods (instance .Spec .RestartLabels , cm , instance .Namespace ); err != nil {
213
214
return err
214
215
}
215
216
}
@@ -607,19 +608,133 @@ func (r *NamespaceScopeReconciler) DeleteRoleBinding(labels map[string]string, t
607
608
}
608
609
609
610
// Restart pods in specific namespace with the matching labels
610
- func (r * NamespaceScopeReconciler ) RestartPods (labels map [string ]string , namespace string ) error {
611
+ func (r * NamespaceScopeReconciler ) RestartPods (labels map [string ]string , cm * corev1. ConfigMap , namespace string ) error {
611
612
klog .Infof ("Restarting pods in namespace %s with matching labels: %v" , namespace , labels )
612
- opts := []client.DeleteAllOfOption {
613
+ opts := []client.ListOption {
613
614
client .MatchingLabels (labels ),
614
615
client .InNamespace (namespace ),
615
616
}
616
- if err := r .DeleteAllOf (ctx , & corev1.Pod {}, opts ... ); err != nil {
617
- klog .Errorf ("Failed to restart pods with matching labels %s in namespace %s: %v" , labels , namespace , err )
617
+ podList := & corev1.PodList {}
618
+ if err := r .Client .List (ctx , podList , opts ... ); err != nil {
619
+ klog .Errorf ("Failed to list pods with matching labels %s in namespace %s: %v" , labels , namespace , err )
618
620
return err
619
621
}
622
+
623
+ deploymentNameList := make ([]string , 0 )
624
+ daemonSetNameList := make ([]string , 0 )
625
+ statefulSetNameList := make ([]string , 0 )
626
+ for _ , pod := range podList .Items {
627
+ // Check if the pod is required to be refreshed
628
+ if ! needRestart (pod , cm .Name ) {
629
+ continue
630
+ }
631
+ // Delete operator pod to refresh it
632
+ podLabels := pod .GetLabels ()
633
+ _ , ok := podLabels ["olm.operatorGroup" ]
634
+ if ok {
635
+ if err := r .Client .Delete (ctx , & pod ); err != nil {
636
+ klog .Errorf ("Failed to delete pods %s in namespace %s: %v" , pod .Name , pod .Namespace , err )
637
+ return err
638
+ }
639
+ continue
640
+ }
641
+ // Rolling update operand pods
642
+ ownerReferences := pod .GetOwnerReferences ()
643
+ for _ , or := range ownerReferences {
644
+ if ! * or .Controller {
645
+ continue
646
+ }
647
+ switch or .Kind {
648
+ case "ReplicaSet" :
649
+ splitedDN := strings .Split (or .Name , "-" )
650
+ deploymentName := strings .Join (splitedDN [:len (splitedDN )- 1 ], "-" )
651
+ deploymentNameList = append (deploymentNameList , deploymentName )
652
+ case "DaemonSet" :
653
+ daemonSetNameList = append (daemonSetNameList , or .Name )
654
+ case "StatefulSet" :
655
+ statefulSetNameList = append (statefulSetNameList , or .Name )
656
+ }
657
+ }
658
+ }
659
+
660
+ hashedData := sha256 .Sum256 ([]byte (cm .Data ["namespaces" ]))
661
+ annotationValue := hex .EncodeToString (hashedData [0 :7 ])
662
+
663
+ // Refresh pods from deployment
664
+ deploymentNameList = util .ToStringSlice (util .MakeSet (deploymentNameList ))
665
+ for _ , deploymentName := range deploymentNameList {
666
+ deploy := & appsv1.Deployment {}
667
+ if err := r .Client .Get (ctx , types.NamespacedName {Name : deploymentName , Namespace : namespace }, deploy ); err != nil {
668
+ klog .Errorf ("Failed to get deployment %s in namespace %s: %v" , deploymentName , namespace , err )
669
+ return err
670
+ }
671
+ originalDeploy := deploy
672
+ if deploy .Spec .Template .Annotations == nil {
673
+ deploy .Spec .Template .Annotations = make (map [string ]string )
674
+ }
675
+ deploy .Spec .Template .Annotations ["nss.ibm.com/namespaceList" ] = annotationValue
676
+ if err := r .Patch (ctx , deploy , client .MergeFrom (originalDeploy )); err != nil {
677
+ klog .Errorf ("Failed to update the annotation of the deployment %s in namespace %s: %v" , deploymentName , namespace , err )
678
+ return err
679
+ }
680
+ }
681
+
682
+ // Refresh pods from daemonSet
683
+ daemonSetNameList = util .ToStringSlice (util .MakeSet (daemonSetNameList ))
684
+ for _ , daemonSetName := range daemonSetNameList {
685
+ daemonSet := & appsv1.DaemonSet {}
686
+ if err := r .Client .Get (ctx , types.NamespacedName {Name : daemonSetName , Namespace : namespace }, daemonSet ); err != nil {
687
+ klog .Errorf ("Failed to get daemonSet %s in namespace %s: %v" , daemonSetName , namespace , err )
688
+ return err
689
+ }
690
+ originalDaemonSet := daemonSet
691
+ if daemonSet .Spec .Template .Annotations == nil {
692
+ daemonSet .Spec .Template .Annotations = make (map [string ]string )
693
+ }
694
+ daemonSet .Spec .Template .Annotations ["nss.ibm.com/namespaceList" ] = annotationValue
695
+ if err := r .Patch (ctx , daemonSet , client .MergeFrom (originalDaemonSet )); err != nil {
696
+ klog .Errorf ("Failed to update the annotation of the daemonSet %s in namespace %s: %v" , daemonSetName , namespace , err )
697
+ return err
698
+ }
699
+ }
700
+
701
+ // Refresh pods from statefulSet
702
+ statefulSetNameList = util .ToStringSlice (util .MakeSet (statefulSetNameList ))
703
+ for _ , statefulSetName := range statefulSetNameList {
704
+ statefulSet := & appsv1.StatefulSet {}
705
+ if err := r .Client .Get (ctx , types.NamespacedName {Name : statefulSetName , Namespace : namespace }, statefulSet ); err != nil {
706
+ klog .Errorf ("Failed to get statefulSet %s in namespace %s: %v" , statefulSetName , namespace , err )
707
+ return err
708
+ }
709
+ originalStatefulSet := statefulSet
710
+ if statefulSet .Spec .Template .Annotations == nil {
711
+ statefulSet .Spec .Template .Annotations = make (map [string ]string )
712
+ }
713
+ statefulSet .Spec .Template .Annotations ["nss.ibm.com/namespaceList" ] = annotationValue
714
+ if err := r .Patch (ctx , statefulSet , client .MergeFrom (originalStatefulSet )); err != nil {
715
+ klog .Errorf ("Failed to update the annotation of the statefulSet %s in namespace %s: %v" , statefulSetName , namespace , err )
716
+ return err
717
+ }
718
+ }
620
719
return nil
621
720
}
622
721
722
+ func needRestart (pod corev1.Pod , cmName string ) bool {
723
+ for _ , volume := range pod .Spec .Volumes {
724
+ if volume .ConfigMap != nil && volume .ConfigMap .Name == cmName {
725
+ return true
726
+ }
727
+ }
728
+ for _ , container := range pod .Spec .Containers {
729
+ for _ , env := range container .Env {
730
+ if env .ValueFrom != nil && env .ValueFrom .ConfigMapKeyRef != nil && env .ValueFrom .ConfigMapKeyRef .Name == cmName {
731
+ return true
732
+ }
733
+ }
734
+ }
735
+ return false
736
+ }
737
+
623
738
func (r * NamespaceScopeReconciler ) setDefaults (instance * operatorv1.NamespaceScope ) * operatorv1.NamespaceScope {
624
739
if instance .Spec .ConfigmapName == "" {
625
740
instance .Spec .ConfigmapName = constant .NamespaceScopeConfigmapName
0 commit comments