Only update managedFields on update if it already exists
Kubernetes-commit: 9a12e37a6dc28fd1d209eb84c210eb0723e6e38f
This commit is contained in:
parent
6101c6d99e
commit
350fef76f5
|
|
@ -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)
|
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)
|
newObjVersioned, err := f.toVersioned(newObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to convert new object to proper version: %v", err)
|
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.
|
// object and update the managed fields.
|
||||||
func (f *FieldManager) Apply(liveObj runtime.Object, patch []byte, fieldManager string, force bool) (runtime.Object, error) {
|
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 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)
|
return nil, fmt.Errorf("couldn't get accessor: %v", err)
|
||||||
}
|
}
|
||||||
|
missingManagedFields := (len(accessor.GetManagedFields()) == 0)
|
||||||
|
|
||||||
managed, err := internal.DecodeObjectManagedFields(liveObj)
|
managed, err := internal.DecodeObjectManagedFields(liveObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -207,6 +213,23 @@ func (f *FieldManager) Apply(liveObj runtime.Object, patch []byte, fieldManager
|
||||||
}
|
}
|
||||||
|
|
||||||
apiVersion := fieldpath.APIVersion(f.groupVersion.String())
|
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)
|
newObjTyped, managedFields, err := f.updater.Apply(liveObjTyped, patchObjTyped, apiVersion, managed.Fields, manager, force)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if conflicts, ok := err.(merge.Conflicts); ok {
|
if conflicts, ok := err.(merge.Conflicts); ok {
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import (
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"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/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
|
@ -75,6 +76,7 @@ func TestApplyStripsFields(t *testing.T) {
|
||||||
f := NewTestFieldManager()
|
f := NewTestFieldManager()
|
||||||
|
|
||||||
obj := &corev1.Pod{}
|
obj := &corev1.Pod{}
|
||||||
|
obj.ObjectMeta.ManagedFields = []metav1.ManagedFieldsEntry{{}}
|
||||||
|
|
||||||
newObj, err := f.Apply(obj, []byte(`{
|
newObj, err := f.Apply(obj, []byte(`{
|
||||||
"apiVersion": "apps/v1",
|
"apiVersion": "apps/v1",
|
||||||
|
|
@ -153,6 +155,7 @@ func TestApplyDoesNotStripLabels(t *testing.T) {
|
||||||
f := NewTestFieldManager()
|
f := NewTestFieldManager()
|
||||||
|
|
||||||
obj := &corev1.Pod{}
|
obj := &corev1.Pod{}
|
||||||
|
obj.ObjectMeta.ManagedFields = []metav1.ManagedFieldsEntry{{}}
|
||||||
|
|
||||||
newObj, err := f.Apply(obj, []byte(`{
|
newObj, err := f.Apply(obj, []byte(`{
|
||||||
"apiVersion": "apps/v1",
|
"apiVersion": "apps/v1",
|
||||||
|
|
|
||||||
|
|
@ -421,7 +421,7 @@ func (p *applyPatcher) applyPatchToCurrentObject(obj runtime.Object) (runtime.Ob
|
||||||
func (p *applyPatcher) createNewObject() (runtime.Object, error) {
|
func (p *applyPatcher) createNewObject() (runtime.Object, error) {
|
||||||
obj, err := p.creater.New(p.kind)
|
obj, err := p.creater.New(p.kind)
|
||||||
if err != nil {
|
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)
|
return p.applyPatchToCurrentObject(obj)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue