Code change:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: CRD: Existing object: New object: says: If this is a problem with the new object definition rather than a bug with , I'd expect a better error message. (The new object looks fine to me, though; it should be identical to the old object.) What you expected to happen: I expected the object to be updated without an error. How to reproduce it (as minimally and precisely as possible): See description. Anything else we need to know?: Environment: Kubernetes version (use ):Cloud provider or hardware configuration**: GCE OS (e.g. from /etc/os-release): CentOS Linux 7.4 (1708) Kernel (e.g. ): Linux master-head-1 4.13.4- SMP Wed Sep 27 13:32:23 EDT 2017 x8664 x8664 x8664 GNU/Linux Install tools: Custom scripts Others:
/sig api-machinery
Are you able to reproduce this everytime? I am able to use apply normally with your example.
I can reliably reproduce it if the annotation exists: If I use to remove the annotation, then it works the first time but fails thereafter:
This is happening for other CRDs as well (Prometheus Operator ServiceMonitors). If I apply a ServiceMonitor CRD 3 times: If I remove the annotation or replace the object () then I can work around the issue.
Seems any CRD is affected; the CRD used by our are also not working: This has completely broken our CI/CD workflow... unfortunately we'd already completed the TPR-CRD migration for the 1.8 upgrade before noticing this problem, so we can't really downgrade. How safe is as an alternative to ? It still generates an update event for watchers, not a delete/recreate, right?
It looks like something going wrong during the patching. After using changes from , I get this: /cc /area third-party-resource
But uses json merge patch and not strategic merge patch for custom resources:
I was able to reproduce this in v1.8.0 with the original manifests at the top. As found, it only happens on the 3rd execution: It also seems to only happen when the ought to be a no-op. If I change something in the IPPool spec, works once more, then starts failing again. When the is a no-op, the PATCH request body generated by looks like this: When the is NOT a no-op, the PATCH request body looks like this:
There's a typo in the code generating the error messages for both and : They should be calling instead of . When I fix that, the error message becomes:
I can reproduce this without , just by doing a no-op twice:
The same issue affects v1.7.8 (tested on GKE)
Same issue with v1.8.1
This just fix the error message: But it doesn't fix the issue
Still investigating the issue but I noticed that when we do a no-op patch for native resources, we get a "not patched" response. However, for non-native resources, it still tries to patch it (and bumps the resourceVersion too).
I don't konwn whether this is a issue, I can't do strategic merge patch to CRD. When I run , --type=merge must be passed.
We should be able to apply strategic merge patch to CRDs. However, we can't apply strategic merge to CRs because we're missing the metadata about how to handle each field for the strategic merge patch. Unfortunately, this error is occuring even with . :(
/assign
do you know if the fix fir this will make it to 1.8.3
hopefully yes, this should be merged soon.
thanks! this has been a blocker for us to upgrade to 1.8
can you confirm this is completely fixed? The PR writes "partial fix".
Now we can't reproduce this issue with the method descripted above. I still need some I extra time to research it. Maybe we can close this one. If I can reproduce the issue in another way, I can open another issue with new situation.
If it's not fixed, let's keep it open.
Fun, a fork closing issues.
From Then I think we can officially close this.
(the fix is merged into release-1.8, but after v1.8.4-beta.0)
what stable release of k8s will this be in? 1.8.4 or 1.8.5?
Is there an update for this?
looks like it was merged here: but did not make it into 1.8.4, might make it into 1.8.5

Related discussion:
text: } } <ins> func TestPatch(t *testing.T) { stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } defer close(stopCh) noxuDefinition := testserver.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.ClusterScoped) noxuVersionClient, err := testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) if err != nil { t.Fatal(err) } ns := "not-the-default" noxuNamespacedResourceClient := noxuVersionClient.Resource(&metav1.APIResource{ Name:       noxuDefinition.Spec.Names.Plural, Namespaced: true, }, ns) noxuInstanceToCreate := testserver.NewNoxuInstance(ns, "foo") createdNoxuInstance, err := noxuNamespacedResourceClient.Create(noxuInstanceToCreate) if err != nil { t.Fatal(err) } patch := []byte(`{"num": {"num2":999}}`) createdNoxuInstance, err = noxuNamespacedResourceClient.Patch("foo", types.MergePatchType, patch) if err != nil { t.Fatalf("unexpected error: %v", err) } // a patch with no change createdNoxuInstance, err = noxuNamespacedResourceClient.Patch("foo", types.MergePatchType, patch) if err != nil { t.Fatalf("unexpected error: %v", err) } // an empty patch createdNoxuInstance, err = noxuNamespacedResourceClient.Patch("foo", types.MergePatchType, []byte(`{}`)) if err != nil { t.Fatalf("unexpected error: %v", err) } originalJSON, err := runtime.Encode(unstructured.UnstructuredJSONScheme, createdNoxuInstance) if err != nil { t.Fatalf("unexpected error: %v", err) } gottenNoxuInstance, err := runtime.Decode(unstructured.UnstructuredJSONScheme, originalJSON) if err != nil { t.Fatalf("unexpected error: %v", err) } // Check if int is preserved. unstructuredObj := gottenNoxuInstance.(*unstructured.Unstructured).Object num := unstructuredObj["num"].(map[string]interface{}) num1 := num["num1"].(int64) num2 := num["num2"].(int64) if num1 != 9223372036854775807 || num2 != 999 { t.Errorf("Expected %v, got %v, %v", `9223372036854775807, 999`, num1, num2) } } </ins> func TestCrossNamespaceListWatch(t *testing.T) { stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil {