Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix original object mutation on patch retry #43871

Merged
merged 1 commit into from
Apr 6, 2017

Conversation

liggitt
Copy link
Member

@liggitt liggitt commented Mar 30, 2017

When applying a patch, the original state of the object and patch are captured so that retries can determine if an overlapping update was made to the object, and the patch API call should abort with a conflict.

However, the strategicPatchObject -> applyPatchToObject -> StrategicMergeMapPatch -> mergeMap call mutates both the original object map and the patch map, making them unsuitable for reusing for subsequent calls.

We saw this in a downstream test that exercises patch conflict retries, where the data being submitted in a patch was showing up in the original object data map.

Since mergeMap also mutates the patch map passed in (deletes patch directives as it encounters them), we also cannot reuse the patch map in applyPatchToObject once it has been used.

This PR:

  • Builds originalObjMap separate from the initial patch application for later use in conflict detection
  • Changes the originalPatchMap to a helper that returns a fresh map from original sources
  • Adds an integration test that exercises retry of non-overlapping patches with patches containing $patch directives
Fix incorrect conflict errors applying strategic merge patches to resources.

@k8s-reviewable
Copy link

This change is Reviewable

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Mar 30, 2017
@liggitt
Copy link
Member Author

liggitt commented Mar 30, 2017

cc @kubernetes/sig-api-machinery-pr-reviews @sttts @ncdc

@liggitt liggitt added the sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. label Mar 30, 2017
@k8s-github-robot k8s-github-robot added approved Indicates a PR has been approved by an approver from all required OWNERS files. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. release-note-label-needed labels Mar 30, 2017
@liggitt liggitt force-pushed the patch-mutation branch 2 times, most recently from 115546c to e06a37d Compare March 30, 2017 21:06
@k8s-github-robot k8s-github-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Mar 30, 2017
@liggitt
Copy link
Member Author

liggitt commented Mar 31, 2017

@wojtek-t @deads2k PTAL

@liggitt liggitt added this to the v1.6.1 milestone Mar 31, 2017
@k8s-cherrypick-bot
Copy link

Removing label cherrypick-candidate because no release milestone was set. This is an invalid state and thus this PR is not being considered for cherry-pick to any release branch. Please add an appropriate release milestone and then re-add the label.

@liggitt
Copy link
Member Author

liggitt commented Mar 31, 2017

Tagging for cherry-pick since this was a regression in 1.6

@sttts
Copy link
Contributor

sttts commented Mar 31, 2017

Looks like this was failed communication: here is another one: #43902, basically the same thing. We can choose one.

@liggitt
Copy link
Member Author

liggitt commented Mar 31, 2017

The patch map also gets mutated. This fixed and tests that issue as well

@deads2k
Copy link
Contributor

deads2k commented Mar 31, 2017

I think this does what it sets out to do, but the code in this area is really sticky to read.

@@ -86,21 +86,21 @@ func strategicPatchObject(
patchJS []byte,
objToUpdate runtime.Object,
versionedObj runtime.Object,
) (originalObjMap map[string]interface{}, patchMap map[string]interface{}, retErr error) {
originalObjMap = make(map[string]interface{})
) error {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just removed the return values here since they are unsuitable for use after having used them to apply the patch

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah - that sounds good.

Copy link
Member

@wojtek-t wojtek-t left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for long delay - I added some comment to a test.

@@ -86,21 +86,21 @@ func strategicPatchObject(
patchJS []byte,
objToUpdate runtime.Object,
versionedObj runtime.Object,
) (originalObjMap map[string]interface{}, patchMap map[string]interface{}, retErr error) {
originalObjMap = make(map[string]interface{})
) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah - that sounds good.

}
wg.Wait()

if successes < handlers.MaxRetryWhenPatchConflicts {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I don't understand this. We have 2N concurrent goroutines trying to do a patch. Why at least N of them has to succeed? Can you explain it (and add comment about it)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/kubernetes/kubernetes/pull/43902/files#diff-a98175d31a994ac0386ef984acfe13f5R111

@liggitt wants to copy that into his patch. Took some time to get the reasoning there.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW - I just looked into the other PR, and I think I like the approach from #43902 better. So maybe we should proceed with that one and close this one?
@liggitt @sttts - thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can rename the function here as well. That one doesn't address the patch map mutation issue

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. But the test is still passing with the other PR, which means it's not really testing everything, right?

Anyway - I'm fine with proceeding with this one too - just want to understand it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the test is still passing with the other PR

the test in the other PR doesn't include the patch directives... the test in this PR would fail against the fix in the other PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK - sorry for confusion then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you then please add a comment (similar than the one from the other PR) and I will lgtm this PR.

@liggitt
Copy link
Member Author

liggitt commented Apr 6, 2017

added comment at https://github.com/kubernetes/kubernetes/pull/43871/files#diff-a98175d31a994ac0386ef984acfe13f5R60

I added a mutation warning to the StrategicMergePatch godoc for now, rather than rename

@wojtek-t
Copy link
Member

wojtek-t commented Apr 6, 2017

I added a mutation warning to the StrategicMergePatch godoc for now, rather than rename

That's fine. Thanks.

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Apr 6, 2017
@wojtek-t wojtek-t added release-note-none Denotes a PR that doesn't merit a release note. and removed release-note-label-needed labels Apr 6, 2017
@k8s-github-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: liggitt, wojtek-t

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@liggitt
Copy link
Member Author

liggitt commented Apr 6, 2017

@k8s-bot kops aws e2e test this

@k8s-github-robot
Copy link

Automatic merge from submit-queue (batch tested with PRs 43871, 44053)

@k8s-github-robot k8s-github-robot merged commit 6497318 into kubernetes:master Apr 6, 2017
@liggitt liggitt mentioned this pull request Apr 6, 2017
13 tasks
@liggitt liggitt deleted the patch-mutation branch April 6, 2017 20:38
k8s-github-robot pushed a commit that referenced this pull request Apr 7, 2017
…1-upstream-release-1.6

Automatic merge from submit-queue

Automated cherry pick of #43871

Cherry pick of #43871 on release-1.6.

#43871: Fix original object mutation on patch retry

```release-note
Fix incorrect conflict errors applying strategic merge patches to resources.
```
@k8s-cherrypick-bot
Copy link

Commit found in the "release-1.6" branch appears to be this PR. Removing the "cherrypick-candidate" label. If this is an error find help to get your PR picked.

@enisoc enisoc added release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed release-note-none Denotes a PR that doesn't merit a release note. labels Apr 13, 2017
mintzhao pushed a commit to mintzhao/kubernetes that referenced this pull request Jun 1, 2017
…k-of-#43871-upstream-release-1.6

Automatic merge from submit-queue

Automated cherry pick of kubernetes#43871

Cherry pick of kubernetes#43871 on release-1.6.

kubernetes#43871: Fix original object mutation on patch retry

```release-note
Fix incorrect conflict errors applying strategic merge patches to resources.
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants