From 0ba49318640c4c1e30fa9046bd0fe1e86b1c7d63 Mon Sep 17 00:00:00 2001 From: "zhuohao.li" Date: Mon, 6 Mar 2023 16:24:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BD=93=E4=BF=AE=E6=94=B9na?= =?UTF-8?q?cos=20cr=E9=83=A8=E5=88=86=E5=8F=82=E6=95=B0=E4=B8=8D=E4=BC=9A?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E7=94=9F=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- operator/pkg/service/k8s/statefulset.go | 61 +++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/operator/pkg/service/k8s/statefulset.go b/operator/pkg/service/k8s/statefulset.go index c8fedac..361153d 100644 --- a/operator/pkg/service/k8s/statefulset.go +++ b/operator/pkg/service/k8s/statefulset.go @@ -121,12 +121,13 @@ func (s *StatefulSetService) CreateOrUpdateStatefulSet(namespace string, statefu // namespace is our spec(https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#concurrency-control-and-consistency), // we will replace the current namespace state. - dAtA, _ := json.Marshal(storedStatefulSet.Spec.Template.Spec.Containers[0].Resources) - dAtB, _ := json.Marshal(statefulSet.Spec.Template.Spec.Containers[0].Resources) - if !bytes.Equal(dAtA, dAtB) || - *statefulSet.Spec.Replicas != *storedStatefulSet.Spec.Replicas { + switch checkSts(storedStatefulSet, statefulSet) { + case Update: statefulSet.ResourceVersion = storedStatefulSet.ResourceVersion return s.UpdateStatefulSet(namespace, statefulSet) + //updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden + case Delete: + return s.DeleteStatefulSet(namespace, storedStatefulSet.Name) } return nil } @@ -141,3 +142,55 @@ func (s *StatefulSetService) DeleteStatefulSet(namespace, name string) error { func (s *StatefulSetService) ListStatefulSets(namespace string) (*appsv1.StatefulSetList, error) { return s.kubeClient.AppsV1().StatefulSets(namespace).List(context.TODO(), metav1.ListOptions{}) } + +type operator int + +const ( + None operator = iota + Update + Delete +) + +// check whether delete sts +func checkSts(old *appsv1.StatefulSet, new *appsv1.StatefulSet) operator { + + rsA, _ := json.Marshal(old.Spec.Template.Spec.Containers[0].Resources) + rsB, _ := json.Marshal(new.Spec.Template.Spec.Containers[0].Resources) + + envA, _ := json.Marshal(old.Spec.Template.Spec.Containers[0].Env) + envB, _ := json.Marshal(new.Spec.Template.Spec.Containers[0].Env) + + if checkVolumeClaimTemplates(old, new) { + return Delete + } + + if !bytes.Equal(rsA, rsB) || *old.Spec.Replicas != *new.Spec.Replicas || !bytes.Equal(envA, envB) { + return Update + } + + return None +} + +// check whether delete sts +func checkVolumeClaimTemplates(old *appsv1.StatefulSet, new *appsv1.StatefulSet) bool { + ov := old.Spec.VolumeClaimTemplates + nv := new.Spec.VolumeClaimTemplates + if len(ov) == 0 && len(nv) == 0 { + return false + } + + if len(ov) != len(nv) { + return true + } + + if len(ov) > 0 && len(nv) > 0 { + vmA, _ := json.Marshal(old.Spec.VolumeClaimTemplates[0].Spec.Resources) + vmB, _ := json.Marshal(new.Spec.VolumeClaimTemplates[0].Spec.Resources) + + oscn := old.Spec.VolumeClaimTemplates[0].Spec.StorageClassName + nscn := new.Spec.VolumeClaimTemplates[0].Spec.StorageClassName + return !bytes.Equal(vmA, vmB) || !strings.EqualFold(*oscn, *nscn) + } + + return false +}