Merge pull request #78738 from jennybuckley/apply-only

Don't start tracking field management until object has been applied

Kubernetes-commit: 0a784c5dc9b7843a642f913c9805c34ae3d4879d
This commit is contained in:
Kubernetes Publisher 2019-08-27 22:41:18 -07:00
commit 3b38fd7ad4
6 changed files with 59 additions and 10 deletions

4
Godeps/Godeps.json generated
View File

@ -456,11 +456,11 @@
},
{
"ImportPath": "k8s.io/apimachinery",
"Rev": "623fa2ae3bef"
"Rev": "f378a67c6af3"
},
{
"ImportPath": "k8s.io/client-go",
"Rev": "6ddd067b1589"
"Rev": "15739c3f8076"
},
{
"ImportPath": "k8s.io/component-base",

8
go.mod
View File

@ -49,8 +49,8 @@ require (
gopkg.in/yaml.v2 v2.2.2
gotest.tools v2.2.0+incompatible // indirect
k8s.io/api v0.0.0-20190826194732-9f642ccb7a30
k8s.io/apimachinery v0.0.0-20190827074644-623fa2ae3bef
k8s.io/client-go v0.0.0-20190826234919-6ddd067b1589
k8s.io/apimachinery v0.0.0-20190827074644-f378a67c6af3
k8s.io/client-go v0.0.0-20190827114928-15739c3f8076
k8s.io/component-base v0.0.0-20190823013255-e3d4ac5c99fb
k8s.io/klog v0.4.0
k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058
@ -66,7 +66,7 @@ replace (
golang.org/x/sys => golang.org/x/sys v0.0.0-20190209173611-3b5209105503
golang.org/x/text => golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db
k8s.io/api => k8s.io/api v0.0.0-20190826194732-9f642ccb7a30
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190827074644-623fa2ae3bef
k8s.io/client-go => k8s.io/client-go v0.0.0-20190826234919-6ddd067b1589
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190827074644-f378a67c6af3
k8s.io/client-go => k8s.io/client-go v0.0.0-20190827114928-15739c3f8076
k8s.io/component-base => k8s.io/component-base v0.0.0-20190823013255-e3d4ac5c99fb
)

4
go.sum
View File

@ -251,8 +251,8 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.0.0-20190826194732-9f642ccb7a30/go.mod h1:wKwR91YLONtsDxeJMXqvshPVeRU6ek8/1MfKoDBFqU0=
k8s.io/apimachinery v0.0.0-20190827074644-623fa2ae3bef/go.mod h1:EZoIMuAgG/4v58YL+bz0kqnivqupk28fKYxFCa5e6X8=
k8s.io/client-go v0.0.0-20190826234919-6ddd067b1589/go.mod h1:U5QdmHvUEX/pxUwYy9sEdX5FHTvKr1c1tPhKtTB9qAM=
k8s.io/apimachinery v0.0.0-20190827074644-f378a67c6af3/go.mod h1:EZoIMuAgG/4v58YL+bz0kqnivqupk28fKYxFCa5e6X8=
k8s.io/client-go v0.0.0-20190827114928-15739c3f8076/go.mod h1:ELXkYq8RZfSxYigoVWjPU8VmykoDq6DH0DQqG49jakE=
k8s.io/component-base v0.0.0-20190823013255-e3d4ac5c99fb/go.mod h1:JjVKThITdppqBfoB0Spaj0MZg9uIoTq4VI9VNyW0lqQ=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=

View File

@ -104,6 +104,10 @@ func (f *FieldManager) Update(liveObj, newObj runtime.Object, manager string) (r
return nil, fmt.Errorf("failed to decode managed fields: %v", err)
}
}
// if managed field is still empty, skip updating managed fields altogether
if len(managed.Fields) == 0 {
return newObj, nil
}
newObjVersioned, err := f.toVersioned(newObj)
if err != nil {
return nil, fmt.Errorf("failed to convert new object to proper version: %v", err)
@ -165,9 +169,11 @@ func (f *FieldManager) Update(liveObj, newObj runtime.Object, manager string) (r
// object and update the managed fields.
func (f *FieldManager) Apply(liveObj runtime.Object, patch []byte, fieldManager string, force bool) (runtime.Object, error) {
// If the object doesn't have metadata, apply isn't allowed.
if _, err := meta.Accessor(liveObj); err != nil {
accessor, err := meta.Accessor(liveObj)
if err != nil {
return nil, fmt.Errorf("couldn't get accessor: %v", err)
}
missingManagedFields := (len(accessor.GetManagedFields()) == 0)
managed, err := internal.DecodeObjectManagedFields(liveObj)
if err != nil {
@ -207,6 +213,23 @@ func (f *FieldManager) Apply(liveObj runtime.Object, patch []byte, fieldManager
}
apiVersion := fieldpath.APIVersion(f.groupVersion.String())
// if managed field is missing, create a single entry for all the fields
if missingManagedFields {
unknownManager, err := internal.BuildManagerIdentifier(&metav1.ManagedFieldsEntry{
Manager: "before-first-apply",
Operation: metav1.ManagedFieldsOperationUpdate,
APIVersion: f.groupVersion.String(),
})
if err != nil {
return nil, fmt.Errorf("failed to create manager for existing fields: %v", err)
}
unknownFieldSet, err := liveObjTyped.ToFieldSet()
if err != nil {
return nil, fmt.Errorf("failed to create fieldset for existing fields: %v", err)
}
managed.Fields[unknownManager] = fieldpath.NewVersionedSet(unknownFieldSet, apiVersion, false)
f.stripFields(managed.Fields, unknownManager)
}
newObjTyped, managedFields, err := f.updater.Apply(liveObjTyped, patchObjTyped, apiVersion, managed.Fields, manager, force)
if err != nil {
if conflicts, ok := err.(merge.Conflicts); ok {

View File

@ -25,6 +25,7 @@ import (
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@ -71,10 +72,34 @@ func TestFieldManagerCreation(t *testing.T) {
}
}
func TestUpdateOnlyDoesNotTrackManagedFields(t *testing.T) {
f := NewTestFieldManager()
liveObj := &corev1.Pod{}
updatedObj := liveObj.DeepCopy()
updatedObj.ObjectMeta.Labels = map[string]string{"k": "v"}
newObj, err := f.Update(liveObj, updatedObj, "fieldmanager_test")
if err != nil {
t.Fatalf("failed to update object: %v", err)
}
accessor, err := meta.Accessor(newObj)
if err != nil {
t.Fatalf("couldn't get accessor: %v", err)
}
if m := accessor.GetManagedFields(); len(m) != 0 {
t.Fatalf("managedFields were tracked on update only: %v", m)
}
}
func TestApplyStripsFields(t *testing.T) {
f := NewTestFieldManager()
obj := &corev1.Pod{}
obj.ObjectMeta.ManagedFields = []metav1.ManagedFieldsEntry{{}}
newObj, err := f.Apply(obj, []byte(`{
"apiVersion": "apps/v1",
@ -153,6 +178,7 @@ func TestApplyDoesNotStripLabels(t *testing.T) {
f := NewTestFieldManager()
obj := &corev1.Pod{}
obj.ObjectMeta.ManagedFields = []metav1.ManagedFieldsEntry{{}}
newObj, err := f.Apply(obj, []byte(`{
"apiVersion": "apps/v1",

View File

@ -421,7 +421,7 @@ func (p *applyPatcher) applyPatchToCurrentObject(obj runtime.Object) (runtime.Ob
func (p *applyPatcher) createNewObject() (runtime.Object, error) {
obj, err := p.creater.New(p.kind)
if err != nil {
return nil, fmt.Errorf("failed to create new object: %v", obj)
return nil, fmt.Errorf("failed to create new object: %v", err)
}
return p.applyPatchToCurrentObject(obj)
}