Commit 5190ace8 authored by Dawn Chen's avatar Dawn Chen Committed by GitHub

Merge pull request #37343 from ymqytw/revert_branch

Revert list of primitives fix
parents ead3cc8c 3cc294b1
......@@ -591,11 +591,11 @@ func patchResource(
if err != nil {
return nil, err
}
currentPatch, err := strategicpatch.CreateStrategicMergePatch(originalObjJS, currentObjectJS, versionedObj, strategicpatch.SMPatchVersionLatest)
currentPatch, err := strategicpatch.CreateStrategicMergePatch(originalObjJS, currentObjectJS, versionedObj)
if err != nil {
return nil, err
}
originalPatch, err := strategicpatch.CreateStrategicMergePatch(originalObjJS, originalPatchedObjJS, versionedObj, strategicpatch.SMPatchVersionLatest)
originalPatch, err := strategicpatch.CreateStrategicMergePatch(originalObjJS, originalPatchedObjJS, versionedObj)
if err != nil {
return nil, err
}
......
......@@ -213,7 +213,7 @@ func (tc *patchTestCase) Run(t *testing.T) {
continue
case api.StrategicMergePatchType:
patch, err = strategicpatch.CreateStrategicMergePatch(originalObjJS, changedJS, versionedObj, strategicpatch.SMPatchVersionLatest)
patch, err = strategicpatch.CreateStrategicMergePatch(originalObjJS, changedJS, versionedObj)
if err != nil {
t.Errorf("%s: unexpected error: %v", tc.name, err)
return
......
......@@ -244,8 +244,7 @@ func (e *eventLogger) eventObserve(newEvent *api.Event) (*api.Event, []byte, err
newData, _ := json.Marshal(event)
oldData, _ := json.Marshal(eventCopy2)
// Defaulting to SMPatchVersion_1_5 is safe, since we only update Count and LastTimestamp, and none of them has list of primitives
patch, err = strategicpatch.CreateStrategicMergePatch(oldData, newData, event, strategicpatch.SMPatchVersion_1_5)
patch, err = strategicpatch.CreateStrategicMergePatch(oldData, newData, event)
}
// record our new observation
......
......@@ -107,9 +107,8 @@ func (nsu *nodeStatusUpdater) UpdateNodeStatuses() error {
err)
}
// Defaulting to SMPatchVersion_1_5 is safe, since updateNodeStatus doesn't update any lists of primitives
patchBytes, err :=
strategicpatch.CreateStrategicMergePatch(oldData, newData, node, strategicpatch.SMPatchVersion_1_5)
strategicpatch.CreateStrategicMergePatch(oldData, newData, node)
if err != nil {
return fmt.Errorf(
"failed to CreateStrategicMergePatch for node %q. %v",
......
......@@ -191,11 +191,9 @@ go_test(
"//pkg/runtime/serializer/streaming:go_default_library",
"//pkg/types:go_default_library",
"//pkg/util/intstr:go_default_library",
"//pkg/util/strategicpatch:go_default_library",
"//pkg/util/strings:go_default_library",
"//pkg/util/term:go_default_library",
"//pkg/util/wait:go_default_library",
"//pkg/version:go_default_library",
"//pkg/watch:go_default_library",
"//pkg/watch/versioned:go_default_library",
"//vendor:github.com/spf13/cobra",
......
......@@ -239,8 +239,7 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro
if err != nil {
return err
}
// Defaulting to SMPatchVersion_1_5 is safe, since it just update the annotation which is a map[string]string
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, obj, strategicpatch.SMPatchVersion_1_5)
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, obj)
createdPatch := err == nil
if err != nil {
glog.V(2).Infof("couldn't compute patch: %v", err)
......
......@@ -24,6 +24,8 @@ import (
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/client/restclient/fake"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/runtime"
......@@ -392,7 +394,7 @@ func TestAnnotateErrors(t *testing.T) {
f, tf, _, _ := cmdtesting.NewAPIFactory()
tf.Printer = &testPrinter{}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &registered.GroupOrDie(api.GroupName).GroupVersion}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdAnnotate(f, buf)
......@@ -430,12 +432,6 @@ func TestAnnotateObject(t *testing.T) {
switch req.Method {
case "GET":
switch req.URL.Path {
case "/version":
resp, err := genResponseWithJsonEncodedBody(serverVersion_1_5_0)
if err != nil {
t.Fatalf("error: failed to generate server version response: %#v\n", serverVersion_1_5_0)
}
return resp, nil
case "/namespaces/test/pods/foo":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[0])}, nil
default:
......@@ -457,7 +453,7 @@ func TestAnnotateObject(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &registered.GroupOrDie(api.GroupName).GroupVersion}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdAnnotate(f, buf)
......@@ -486,12 +482,6 @@ func TestAnnotateObjectFromFile(t *testing.T) {
switch req.Method {
case "GET":
switch req.URL.Path {
case "/version":
resp, err := genResponseWithJsonEncodedBody(serverVersion_1_5_0)
if err != nil {
t.Fatalf("error: failed to generate server version response: %#v\n", serverVersion_1_5_0)
}
return resp, nil
case "/namespaces/test/replicationcontrollers/cassandra":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[0])}, nil
default:
......@@ -513,7 +503,7 @@ func TestAnnotateObjectFromFile(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &registered.GroupOrDie(api.GroupName).GroupVersion}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdAnnotate(f, buf)
......@@ -542,7 +532,7 @@ func TestAnnotateLocal(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &registered.GroupOrDie(api.GroupName).GroupVersion}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdAnnotate(f, buf)
......@@ -572,12 +562,6 @@ func TestAnnotateMultipleObjects(t *testing.T) {
switch req.Method {
case "GET":
switch req.URL.Path {
case "/version":
resp, err := genResponseWithJsonEncodedBody(serverVersion_1_5_0)
if err != nil {
t.Fatalf("error: failed to generate server version response: %#v\n", serverVersion_1_5_0)
}
return resp, nil
case "/namespaces/test/pods":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, pods)}, nil
default:
......@@ -601,7 +585,7 @@ func TestAnnotateMultipleObjects(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &registered.GroupOrDie(api.GroupName).GroupVersion}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdAnnotate(f, buf)
......
......@@ -531,23 +531,13 @@ 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.
patch, err := strategicpatch.CreateThreeWayMergePatch(original, modified, current, versionedObject, p.overwrite)
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 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:"
return nil, cmdutil.AddSourceToErr(fmt.Sprintf(format, original, modified, current), source, err)
}
_, err = p.helper.Patch(namespace, name, api.StrategicMergePatchType, patch)
}
return patch, err
}
......
......@@ -23,7 +23,6 @@ import (
"io/ioutil"
"net/http"
"os"
"strings"
"testing"
"github.com/spf13/cobra"
......@@ -38,7 +37,6 @@ import (
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/strategicpatch"
)
func TestApplyExtraArgsFail(t *testing.T) {
......@@ -144,58 +142,6 @@ func readAndAnnotateService(t *testing.T, filename string) (string, []byte) {
return annotateRuntimeObject(t, svc1, svc2, "Service")
}
func setFinalizersRuntimeObject(t *testing.T, originalObj, currentObj runtime.Object) (string, []byte) {
originalAccessor, err := meta.Accessor(originalObj)
if err != nil {
t.Fatal(err)
}
originalFinalizers := []string{"a/a"}
originalAccessor.SetFinalizers(originalFinalizers)
original, err := runtime.Encode(testapi.Default.Codec(), originalObj)
if err != nil {
t.Fatal(err)
}
currentAccessor, err := meta.Accessor(currentObj)
if err != nil {
t.Fatal(err)
}
currentFinalizers := []string{"b/b"}
currentAccessor.SetFinalizers(currentFinalizers)
currentAnnotations := currentAccessor.GetAnnotations()
if currentAnnotations == nil {
currentAnnotations = make(map[string]string)
}
currentAnnotations[annotations.LastAppliedConfigAnnotation] = string(original)
currentAccessor.SetAnnotations(currentAnnotations)
current, err := runtime.Encode(testapi.Default.Codec(), currentObj)
if err != nil {
t.Fatal(err)
}
return currentAccessor.GetName(), current
}
func readAndSetFinalizersReplicationController(t *testing.T, filename string) (string, []byte) {
rc1 := readReplicationControllerFromFile(t, filename)
rc2 := readReplicationControllerFromFile(t, filename)
name, rcBytes := setFinalizersRuntimeObject(t, rc1, rc2)
return name, rcBytes
}
func isSMPatchVersion_1_5(t *testing.T, req *http.Request) bool {
patch, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Fatal(err)
}
// SMPatchVersion_1_5 patch should has string "mergeprimitiveslist"
return strings.Contains(string(patch), strategicpatch.MergePrimitivesListDirective)
}
func validatePatchApplication(t *testing.T, req *http.Request) {
patch, err := ioutil.ReadAll(req.Body)
if err != nil {
......@@ -242,12 +188,6 @@ func TestApplyObject(t *testing.T) {
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/version" && m == "GET":
resp, err := genResponseWithJsonEncodedBody(serverVersion_1_5_0)
if err != nil {
t.Fatalf("error: failed to generate server version response: %#v\n", serverVersion_1_5_0)
}
return resp, nil
case p == pathRC && m == "GET":
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
......@@ -262,62 +202,6 @@ func TestApplyObject(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply(f, buf)
cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
// uses the name from the file, not the response
expectRC := "replicationcontroller/" + nameRC + "\n"
if buf.String() != expectRC {
t.Fatalf("unexpected output: %s\nexpected: %s", buf.String(), expectRC)
}
}
func TestApplyRetryWithSMPatchVersion_1_5(t *testing.T) {
initTestErrorHandler(t)
nameRC, currentRC := readAndSetFinalizersReplicationController(t, filenameRC)
pathRC := "/namespaces/test/replicationcontrollers/" + nameRC
firstPatch := true
retry := false
f, tf, _, ns := cmdtesting.NewAPIFactory()
tf.Printer = &testPrinter{}
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == pathRC && m == "GET":
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
case p == pathRC && m == "PATCH":
if firstPatch {
if !isSMPatchVersion_1_5(t, req) {
t.Fatalf("apply didn't try to send SMPatchVersion_1_5 for the first time")
}
firstPatch = false
statusErr := kubeerr.NewInternalError(fmt.Errorf("Server encountered internal error."))
bodyBytes, _ := json.Marshal(statusErr)
bodyErr := ioutil.NopCloser(bytes.NewReader(bodyBytes))
return &http.Response{StatusCode: http.StatusInternalServerError, Header: defaultHeader(), Body: bodyErr}, nil
}
retry = true
if isSMPatchVersion_1_5(t, req) {
t.Fatalf("apply didn't try to send SMPatchVersion_1_0 after SMPatchVersion_1_5 patch encounter an Internal Error (500)")
}
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply(f, buf)
......@@ -325,10 +209,6 @@ func TestApplyRetryWithSMPatchVersion_1_5(t *testing.T) {
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
if !retry {
t.Fatalf("apply didn't retry when get Internal Error (500)")
}
// uses the name from the file, not the response
expectRC := "replicationcontroller/" + nameRC + "\n"
if buf.String() != expectRC {
......@@ -350,12 +230,6 @@ func TestApplyRetry(t *testing.T) {
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/version" && m == "GET":
resp, err := genResponseWithJsonEncodedBody(serverVersion_1_5_0)
if err != nil {
t.Fatalf("error: failed to generate server version response: %#v\n", serverVersion_1_5_0)
}
return resp, nil
case p == pathRC && m == "GET":
getCount++
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
......@@ -379,7 +253,6 @@ func TestApplyRetry(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply(f, buf)
......@@ -409,12 +282,6 @@ func TestApplyNonExistObject(t *testing.T) {
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/version" && m == "GET":
resp, err := genResponseWithJsonEncodedBody(serverVersion_1_5_0)
if err != nil {
t.Fatalf("error: failed to generate server version response: %#v\n", serverVersion_1_5_0)
}
return resp, nil
case p == "/api/v1/namespaces/test" && m == "GET":
return &http.Response{StatusCode: 404, Header: defaultHeader(), Body: ioutil.NopCloser(bytes.NewReader(nil))}, nil
case p == pathNameRC && m == "GET":
......@@ -429,7 +296,6 @@ func TestApplyNonExistObject(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply(f, buf)
......@@ -465,12 +331,6 @@ func testApplyMultipleObjects(t *testing.T, asList bool) {
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/version" && m == "GET":
resp, err := genResponseWithJsonEncodedBody(serverVersion_1_5_0)
if err != nil {
t.Fatalf("error: failed to generate server version response: %#v\n", serverVersion_1_5_0)
}
return resp, nil
case p == pathRC && m == "GET":
bodyRC := ioutil.NopCloser(bytes.NewReader(currentRC))
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: bodyRC}, nil
......@@ -492,7 +352,6 @@ func testApplyMultipleObjects(t *testing.T, asList bool) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply(f, buf)
......
......@@ -39,13 +39,8 @@ import (
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/strings"
"k8s.io/kubernetes/pkg/version"
)
var serverVersion_1_5_0 = version.Info{
GitVersion: "v1.5.0",
}
func initTestErrorHandler(t *testing.T) {
cmdutil.BehaviorOnFatal(func(str string, code int) {
t.Errorf("Error running command (exit code %d): %s", code, str)
......
......@@ -291,7 +291,7 @@ func runEdit(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args
switch editMode {
case NormalEditMode:
err = visitToPatch(originalObj, updates, f, mapper, resourceMapper, encoder, out, errOut, defaultVersion, &results, file)
err = visitToPatch(originalObj, updates, mapper, resourceMapper, encoder, out, errOut, defaultVersion, &results, file)
case EditBeforeCreateMode:
err = visitToCreate(updates, mapper, resourceMapper, out, errOut, defaultVersion, &results, file)
default:
......@@ -415,15 +415,7 @@ func getMapperAndResult(f cmdutil.Factory, args []string, options *resource.File
return mapper, resourceMapper, r, cmdNamespace, err
}
func visitToPatch(originalObj runtime.Object, updates *resource.Info,
f cmdutil.Factory,
mapper meta.RESTMapper, resourceMapper *resource.Mapper,
encoder runtime.Encoder,
out, errOut io.Writer,
defaultVersion unversioned.GroupVersion,
results *editResults,
file string) error {
func visitToPatch(originalObj runtime.Object, updates *resource.Info, mapper meta.RESTMapper, resourceMapper *resource.Mapper, encoder runtime.Encoder, out, errOut io.Writer, defaultVersion unversioned.GroupVersion, results *editResults, file string) error {
patchVisitor := resource.NewFlattenListVisitor(updates, resourceMapper)
err := patchVisitor.Visit(func(info *resource.Info, incomingErr error) error {
currOriginalObj := originalObj
......@@ -486,8 +478,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.
patch, err := strategicpatch.CreateTwoWayMergePatch(originalJS, editedJS, currOriginalObj, preconditions...)
if err != nil {
glog.V(4).Infof("Unable to calculate diff, no merge is possible: %v", err)
if strategicpatch.IsPreconditionFailed(err) {
......@@ -499,20 +490,8 @@ 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 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)
}
if err != nil {
fmt.Fprintln(out, results.addError(err, info))
return nil
}
fmt.Fprintln(out, results.addError(err, info))
return nil
}
info.Refresh(patched, true)
cmdutil.PrintSuccess(mapper, false, out, info.Mapping.Resource, info.Name, false, "edited")
......
......@@ -246,8 +246,7 @@ func (o *LabelOptions) RunLabel(f cmdutil.Factory, cmd *cobra.Command) error {
if !reflect.DeepEqual(oldData, newData) {
dataChangeMsg = "labeled"
}
// Defaulting to SMPatchVersion_1_5 is safe, since we only update labels and change cause, and none of them has list of primitives
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, obj, strategicpatch.SMPatchVersion_1_5)
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, obj)
createdPatch := err == nil
if err != nil {
glog.V(2).Infof("couldn't compute patch: %v", err)
......
......@@ -354,12 +354,6 @@ func TestLabelForResourceFromFile(t *testing.T) {
switch req.Method {
case "GET":
switch req.URL.Path {
case "/version":
resp, err := genResponseWithJsonEncodedBody(serverVersion_1_5_0)
if err != nil {
t.Fatalf("error: failed to generate server version response: %#v\n", serverVersion_1_5_0)
}
return resp, nil
case "/namespaces/test/replicationcontrollers/cassandra":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[0])}, nil
default:
......@@ -381,7 +375,7 @@ func TestLabelForResourceFromFile(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &registered.GroupOrDie(api.GroupName).GroupVersion}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdLabel(f, buf)
......@@ -443,12 +437,6 @@ func TestLabelMultipleObjects(t *testing.T) {
switch req.Method {
case "GET":
switch req.URL.Path {
case "/version":
resp, err := genResponseWithJsonEncodedBody(serverVersion_1_5_0)
if err != nil {
t.Fatalf("error: failed to generate server version response: %#v\n", serverVersion_1_5_0)
}
return resp, nil
case "/namespaces/test/pods":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, pods)}, nil
default:
......@@ -472,7 +460,7 @@ func TestLabelMultipleObjects(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
tf.ClientConfig = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &registered.GroupOrDie(api.GroupName).GroupVersion}}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdLabel(f, buf)
......
......@@ -34,12 +34,6 @@ func TestPatchObject(t *testing.T) {
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/version" && m == "GET":
resp, err := genResponseWithJsonEncodedBody(serverVersion_1_5_0)
if err != nil {
t.Fatalf("error: failed to generate server version response: %#v\n", serverVersion_1_5_0)
}
return resp, nil
case p == "/namespaces/test/services/frontend" && (m == "PATCH" || m == "GET"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &svc.Items[0])}, nil
default:
......@@ -49,7 +43,6 @@ func TestPatchObject(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdPatch(f, buf)
......@@ -73,12 +66,6 @@ func TestPatchObjectFromFile(t *testing.T) {
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/version" && m == "GET":
resp, err := genResponseWithJsonEncodedBody(serverVersion_1_5_0)
if err != nil {
t.Fatalf("error: failed to generate server version response: %#v\n", serverVersion_1_5_0)
}
return resp, nil
case p == "/namespaces/test/services/frontend" && (m == "PATCH" || m == "GET"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &svc.Items[0])}, nil
default:
......@@ -88,7 +75,6 @@ func TestPatchObjectFromFile(t *testing.T) {
}),
}
tf.Namespace = "test"
tf.ClientConfig = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdPatch(f, buf)
......
......@@ -32,7 +32,6 @@ go_library(
"//pkg/runtime:go_default_library",
"//pkg/util/errors:go_default_library",
"//pkg/util/interrupt:go_default_library",
"//pkg/util/strategicpatch:go_default_library",
"//pkg/watch:go_default_library",
"//vendor:github.com/renstrom/dedent",
"//vendor:github.com/spf13/cobra",
......
......@@ -31,7 +31,6 @@ import (
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/runtime"
utilerrors "k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/strategicpatch"
)
// PauseConfig is the start of the data required to perform the operation. As new fields are added, add them here instead of
......@@ -39,7 +38,6 @@ import (
type PauseConfig struct {
resource.FilenameOptions
f cmdutil.Factory
Pauser func(info *resource.Info) (bool, error)
Mapper meta.RESTMapper
Typer runtime.ObjectTyper
......@@ -101,7 +99,6 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, out i
return cmdutil.UsageError(cmd, cmd.Use)
}
o.f = f
o.Mapper, o.Typer = f.Object()
o.Encoder = f.JSONEncoder()
......@@ -135,8 +132,7 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, out i
func (o PauseConfig) RunPause() error {
allErrs := []error{}
// Defaulting to SMPatchVersion_1_5 is safe, since Pauser only update a boolean variable
for _, patch := range set.CalculatePatches(o.f, o.Infos, o.Encoder, strategicpatch.SMPatchVersion_1_5, o.Pauser) {
for _, patch := range set.CalculatePatches(o.Infos, o.Encoder, o.Pauser) {
info := patch.Info
if patch.Err != nil {
allErrs = append(allErrs, fmt.Errorf("error: %s %q %v", info.Mapping.Resource, info.Name, patch.Err))
......
......@@ -31,7 +31,6 @@ import (
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/runtime"
utilerrors "k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/strategicpatch"
)
// ResumeConfig is the start of the data required to perform the operation. As new fields are added, add them here instead of
......@@ -39,7 +38,6 @@ import (
type ResumeConfig struct {
resource.FilenameOptions
f cmdutil.Factory
Resumer func(object *resource.Info) (bool, error)
Mapper meta.RESTMapper
Typer runtime.ObjectTyper
......@@ -99,7 +97,6 @@ func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, out
return cmdutil.UsageError(cmd, cmd.Use)
}
o.f = f
o.Mapper, o.Typer = f.Object()
o.Encoder = f.JSONEncoder()
......@@ -139,8 +136,7 @@ func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, out
func (o ResumeConfig) RunResume() error {
allErrs := []error{}
// Defaulting to SMPatchVersion_1_5 is safe, since Resumer only update a boolean variable
for _, patch := range set.CalculatePatches(o.f, o.Infos, o.Encoder, strategicpatch.SMPatchVersion_1_5, o.Resumer) {
for _, patch := range set.CalculatePatches(o.Infos, o.Encoder, o.Resumer) {
info := patch.Info
if patch.Err != nil {
......
......@@ -23,7 +23,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/strategicpatch"
......@@ -61,7 +61,7 @@ func handlePodUpdateError(out io.Writer, err error, resource string) {
return
}
} else {
if ok := cmdutil.PrintErrorWithCauses(err, out); ok {
if ok := kcmdutil.PrintErrorWithCauses(err, out); ok {
return
}
}
......@@ -120,10 +120,7 @@ type Patch struct {
// CalculatePatches calls the mutation function on each provided info object, and generates a strategic merge patch for
// the changes in the object. Encoder must be able to encode the info into the appropriate destination type. If mutateFn
// returns false, the object is not included in the final list of patches.
// If local is true, it will be default to use SMPatchVersionLatest to calculate a patch without contacting the server to
// get the server supported SMPatchVersion. If you are using a patch's Patch field generated in local mode, be careful.
// If local is false, it will talk to the server to check which StategicMergePatchVersion to use.
func CalculatePatches(f cmdutil.Factory, infos []*resource.Info, encoder runtime.Encoder, smPatchVersion strategicpatch.StrategicMergePatchVersion, mutateFn func(*resource.Info) (bool, error)) []*Patch {
func CalculatePatches(infos []*resource.Info, encoder runtime.Encoder, mutateFn func(*resource.Info) (bool, error)) []*Patch {
var patches []*Patch
for _, info := range infos {
patch := &Patch{Info: info}
......@@ -159,7 +156,7 @@ func CalculatePatches(f cmdutil.Factory, infos []*resource.Info, encoder runtime
continue
}
patch.Patch, patch.Err = strategicpatch.CreateTwoWayMergePatch(patch.Before, patch.After, versioned, smPatchVersion)
patch.Patch, patch.Err = strategicpatch.CreateTwoWayMergePatch(patch.Before, patch.After, versioned)
}
return patches
}
......@@ -28,7 +28,6 @@ import (
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/runtime"
utilerrors "k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/strategicpatch"
)
// ImageOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
......@@ -36,7 +35,6 @@ import (
type ImageOptions struct {
resource.FilenameOptions
f cmdutil.Factory
Mapper meta.RESTMapper
Typer runtime.ObjectTyper
Infos []*resource.Info
......@@ -110,7 +108,6 @@ func NewCmdImage(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
}
func (o *ImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.f = f
o.Mapper, o.Typer = f.Object()
o.UpdatePodSpecForObject = f.UpdatePodSpecForObject
o.Encoder = f.JSONEncoder()
......@@ -164,8 +161,8 @@ func (o *ImageOptions) Validate() error {
func (o *ImageOptions) Run() error {
allErrs := []error{}
// Defauting to SMPatchVersion_1_5, since the func passed in doesn't update any lists of primitive
patches := CalculatePatches(o.f, o.Infos, o.Encoder, strategicpatch.SMPatchVersion_1_5, func(info *resource.Info) (bool, error) {
patches := CalculatePatches(o.Infos, o.Encoder, func(info *resource.Info) (bool, error) {
transformed := false
_, err := o.UpdatePodSpecForObject(info.Object, func(spec *api.PodSpec) error {
for name, image := range o.ContainerImages {
......
......@@ -31,7 +31,6 @@ import (
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/runtime"
utilerrors "k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/strategicpatch"
)
var (
......@@ -61,7 +60,6 @@ var (
type ResourcesOptions struct {
resource.FilenameOptions
f cmdutil.Factory
Mapper meta.RESTMapper
Typer runtime.ObjectTyper
Infos []*resource.Info
......@@ -126,7 +124,6 @@ func NewCmdResources(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.
}
func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.f = f
o.Mapper, o.Typer = f.Object()
o.UpdatePodSpecForObject = f.UpdatePodSpecForObject
o.Encoder = f.JSONEncoder()
......@@ -177,8 +174,7 @@ func (o *ResourcesOptions) Validate() error {
func (o *ResourcesOptions) Run() error {
allErrs := []error{}
// Defauting to SMPatchVersion_1_5, since the func passed in doesn't update any lists of primitive
patches := CalculatePatches(o.f, o.Infos, o.Encoder, strategicpatch.SMPatchVersion_1_5, func(info *resource.Info) (bool, error) {
patches := CalculatePatches(o.Infos, o.Encoder, func(info *resource.Info) (bool, error) {
transformed := false
_, err := o.UpdatePodSpecForObject(info.Object, func(spec *api.PodSpec) error {
containers, _ := selectContainers(spec.Containers, o.ContainerSelector)
......
......@@ -343,8 +343,7 @@ func (o TaintOptions) RunTaint() error {
if err != nil {
return err
}
// Defaulting to SMPatchVersion_1_5 is safe, since we don't update list of primitives.
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, obj, strategicpatch.SMPatchVersion_1_5)
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, obj)
createdPatch := err == nil
if err != nil {
glog.V(2).Infof("couldn't compute patch: %v", err)
......
......@@ -252,6 +252,7 @@ func TestTaint(t *testing.T) {
for _, test := range tests {
oldNode, expectNewNode := generateNodeAndTaintedNode(test.oldTaints, test.newTaints)
new_node := &api.Node{}
tainted := false
f, tf, codec, ns := cmdtesting.NewAPIFactory()
......@@ -261,12 +262,6 @@ func TestTaint(t *testing.T) {
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
m := &MyReq{req}
switch {
case m.isFor("GET", "/version"):
resp, err := genResponseWithJsonEncodedBody(serverVersion_1_5_0)
if err != nil {
t.Fatalf("error: failed to generate server version response: %#v\n", serverVersion_1_5_0)
}
return resp, nil
case m.isFor("GET", "/nodes/node-name"):
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, oldNode)}, nil
case m.isFor("PATCH", "/nodes/node-name"), m.isFor("PUT", "/nodes/node-name"):
......
......@@ -427,12 +427,8 @@ func (f *fakeAPIFactory) UnstructuredObject() (meta.RESTMapper, runtime.ObjectTy
return cmdutil.NewShortcutExpander(mapper, nil), typer, nil
}
func (f *fakeAPIFactory) Decoder(toInternal bool) runtime.Decoder {
if toInternal {
return api.Codecs.UniversalDecoder()
} else {
return api.Codecs.UniversalDeserializer()
}
func (f *fakeAPIFactory) Decoder(bool) runtime.Decoder {
return testapi.Default.Codec()
}
func (f *fakeAPIFactory) JSONEncoder() runtime.Encoder {
......
......@@ -533,8 +533,7 @@ func ChangeResourcePatch(info *resource.Info, changeCause string) ([]byte, error
if err != nil {
return nil, err
}
// Using SMPatchVersion_1_5, since RecordChangeCause() just update the annotation which is a map[string]string
return strategicpatch.CreateTwoWayMergePatch(oldData, newData, info.Object, strategicpatch.SMPatchVersion_1_5)
return strategicpatch.CreateTwoWayMergePatch(oldData, newData, info.Object)
}
// containsChangeCause checks if input resource info contains change-cause annotation.
......
apiVersion: v1
kind: ReplicationController
metadata:
finalizers:
- b/b
name: test-rc
labels:
name: test-rc
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment