mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 14:37:00 +00:00
Preserve old observedGen if incoming attempts to clear it
This commit is contained in:
parent
12d34624ba
commit
bb3ba9d073
@ -227,9 +227,38 @@ func (podStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.
|
|||||||
newPod.Status.QOSClass = oldPod.Status.QOSClass
|
newPod.Status.QOSClass = oldPod.Status.QOSClass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preserveOldObservedGeneration(newPod, oldPod)
|
||||||
podutil.DropDisabledPodFields(newPod, oldPod)
|
podutil.DropDisabledPodFields(newPod, oldPod)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a client request tries to clear `observedGeneration`, in the pod status or
|
||||||
|
// conditions, we preserve the original value.
|
||||||
|
func preserveOldObservedGeneration(newPod, oldPod *api.Pod) {
|
||||||
|
if newPod.Status.ObservedGeneration == 0 {
|
||||||
|
newPod.Status.ObservedGeneration = oldPod.Status.ObservedGeneration
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember observedGeneration values from old status conditions.
|
||||||
|
// This is a list per type because validation permits multiple conditions with the same type.
|
||||||
|
oldConditionGenerations := map[api.PodConditionType][]int64{}
|
||||||
|
for _, oldCondition := range oldPod.Status.Conditions {
|
||||||
|
oldConditionGenerations[oldCondition.Type] = append(oldConditionGenerations[oldCondition.Type], oldCondition.ObservedGeneration)
|
||||||
|
}
|
||||||
|
|
||||||
|
// For any conditions in the new status without observedGeneration set, preserve the old value.
|
||||||
|
for i, newCondition := range newPod.Status.Conditions {
|
||||||
|
oldGeneration := int64(0)
|
||||||
|
if oldGenerations, ok := oldConditionGenerations[newCondition.Type]; ok && len(oldGenerations) > 0 {
|
||||||
|
oldGeneration = oldGenerations[0]
|
||||||
|
oldConditionGenerations[newCondition.Type] = oldGenerations[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if newCondition.ObservedGeneration == 0 {
|
||||||
|
newPod.Status.Conditions[i].ObservedGeneration = oldGeneration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (podStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
func (podStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
|
||||||
pod := obj.(*api.Pod)
|
pod := obj.(*api.Pod)
|
||||||
oldPod := old.(*api.Pod)
|
oldPod := old.(*api.Pod)
|
||||||
|
@ -3396,6 +3396,161 @@ func TestStatusPrepareForUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: "preserve old status.observedGeneration if empty",
|
||||||
|
oldPod: &api.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "pod"},
|
||||||
|
Status: api.PodStatus{
|
||||||
|
ObservedGeneration: 20,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
newPod: &api.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "pod"},
|
||||||
|
},
|
||||||
|
expected: &api.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "pod"},
|
||||||
|
Status: api.PodStatus{
|
||||||
|
ObservedGeneration: 20,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "preserve old conditions.observedGeneration if empty",
|
||||||
|
oldPod: &api.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "pod"},
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Conditions: []api.PodCondition{
|
||||||
|
{
|
||||||
|
Type: "old=without,new=without",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "old=with,new=without",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "old=without,new=with",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "old=with,new=with",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "removed-condition",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "duplicate type",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "duplicate type",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "duplicate type",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
newPod: &api.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "pod"},
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Conditions: []api.PodCondition{
|
||||||
|
{
|
||||||
|
Type: "old=without,new=without",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "old=with,new=without",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "old=without,new=with",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "old=with,new=with",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "new-condition",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "duplicate type",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "duplicate type",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "duplicate type",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &api.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "pod"},
|
||||||
|
Status: api.PodStatus{
|
||||||
|
Conditions: []api.PodCondition{
|
||||||
|
{
|
||||||
|
Type: "old=without,new=without",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "old=with,new=without",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "old=without,new=with",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "old=with,new=with",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "new-condition",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "duplicate type",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "duplicate type",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: "duplicate type",
|
||||||
|
Status: api.ConditionTrue,
|
||||||
|
ObservedGeneration: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
Loading…
Reference in New Issue
Block a user