diff --git a/pkg/kubectl/cmd/apply.go b/pkg/kubectl/cmd/apply.go index 584ccaf9e09..620e68c5147 100644 --- a/pkg/kubectl/cmd/apply.go +++ b/pkg/kubectl/cmd/apply.go @@ -532,13 +532,15 @@ func (p *patcher) patchSimple(obj runtime.Object, modified []byte, source, names // Compute a three way strategic merge patch to send to server. patch, err := strategicpatch.CreateThreeWayMergePatch(original, modified, current, versionedObject, p.overwrite, strategicpatch.SMPatchVersion_1_5) + // If creating a patch fails, retrying with SMPatchVersion_1_0 is not helpful. So we return the error. if err != nil { format := "creating patch with:\noriginal:\n%s\nmodified:\n%s\ncurrent:\n%s\nfor:" return nil, cmdutil.AddSourceToErr(fmt.Sprintf(format, original, modified, current), source, err) } _, err = p.helper.Patch(namespace, name, api.StrategicMergePatchType, patch) - if err != nil { - // Retry SMPatchVersion_1_0 when applying the SMPatchVersion_1_5 patch + if errors.IsInternalError(err) { + // Retry SMPatchVersion_1_0 when applying the SMPatchVersion_1_5 patch returns an Internal Error (500). + // Because the failure may be due to the server not supporting the SMPatchVersion_1_5 patch. patch, err = strategicpatch.CreateThreeWayMergePatch(original, modified, current, versionedObject, p.overwrite, strategicpatch.SMPatchVersion_1_0) if err != nil { format := "creating patch with:\noriginal:\n%s\nmodified:\n%s\ncurrent:\n%s\nfor:" diff --git a/pkg/kubectl/cmd/edit.go b/pkg/kubectl/cmd/edit.go index 14814110018..36bc46e7956 100644 --- a/pkg/kubectl/cmd/edit.go +++ b/pkg/kubectl/cmd/edit.go @@ -487,6 +487,7 @@ func visitToPatch(originalObj runtime.Object, updates *resource.Info, preconditions := []strategicpatch.PreconditionFunc{strategicpatch.RequireKeyUnchanged("apiVersion"), strategicpatch.RequireKeyUnchanged("kind"), strategicpatch.RequireMetadataKeyUnchanged("name")} patch, err := strategicpatch.CreateTwoWayMergePatch(originalJS, editedJS, currOriginalObj, strategicpatch.SMPatchVersion_1_5, preconditions...) + // If creating a patch fails, retrying with SMPatchVersion_1_0 is not helpful. So we return the error. if err != nil { glog.V(4).Infof("Unable to calculate diff, no merge is possible: %v", err) if strategicpatch.IsPreconditionFailed(err) { @@ -498,13 +499,16 @@ func visitToPatch(originalObj runtime.Object, updates *resource.Info, results.version = defaultVersion patched, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, api.StrategicMergePatchType, patch) if err != nil { - // Retry SMPatchVersion_1_0 when applying the SMPatchVersion_1_5 patch - patch, err = strategicpatch.CreateTwoWayMergePatch(originalJS, editedJS, currOriginalObj, strategicpatch.SMPatchVersion_1_0) - if err != nil { - glog.V(4).Infof("Unable to calculate diff, no merge is possible: %v", err) - return err + // Retry SMPatchVersion_1_0 when applying the SMPatchVersion_1_5 patch returns an Internal Error (500). + // Because the failure may be due to the server not supporting the SMPatchVersion_1_5 patch. + if errors.IsInternalError(err) { + patch, err = strategicpatch.CreateTwoWayMergePatch(originalJS, editedJS, currOriginalObj, strategicpatch.SMPatchVersion_1_0) + if err != nil { + glog.V(4).Infof("Unable to calculate diff, no merge is possible: %v", err) + return err + } + patched, err = resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, api.StrategicMergePatchType, patch) } - patched, err = resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, api.StrategicMergePatchType, patch) if err != nil { fmt.Fprintln(out, results.addError(err, info)) return nil