[chef] Re: Re: Re: Re: Re: notifies :before


Chronological Thread 
  • From: Daniel DeLeo < >
  • To:
  • Subject: [chef] Re: Re: Re: Re: Re: notifies :before
  • Date: Fri, 22 Nov 2013 12:07:49 -0800


On Friday, November 22, 2013 at 11:22 AM, Xabier de Zuazo wrote:


Hello guys,

On Thu, 21 Nov 2013 09:22:33 -0800

Thank you for your reply. I understand how notifies work, I was
just wondering if there was an elegant way to notify resources
_before_ running current resource. I know you could do it with
chaining resources through notify, but that smells a bit.
I found an issue asking the same question:

This would certainly be useful. The canonical use case is if you’re
managing a service that needs to be stopped before it’s upgraded,
which is common for some kinds of web app.

Unfortunately, the way most Chef providers are written now, there’s
no reasonable way to implement this as a before notification. One
possible avenue we haven’t explored yet is to run an individual
resource in why-run mode to see if it would make a change, which
might look like this in the DSL:

service “my-web-app” do
action :stop
# means “only if the resource deploy[my-web-app] would make
changes when running the :deploy action" test_resource
“deploy[my-web-app]”, :deploy end

The implementation would still be pretty complicated, but much less
so than the things we’ve tried before. Someone outside of opscode
would need to take this on because I don’t think we can fit it in our
priorities for quite a while.

I'm the one who tried to implement this a year ago. I proposed a
solution for the :before in this comment:


This solution included why-run support. In fact, it was easier for me
to implement this with why-run than without it.

After this solution was proposed, I know you talked a lot about it and
whether to add this feature to Chef or not. Even you asked on this
list. Much time was spent on this.

Time passed and the issue was finally closed putting it to "Won't
fix" state. But I didn't received any feedback about my code and I
didn't know how to improve it or what was the way forward.

The point is: Do you think it is a good idea to attempt to rebase this
solution and make a new PR or that would not help?

Bye,

--
Xabier de Zuazo Oteiza
IT System Administrator - Onddo Labs S.L.
--------------------------------------------------------------------
Key Fingerprint = 8EFA 5B17 7275 5F1F 42B2 26B4 8E18 8B67 9DE1 9468
--------------------------------------------------------------------
What happened here is, when we first implemented why run mode, we thought that we could restructure the way that providers work to do the following:

1. Examine the system
2. Compile a list of actions (as ruby Proc objects) that would converge the system to the desired state
3. Execute each action generated in step 2.

This was right around the time you submitted your patch, so it seemed sensible that we could just do:

1. Examine the system
2. Compile a list of actions (as ruby Proc objects) that would converge the system to the desired state

2a. Run before notifications

3. Execute each action generated in step 2.

At the same time that you were updating your patch, we learned that what we’d done by restructuring the providers to work that way was based on faulty assumptions and made the system more complicated and difficult to debug. In particular, whether or not a provider needs to take some action may depend on what the provider did in a previous step (this was most apparent for complicated providers like deploy). So we changed it to work more like it did previously:

1. Examine some aspect of the system
2. Run some code that converges that aspect of the system to the desired state
3. Repeat 1-2 until all aspects of the system described by a resource are in the desired state.

Unfortunately, this meant that we fundamentally broke the things your patch needed to work, after we suggested you could take advantage of them. I personally feel quite terrible that this happened. Sorry.

I know this is a valuable feature for some people and implementing the same behavior on your own is a PITA, so I’ve been trying to dream up ways that it could work without a scary level of implementation complexity. What I’m proposing is a little different than your patch:

1. There is a method in the DSL that allows you to run one action on one resource, except in why run mode. This either returns the value of Resource#updated_by_last_action? directly or returns the resource so you can query it.
2. Rather than specify a “before notification” on a resource, you use an “only_if” like construct that tests the later resource.

Example:

## Before notification that’s hard to implement clearly:

service “my-web-app” do
  action :nothing
end

deploy “my-web-app” do
  notify_before “service[my-web-app]”, :stop
  # other stuff
end

## As a guard, it should be much cleaner:

service “my-web-app” do
  action :stop
  
  # one way to implement DSL:
  only_if { test_action “deploy[my-web-app]”, :deploy }

  # or add a convince method that does the above in one go
  only_if_would_update “deploy[my-web-app]”, :deploy

end

deploy “my-web-app” do
  # doesn’t know anything about the service stop stuff above
end

I hope that explains the difference. Apologies again for sending you down the wrong path with your patch.



-- 
Daniel DeLeo




Archive powered by MHonArc 2.6.16.

§