Skip to content

Commit 3005b6d

Browse files
authored
Merge pull request kubernetes#95240 from apelisse/no-field-update-on-nop
Do not update managedFields timestamp when they don't change
2 parents 112dbd5 + fedc0b7 commit 3005b6d

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed

staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ go_test(
5656
"fieldmanager_test.go",
5757
"lastappliedmanager_test.go",
5858
"lastappliedupdater_test.go",
59+
"managedfieldsupdater_test.go",
5960
"skipnonapplied_test.go",
6061
],
6162
data = [

staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/managedfieldsupdater.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ func NewManagedFieldsUpdater(fieldManager Manager) Manager {
4444
// Update implements Manager.
4545
func (f *managedFieldsUpdater) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) {
4646
self := "current-operation"
47+
formerSet := managed.Fields()[manager]
4748
object, managed, err := f.fieldManager.Update(liveObj, newObj, managed, self)
4849
if err != nil {
4950
return object, managed, err
@@ -54,12 +55,15 @@ func (f *managedFieldsUpdater) Update(liveObj, newObj runtime.Object, managed Ma
5455
if vs, ok := managed.Fields()[self]; ok {
5556
delete(managed.Fields(), self)
5657

57-
managed.Times()[manager] = &metav1.Time{Time: time.Now().UTC()}
5858
if previous, ok := managed.Fields()[manager]; ok {
5959
managed.Fields()[manager] = fieldpath.NewVersionedSet(vs.Set().Union(previous.Set()), vs.APIVersion(), vs.Applied())
6060
} else {
6161
managed.Fields()[manager] = vs
6262
}
63+
// Update the time only if the manager's fieldSet has changed.
64+
if formerSet == nil || !managed.Fields()[manager].Set().Equals(formerSet.Set()) {
65+
managed.Times()[manager] = &metav1.Time{Time: time.Now().UTC()}
66+
}
6367
}
6468

6569
return object, managed, nil
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package fieldmanager_test
18+
19+
import (
20+
"reflect"
21+
"testing"
22+
"time"
23+
24+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
25+
"k8s.io/apimachinery/pkg/runtime/schema"
26+
"sigs.k8s.io/yaml"
27+
)
28+
29+
func TestNoManagedFieldsUpdateDoesntUpdateTime(t *testing.T) {
30+
f := NewTestFieldManager(schema.FromAPIVersionAndKind("v1", "Pod"), false, nil)
31+
32+
obj := &unstructured.Unstructured{Object: map[string]interface{}{}}
33+
if err := yaml.Unmarshal([]byte(`{
34+
"apiVersion": "v1",
35+
"kind": "Pod",
36+
"metadata": {
37+
"name": "pod",
38+
"labels": {"app": "nginx"}
39+
},
40+
}`), &obj.Object); err != nil {
41+
t.Fatalf("error decoding YAML: %v", err)
42+
}
43+
44+
if err := f.Update(obj, "fieldmanager_test"); err != nil {
45+
t.Fatalf("failed to update object: %v", err)
46+
}
47+
managed := f.ManagedFields()
48+
obj2 := &unstructured.Unstructured{Object: map[string]interface{}{}}
49+
if err := yaml.Unmarshal([]byte(`{
50+
"apiVersion": "v1",
51+
"kind": "Pod",
52+
"metadata": {
53+
"name": "pod",
54+
"labels": {"app": "nginx2"}
55+
},
56+
}`), &obj2.Object); err != nil {
57+
t.Fatalf("error decoding YAML: %v", err)
58+
}
59+
time.Sleep(time.Second)
60+
if err := f.Update(obj2, "fieldmanager_test"); err != nil {
61+
t.Fatalf("failed to update object: %v", err)
62+
}
63+
if !reflect.DeepEqual(managed, f.ManagedFields()) {
64+
t.Errorf("ManagedFields changed:\nBefore:\n%v\nAfter:\n%v", managed, f.ManagedFields())
65+
}
66+
}

0 commit comments

Comments
 (0)