From 00d24d618589c98af3525c663228c54b467377b8 Mon Sep 17 00:00:00 2001 From: MarkLux Date: Fri, 30 Jun 2023 10:20:00 +0800 Subject: [PATCH] fix pod condition of sidecarset upgradable when multi sidecarset injected (#1272) Signed-off-by: MarkLux --- .../sidecarset/sidecarset_processor.go | 93 +++++++++++++++---- pkg/controller/util/pod_condition_utils.go | 26 ++++++ 2 files changed, 99 insertions(+), 20 deletions(-) create mode 100644 pkg/controller/util/pod_condition_utils.go diff --git a/pkg/controller/sidecarset/sidecarset_processor.go b/pkg/controller/sidecarset/sidecarset_processor.go index 4ea1e0a218..53af02126d 100644 --- a/pkg/controller/sidecarset/sidecarset_processor.go +++ b/pkg/controller/sidecarset/sidecarset_processor.go @@ -27,6 +27,7 @@ import ( appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" "github.com/openkruise/kruise/pkg/control/sidecarcontrol" + controlutil "github.com/openkruise/kruise/pkg/controller/util" "github.com/openkruise/kruise/pkg/util" utilclient "github.com/openkruise/kruise/pkg/util/client" historyutil "github.com/openkruise/kruise/pkg/util/history" @@ -217,19 +218,8 @@ func (p *Processor) updatePodSidecarAndHash(control sidecarcontrol.SidecarContro return err } - // patch SidecarSetUpgradable condition - if conditionChanged := podutil.UpdatePodCondition(&podClone.Status, &corev1.PodCondition{ - Type: sidecarcontrol.SidecarSetUpgradable, - Status: corev1.ConditionTrue, - }); !conditionChanged { - // reduce unnecessary patch. - return nil - } - - _, condition := podutil.GetPodCondition(&podClone.Status, sidecarcontrol.SidecarSetUpgradable) - mergePatch := fmt.Sprintf(`{"status": {"conditions": [%s]}}`, util.DumpJSON(condition)) - err = p.Client.Status().Patch(context.TODO(), podClone, client.RawPatch(types.StrategicMergePatchType, []byte(mergePatch))) - return err + // update pod condition of sidecar upgradable + return p.updateUpgradablePodCondition(sidecarSet, podClone) } func (p *Processor) listMatchedSidecarSets(pod *corev1.Pod) string { @@ -632,6 +622,50 @@ func isSidecarSetUpdateFinish(status *appsv1alpha1.SidecarSetStatus) bool { return status.UpdatedPods >= status.MatchedPods } +func (p *Processor) updateUpgradablePodCondition(sidecarset *appsv1alpha1.SidecarSet, upgradablePod *corev1.Pod) error { + + _, condition := podutil.GetPodCondition(&upgradablePod.Status, sidecarcontrol.SidecarSetUpgradable) + + if condition == nil { + condition = &corev1.PodCondition{ + Type: sidecarcontrol.SidecarSetUpgradable, + Status: corev1.ConditionTrue, + } + } + + // get message kv from condition message + messageKv, err := controlutil.GetMessageKvFromCondition(condition) + if err != nil { + return err + } + + // mark sidecarset upgradable status to true + messageKv[sidecarset.Name] = true + + // update messageKv + for _, v := range messageKv { + if v == false { + // if there is any sidecarset that is not upgradable, the condition status should be false + condition.Status = corev1.ConditionFalse + break + } + } + + err = controlutil.UpdateMessageKvCondition(messageKv, condition) + if err != nil { + return err + } + + // patch SidecarSetUpgradable condition + if conditionChanged := podutil.UpdatePodCondition(&upgradablePod.Status, condition); !conditionChanged { + // reduce unnecessary patch. + return nil + } + + mergePatch := fmt.Sprintf(`{"status": {"conditions": [%s]}}`, util.DumpJSON(condition)) + return p.Client.Status().Patch(context.TODO(), upgradablePod, client.RawPatch(types.StrategicMergePatchType, []byte(mergePatch))) +} + func (p *Processor) updateNotUpgradablePodCondition(sidecarset *appsv1alpha1.SidecarSet, notUpgradablePod *corev1.Pod) error { podClone := &corev1.Pod{} @@ -641,17 +675,36 @@ func (p *Processor) updateNotUpgradablePodCondition(sidecarset *appsv1alpha1.Sid klog.Errorf("error getting pod %s/%s from client", notUpgradablePod.Namespace, notUpgradablePod.Name) return err } + + _, condition := podutil.GetPodCondition(&podClone.Status, sidecarcontrol.SidecarSetUpgradable) + + if condition == nil { + condition = &corev1.PodCondition{ + Type: sidecarcontrol.SidecarSetUpgradable, + Status: corev1.ConditionFalse, + Reason: "UpdateImmutableField", + } + } + + // get message kv from pod condition, if conditoin not exist, an empty map will be returned + messageKv, err := controlutil.GetMessageKvFromCondition(condition) + if err != nil { + return err + } + // mark this sidecarSet as false + messageKv[sidecarset.Name] = false + // update message kv + err = controlutil.UpdateMessageKvCondition(messageKv, condition) + if err != nil { + return err + } + // update pod condition - conditionUpdateResult := podutil.UpdatePodCondition(&podClone.Status, &corev1.PodCondition{ - Type: sidecarcontrol.SidecarSetUpgradable, - Status: corev1.ConditionFalse, - Reason: "UpdateImmutableField", - Message: "Pod's sidecar set is not upgradable due to changes out of image field", - }) + conditionUpdateResult := podutil.UpdatePodCondition(&podClone.Status, condition) if !conditionUpdateResult { return nil } - err := p.Client.Status().Update(context.TODO(), podClone) + err = p.Client.Status().Update(context.TODO(), podClone) if err != nil { return err } diff --git a/pkg/controller/util/pod_condition_utils.go b/pkg/controller/util/pod_condition_utils.go new file mode 100644 index 0000000000..af89c5535f --- /dev/null +++ b/pkg/controller/util/pod_condition_utils.go @@ -0,0 +1,26 @@ +package util + +import ( + "encoding/json" + + v1 "k8s.io/api/core/v1" +) + +func GetMessageKvFromCondition(condition *v1.PodCondition) (map[string]interface{}, error) { + messageKv := make(map[string]interface{}) + if condition.Message != "" { + if err := json.Unmarshal([]byte(condition.Message), &messageKv); err != nil { + return nil, err + } + } + return messageKv, nil +} + +func UpdateMessageKvCondition(kv map[string]interface{}, condition *v1.PodCondition) error { + message, err := json.Marshal(kv) + if err != nil { + return err + } + condition.Message = string(message) + return nil +}