-
Notifications
You must be signed in to change notification settings - Fork 81
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
Add resource current value loading to actions, and converge helper #127
Conversation
@coderanger had some good feedback which I haven't had time to update this proposal with. The three biggies were:
|
There's really 4 different states of resource parameters and we only capture two:
We diff 2 and 3 in order to make run reports, but we really should be diffing 2 and 4 and hacking up #3 for reporting causes all kinds of issues if we later wind up re-using the new_resource and we've lost he original meaning of what the user requested. There's also most likely plenty of existing bugs where providers mutate the new_resource and corrupt the original meaning. |
@lamont-granquist What is reporting doing to |
reporting doesn't do it directly. see chef/chef#3295 for more details. |
@coderanger @lamont-granquist I have modified the proposal to remove current-value loading from the actual front-facing resource, so that we can have that discussion separately; and renamed One thing that is worth looking at: it might be worth renaming |
|
||
#### Inheritance | ||
|
||
`super` in `load_actual_value!` will call the superclass's `load_actual_value!` method. |
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.
I don't think this is actually possible.
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.
Oh! I'll fix that one. I was using def load_actual_value! at first.
I'm still really not very enthused about these new APIs overall. Given the target is a very narrow niche of people that write resources from scratch (i.e. not based on existing resources for the most part) I would rather see them done in a helper library and iterated outside of core for a bit. |
```ruby | ||
load_actual_value do | ||
# Check for existence before doing anything else. | ||
actual_value_does_not_exist! if !File.exist?(path) |
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 seems kind of unfortunate, but I agree I don't know of a better option. As an API it seems really silly though.
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.
Another possibility is actual_value_exists? { File.exist?(path) }
. Not as much a fan of that, but it can make sense.
@coderanger some form of As for putting it in an outside library so it can be used and iterated upon, |
@jkeiser The changes you just made to use a block to define methods on the action class should work for |
@coderanger |
@jkeiser I don't feel like the resource cookbook is a great example of being proven out in the community given relatively low uptake, but that's a catch 22 for you so :-/ This feels like adding an API no one other than you has asked for and it does add considerable complexity. I feel like this is a small step in your vision for Resources 2.0 but we still have no actual overall view of that vision, let alone agreement that it is what we should be moving towards. |
@coderanger Like I said, there's no way to avoid having
if current_resource
# We're updating; look for properties that the user wants to change (do the "test" part of test-and-set)
differences = []
if (new_resource.property_is_set?(:foo) && new_resource.foo != current_resource.foo)
differences << "foo = #{new_resource.foo}"
end
if (new_resource.property_is_set?(:bar) && new_resource.bar != current_resource.bar)
differences << "bar = #{new_resource.bar}"
end
if (new_resource.property_is_set?(:baz) && new_resource.baz != current_resource.baz)
differences << "baz = #{new_resource.baz}"
end
if !differences.empty?
converge_by "updating FooBarBaz #{new_resource.id}, setting #{differences.join(", ")}" do
FooBarBaz.create(new_resource.id, new_resource.foo, new_resource.bar, new_resource.baz)
end
end
else
# If the current resource doesn't exist, we're definitely creating it
converge_by "creating FooBarBaz #{new_resource.id} with foo = #{new_resource.foo}, bar = #{new_resource.bar}, baz = #{new_resource.baz}" do
FooBarBaz.update(new_resource.id, new_resource.foo, new_resource.bar, new_resource.baz)
end
end Instead of this: converge do
if current_resource
FooBarBaz.update(new_resource.id, new_resource.foo, new_resource.bar, new_resource.baz)
else
FooBarBaz.create(new_resource.id, new_resource.foo, new_resource.bar, new_resource.baz)
end
end In one case, there is a huge amount of ceremony you have to go through if you want to do things right; in the other, you concentrate only on your own code rather than handholding Chef. |
And the above assumes that on update, unspecified values for I'll put the above example into the RFC for comparison purposes. |
@jkeiser Maybe I'm confused, I thought to goal of chef/chef#3660 was to be able to define methods on the fused provider class. |
@coderanger you rightly pointed out that you really shouldn't need to put (much of?) your crap in that class, so I'm backing off on that. |
Okay, then yes back on board with |
Yeah, I can do that. |
With that I'm back 👍. I feel like we could go two ways with |
I'm seriously all ears for different names :) I haven't thought of one better yet, but it does gnaw at me. |
Random ideas without regard for actual quality: |
Maybe |
Naming is hard, let's just call it |
Deal! |
@coderanger renamed |
|
||
#### Inheritance | ||
|
||
`super` in `load_current_value!` will call the superclass's `load_current_value!` method. |
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.
Should be
`super()` in `load_current_value` will call the superclass's `load_current_value` method.
Okay - this seems to have universal good times. 👍 /deciderated |
@chef/rfc-editors this appears ready for merge... |
Add resource current value loading to actions, and converge helper
Doneburger. |
No description provided.