-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add replaceOnChanges
resource option
#7226
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
Conversation
loaders := []*deploytest.ProviderLoader{ | ||
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) { | ||
return &deploytest.Provider{ | ||
DiffF: func(urn resource.URN, id resource.ID, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like we should have something built-in to produce a plugin.DiffResult
from two resource.PropertyMaps
(and potentially a set of replace keys). I was surprised I had to implement all this myself. Did I miss where this is defined? cc @pgavlin
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like there is code like this in most of our native providers: https://github.com/pulumi/pulumi-azure-native/blob/ae7f380268c97b951a76848ec45b3bafa22d4338/provider/pkg/provider/diff.go. It's mostly the same sort of thing implemented here - but with some slightly special-cased to pull the "set of replace keys" from the specific provider schema. It feels like that implementation could/should be pulled into the core and generalized so it doesn't have to be reimplemented in every provider (and could also be reused in tests here).
b4064b4
to
05f2768
Compare
@lukehoban All of the SDK changes + tests should be finished now. It seems like the diff code deduplication could be addressed in a followup PR so we can finish out the immediate work stream. I'm not as familiar with the version compatibility considerations, so @pgavlin will probably need to verify that. |
@pgavlin This looks to be ready for your review.
Opened #7326 on this one.
Since we are not storing this in the state file (at least until #7285), I believe the two scenarios here are just:
This second case is potentially concerning. I am actually not sure how we handle this generally. Ideally the SDKs could require this support in the CLI and fail telling the user that this feature isn't supported in their CLI if they try to use it? Do we have support for that kind of version negotiation? Curious @pgavlin thoughts on this one. |
@lukehoban I was trying to test this out with the k8s provider and noticed that the |
@lblackstone this might be asking a lot, but would it be possible to split the property-path-related changes into a separate PR? It's a bit difficult to see the forest for the trees at the moment. |
The resource monitor provides the |
Do you mean just the changes in |
@lblackstone The engine does not pass |
And the tests, yes, assuming that those are the only affected files. |
Split out the prop path changes into #7354 |
0ca5c63
to
a472baf
Compare
Rebased and split up commits into logical chunks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple suggestions, but LGTM overall
diff, err = sg.applyReplaceOnChanges(diff, goal.ReplaceOnChanges, hasInitErrors) | ||
if err != nil { | ||
return nil, result.FromError(err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change to the logic is a bit concerning: we'll now be examining the diff even if there are no changes but there are init errors, where previously we would skip looking at the diff if it had no changes but there were init errors. What if we instead had applyReplaceOnChanges
run outside this check?
func (sg *stepGenerator) applyReplaceOnChanges(diff plugin.DiffResult, | ||
replaceOnChanges []string, hasInitErrors bool) (plugin.DiffResult, error) { | ||
|
||
var err error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we take my earlier suggestion re: rearranging the logic in generateStepsFromDiff
, then this function should early-out if diff.Changes != plugin.DiffSome && !hasInitErrors
@pgavlin I attempted to address your feedback. Can you double-check that the changes to the diff logic look like you expect? |
Adds a new resource option to force replacement when certain properties report changes, even if the resource provider itself does not require a replacement. Fixes #6753.
Squashed commits: [bba44ac92] Modify changes logic for init error case [c07ece4b3] Further feedback from Pat [50c7c16da] Address naming feedback [8b61b6ccf] Address diff feedback
5e318f0
to
14027da
Compare
# Conflicts: # CHANGELOG_PENDING.md
@lukehoban Any final comments before this gets merged? |
LGTM 🚀 I did some manual validation against a few "real world" use cases last night, and this worked great! |
The diff rendering logic tests whether the DetailedDiff is nil to determine whether to use it for rendering or defer to older older supported approaches to computing diffs. The new logic added in #7226 could lead to replacing a nil DetailedDiff with an empty DetailedDiff, whcih would make the rendering logic believe that a DetailedDiff was present but empty, instead of missing entirely. This change ensures that we maintain nil-ness of the DetailedDiff when we transform it for handling of replaceOnChanges. Also adds tests for this and other cases on applyReplaceOnChanges. Fixes #7486.
The diff rendering logic tests whether the DetailedDiff is nil to determine whether to use it for rendering or defer to older older supported approaches to computing diffs. The new logic added in #7226 could lead to replacing a nil DetailedDiff with an empty DetailedDiff, whcih would make the rendering logic believe that a DetailedDiff was present but empty, instead of missing entirely. This change ensures that we maintain nil-ness of the DetailedDiff when we transform it for handling of replaceOnChanges. Also adds tests for this and other cases on applyReplaceOnChanges. Fixes #7486.
Adds a new resource option to force replacement when certain properties report changes, even if the resource provider itself does not require a replacement. Fixes pulumi/pulumi#6753. Co-authored-by: Levi Blackstone <levi@pulumi.com>
Adds a new resource option to force replacement when certain properties report changes, even if the resource provider itself does not require a replacement.
Also supports
replaceOnChanges: ["*"]
to force any update to be a replacement instead. This includes updates triggered by initialization errors on previous create/update operations even when no inputs have changed (as a more general fix for things like pulumi/pulumi-kubernetes#856).Fixes #6753.
Addresses pulumi/pulumi-kubernetes#1007 (though via a resource option instead of a Kubernetes-specific annotation).
TODO:
Future work:
Without
replaceOnChanges
:With
replaceOnChanges
:With
replaceOnChanges
anddeleteBeforeReplace
: