[chef-dev] Re: notifies :before


Chronological Thread 
  • From: Xabier de Zuazo < >
  • To:
  • Subject: [chef-dev] Re: notifies :before
  • Date: Wed, 27 Nov 2013 07:15:33 +0100
  • Organization: Onddo Labs SL


 Hello Lamont Granquist,

 I will try to answer all your questions. Please, let me know if
 anything is not clear or I'm wrong. I'm far from being a Chef
 expert :-)

 Before we begin: I know my solution may not be perfect and certainly
 can be improved. But I also think it's not a bad starting point.

On Tue, 26 Nov 2013 11:49:59 -0800
Lamont Granquist 
< >
 wrote:

[...]
> > https://github.com/onddo/chef/compare/CHEF-2421-3
> >
[...]
> What is your feature supposed to do now?  The thing that you wanted
> to do was to be able to use the old behavior of why-run mode in order
> to be able to figure out if there were any queue'd up converge_by
> blocks, but before the blocks were executed, in order to get a kind
> of "would_modify_by_action?" check.

 My patch does not work exactly like that.

 I'll try to explain more or less how it works (linking some code
 snippets).

 In summary:

1. If resource supports why-run, updated_by_last_action will be
   predicted and :befores executed.

2. If resource does not support why-run, it will try to use not_if &
   only_if conditionals to know whether to run :before notifications,
   printing a warning about it, because may not be the expected
   behavior.

 I think this sounds simple enough.

 To predict updated_by_last_action with why-run (1.), Chef will
 run :before notifications inside the #converge_by method, but before
 running the converge_by &block.

WhyRun::ConvergeActions#add_action patch: http://git.io/qjNwag

 This works because whenever we call #converge_by,
 updated_by_last_action will become true, so, the resource will be run
 and all notifications called.

Provider methods that establish this behavior: http://git.io/KFih4w

 My solution predicts updated_by_last_action because the logic that
 determines its value is outside #converge_by. It is inside each
 provider logic, before calling #converge_by. So, if #converge_by is
 called, updated_by_last_action will always be true.

 You can check the code of any provider to verify this behavior.


 If why-run is not supported by the resource (2.), it will run
 the :before notifications only if it has only_if/not_if conditions and
 they are met.

Provider#run_action patch: http://git.io/fGBNMA

Provider#run_before_notifications: http://git.io/WF0cmw

 The latter can be considered as an incomplete imitation of the :before
 notifications. But without why-run, I think it's impossible to predict
 updated_by_last_action without changing all the providers in the
 space and part of the void.

>  We completely broke the ability
> to do that, and as its noted in the ticket its difficult to even
> predict in the general case that a resource will be updated before
> you call the action.

 I know you advised me to use why-run to predict updated_by_last_action,
 insinuating that I could use something like the
 Provider#resource_updated? or the ConvergeActions#empty? method,
 and I started to implement this way. But at the time, I 
 could not find a clean way to implement that without adding tricky
 code, so I finally used a similar but slightly different approach (it
 was long ago, so I do not remember in detail).

 I think it was a mistake on my part not clarify this. I hope it is
 already clear how it works.

>  So what are the conditions under which you
> expect these before notifications to fire?

 When why-run is supported, before notifications are fired when the
 resource will be updated, and just before calling the converge_by
 block.

> And why can't you
> restructure your run_list so that those resources simply come first
> and are idempotent?

 Because sometimes you require to change the status of the same
 resource multiple times during a chef run.

 Some simple examples are mainly related with stopping services, perhaps
 before updates, and then starting them again. Something like:

execute "install/update database" do
  command " ... "
  notifies :stop, "service[database]", :before
  notifies :start, "service[database]", :immediately
  only_if { ... }
end

execute "install my-webapp" do
  command " ... "
  notifies :stop, "service[tomcat]", :before
  notifies :start, "service[tomcat]", :immediately
  only_if { ... }
end

 There are some more examples in the ticket.

> Why can't you restructure your run_list to use
> an after notification?

 I think the following comment in the ticket answers this question:
 
https://tickets.opscode.com/browse/CHEF-2421?focusedCommentId=27014&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-27014

 Implementing some :before notifications using :after surely is not
 impossible. But IMHO the code can become weird and difficult to
 understand in some cases.

> This smells like its become a feature-for-the-sake-of-a-feature where 
> there's other, better, clearer ways to get the job done.

 Maybe, but this seems to be a requested feature by some people. This is
 not the first time the topic comes out on the list/IRC.

From https://github.com/opscode/chef/pull/1145:
> Generally the code seems overly complicated and i think it still has
> vestigial code that was meant to deal with the old approach of trying
> to only trigger when the resource would be updated, but before the
> converge blocks were invoked. since you simply cannot do that any
> more, the replacement feature must be to just hit the before notify
> every time the provider is invoked, which is a simpler problem, and i
> don't understand the complexity here.

 Some of these things are already answered above.

 AFAIK, using this solution the provider does NOT call the before
 notification every time the provider is invoked. It calls it whenever
 the provider will be run, i.e. whenever updated_by_last_action will be
 true.

> i'm also less sure of the value
> of this feature, since you can just structure your run list so that
> the resource you are 'notifying' comes first.

 You maybe right, but I think it's not so obvious how to implement this
 without :before.

> is there a compelling
> use case where you want to have a recipe follow in the run list but
> have a prior recipe's resource notify a resource that comes later?

 I think this feature is useful for calling both resources that comes
 later and resources that has come before. Some examples are in this
 email and in the ticket.


 Either way, and above all, thanks for taking time to review this
 ticket. The decision on the importance of this feature and whether to
 do it my way or not is in your hands. My opinions are clearly
 debatable :-)

 Regards,

-- 
Xabier de Zuazo Oteiza
IT System Administrator - Onddo Labs S.L.
www.onddo.com
--------------------------------------------------------------------
Public Key = http://www.onddo.com/xabier_zuazo.pub
Key Fingerprint = 8EFA 5B17 7275 5F1F 42B2  26B4 8E18 8B67 9DE1 9468
--------------------------------------------------------------------

Attachment: signature.asc
Description: PGP signature




Archive powered by MHonArc 2.6.16.

§