Skip to content

Commit 39681aa

Browse files
author
Antoine Pelisse
committed
fieldmanager: Move ManagedFields update logic into its own class
1 parent 8508875 commit 39681aa

File tree

5 files changed

+80
-19
lines changed

5 files changed

+80
-19
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
@@ -6,6 +6,7 @@ go_library(
66
"buildmanagerinfo.go",
77
"capmanagers.go",
88
"fieldmanager.go",
9+
"managedfieldsupdater.go",
910
"skipnonapplied.go",
1011
"stripmeta.go",
1112
"structuredmerge.go",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ func NewDefaultCRDFieldManager(models openapiproto.Models, objectConverter runti
9494
// newDefaultFieldManager is a helper function which wraps a Manager with certain default logic.
9595
func newDefaultFieldManager(f Manager, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind) *FieldManager {
9696
f = NewStripMetaManager(f)
97+
f = NewManagedFieldsUpdater(f)
9798
f = NewBuildManagerInfoManager(f, kind.GroupVersion())
9899
f = NewCapManagersManager(f, DefaultMaxUpdateManagers)
99100
f = NewProbabilisticSkipNonAppliedManager(f, objectCreater, kind, DefaultTrackOnCreateProbability)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ func NewTestFieldManager(gvk schema.GroupVersionKind) TestFieldManager {
104104
live.SetKind(gvk.Kind)
105105
live.SetAPIVersion(gvk.GroupVersion().String())
106106
f = fieldmanager.NewStripMetaManager(f)
107+
f = fieldmanager.NewManagedFieldsUpdater(f)
107108
f = fieldmanager.NewBuildManagerInfoManager(f, gvk.GroupVersion())
108109
return TestFieldManager{
109110
fieldManager: f,
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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
18+
19+
import (
20+
"time"
21+
22+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23+
"k8s.io/apimachinery/pkg/runtime"
24+
"sigs.k8s.io/structured-merge-diff/v3/fieldpath"
25+
)
26+
27+
type managedFieldsUpdater struct {
28+
fieldManager Manager
29+
}
30+
31+
var _ Manager = &managedFieldsUpdater{}
32+
33+
// NewManagedFieldsUpdater is responsible for updating the managedfields
34+
// in the object, updating the time of the operation as necessary. For
35+
// updates, it uses a hard-coded manager to detect if things have
36+
// changed, and swaps back the correct manager after the operation is
37+
// done.
38+
func NewManagedFieldsUpdater(fieldManager Manager) Manager {
39+
return &managedFieldsUpdater{
40+
fieldManager: fieldManager,
41+
}
42+
}
43+
44+
// Update implements Manager.
45+
func (f *managedFieldsUpdater) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) {
46+
self := "current-operation"
47+
object, managed, err := f.fieldManager.Update(liveObj, newObj, managed, self)
48+
if err != nil {
49+
return object, managed, err
50+
}
51+
52+
// If the current operation took any fields from anything, it means the object changed,
53+
// so update the timestamp of the managedFieldsEntry and merge with any previous updates from the same manager
54+
if vs, ok := managed.Fields()[self]; ok {
55+
delete(managed.Fields(), self)
56+
57+
managed.Times()[manager] = &metav1.Time{Time: time.Now().UTC()}
58+
if previous, ok := managed.Fields()[manager]; ok {
59+
managed.Fields()[manager] = fieldpath.NewVersionedSet(vs.Set().Union(previous.Set()), vs.APIVersion(), vs.Applied())
60+
} else {
61+
managed.Fields()[manager] = vs
62+
}
63+
}
64+
65+
return object, managed, nil
66+
}
67+
68+
// Apply implements Manager.
69+
func (f *managedFieldsUpdater) Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) {
70+
object, managed, err := f.fieldManager.Apply(liveObj, appliedObj, managed, fieldManager, force)
71+
if err != nil {
72+
return object, managed, err
73+
}
74+
managed.Times()[fieldManager] = &metav1.Time{Time: time.Now().UTC()}
75+
return object, managed, nil
76+
}

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

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222

2323
"k8s.io/apimachinery/pkg/api/errors"
2424
"k8s.io/apimachinery/pkg/api/meta"
25-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2625
"k8s.io/apimachinery/pkg/runtime"
2726
"k8s.io/apimachinery/pkg/runtime/schema"
2827
"k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal"
@@ -116,26 +115,12 @@ func (f *structuredMergeManager) Update(liveObj, newObj runtime.Object, managed
116115
apiVersion := fieldpath.APIVersion(f.groupVersion.String())
117116

118117
// TODO(apelisse) use the first return value when unions are implemented
119-
self := "current-operation"
120-
_, managedFields, err := f.updater.Update(liveObjTyped, newObjTyped, apiVersion, managed.Fields(), self)
118+
_, managedFields, err := f.updater.Update(liveObjTyped, newObjTyped, apiVersion, managed.Fields(), manager)
121119
if err != nil {
122120
return nil, nil, fmt.Errorf("failed to update ManagedFields: %v", err)
123121
}
124122
managed = internal.NewManaged(managedFields, managed.Times())
125123

126-
// If the current operation took any fields from anything, it means the object changed,
127-
// so update the timestamp of the managedFieldsEntry and merge with any previous updates from the same manager
128-
if vs, ok := managed.Fields()[self]; ok {
129-
delete(managed.Fields(), self)
130-
131-
managed.Times()[manager] = &metav1.Time{Time: time.Now().UTC()}
132-
if previous, ok := managed.Fields()[manager]; ok {
133-
managed.Fields()[manager] = fieldpath.NewVersionedSet(vs.Set().Union(previous.Set()), vs.APIVersion(), vs.Applied())
134-
} else {
135-
managed.Fields()[manager] = vs
136-
}
137-
}
138-
139124
return newObj, managed, nil
140125
}
141126

@@ -182,9 +167,6 @@ func (f *structuredMergeManager) Apply(liveObj, patchObj runtime.Object, managed
182167
}
183168
managed = internal.NewManaged(managedFields, managed.Times())
184169

185-
// Update the time in the managedFieldsEntry for this operation
186-
managed.Times()[manager] = &metav1.Time{Time: time.Now().UTC()}
187-
188170
newObj, err := f.typeConverter.TypedToObject(newObjTyped)
189171
if err != nil {
190172
return nil, nil, fmt.Errorf("failed to convert new typed object to object: %v", err)

0 commit comments

Comments
 (0)