Pre-update notifications

Hello,

I’d like to have pre-update notifications which would be the same as
"notifies" but triggered before resource convergence.

For instance, some packages automatically restart a service during
upgrade and I’d like to downtime the host in supervision before
actually starting to upgrade those packages.

Classic notifications would be :

package “cassandra” do
notifies :run, "execute[downtime host]"
end

but notification is triggered after the upgrade so it is not useful
anymore.

I wondered how to do this and came up with a partial solution switching
to why_run temporarily to find wether a given resource (package) will
be updated during convergence.
An example is https://gist.github.com/kamaradclimber/6306398
which would execute the resource to downtime only if the package will be
upgrade later.

Does anyone has already encountered such need? and fixed it?


Grégoire

Hey,

Our solution for this was to chain notifications in the order we wanted.

For example:

execute “Update Cassandra” do
notifies :run, execute[Downtime Cassandra Host],
end

execute “Downtime Cassandra Host” do
action :nothing
notifies :restart, service[Cassandra],
end

service “Cassandra” do
action :nothing
end

The upside is that you have a relatively straightforward way to chain these
processes, the downside is that this is entirely up to the coder to make
sure they follow the pattern.

We do something similar with config validation before service restarts for
Nginx.

On Thu, Aug 22, 2013 at 8:31 AM, Gregoire Seux g.seux@criteo.com wrote:

Hello,

I’d like to have pre-update notifications which would be the same as
"notifies" but triggered before resource convergence.

For instance, some packages automatically restart a service during
upgrade and I’d like to downtime the host in supervision before
actually starting to upgrade those packages.

Classic notifications would be :

package “cassandra” do
notifies :run, "execute[downtime host]"
end

but notification is triggered after the upgrade so it is not useful
anymore.

I wondered how to do this and came up with a partial solution switching
to why_run temporarily to find wether a given resource (package) will
be updated during convergence.
An example is https://gist.github.com/kamaradclimber/6306398
which would execute the resource to downtime only if the package will be
upgrade later.

Does anyone has already encountered such need? and fixed it?


Grégoire

Le 22/08/2013 16:17, Andrew Gross a écrit :

execute “Update Cassandra” do
notifies :run, execute[Downtime Cassandra Host],
end

execute “Downtime Cassandra Host” do
action :nothing
notifies :restart, service[Cassandra],
end

service “Cassandra” do
action :nothing
end
Hi Andrew,

thanks for your reply.
This issue with your solution is that it assumes that you can update the
package and then decide to restart the service.
In my case, the package contains triggers to update restart the service
(stop it as pre-install and start as post-install hook). This pattern is
quite commom I guess on rhel and debian systems.

So in your example you would have updated the package (thus restart the
service), downtimed the host and restart the service once more.


Gregoire

Fair enough, the order was rather arbitrary in my example, though I can see
how it might be problematic, as you would now need an additional block to
determine if an update was available, and one to install it.

On Thu, Aug 22, 2013 at 10:52 AM, Grégoire Seux g.seux@criteo.com wrote:

Le 22/08/2013 16:17, Andrew Gross a écrit :

execute “Update Cassandra” do
notifies :run, execute[Downtime Cassandra Host],
end

execute “Downtime Cassandra Host” do
action :nothing
notifies :restart, service[Cassandra],
end

service “Cassandra” do
action :nothing
end

Hi Andrew,

thanks for your reply.
This issue with your solution is that it assumes that you can update the
package and then decide to restart the service.
In my case, the package contains triggers to update restart the service
(stop it as pre-install and start as post-install hook). This pattern is
quite commom I guess on rhel and debian systems.

So in your example you would have updated the package (thus restart the
service), downtimed the host and restart the service once more.


Gregoire

Chef does not provide anything like before resource update notification.
you have post update even handler hooks and standard
notification/subscription via dsl.might be able to get close to what you
want by doing a why_run first and then dynamically changing the action of
notified resource, but this wont be very straightforward, also you have to
ensure the why_run implementations are correct.

On Thu, Aug 22, 2013 at 7:52 AM, Grégoire Seux g.seux@criteo.com wrote:

Le 22/08/2013 16:17, Andrew Gross a écrit :

execute “Update Cassandra” do
notifies :run, execute[Downtime Cassandra Host],
end

execute “Downtime Cassandra Host” do
action :nothing
notifies :restart, service[Cassandra],
end

service “Cassandra” do
action :nothing
end

Hi Andrew,

thanks for your reply.
This issue with your solution is that it assumes that you can update the
package and then decide to restart the service.
In my case, the package contains triggers to update restart the service
(stop it as pre-install and start as post-install hook). This pattern is
quite commom I guess on rhel and debian systems.

So in your example you would have updated the package (thus restart the
service), downtimed the host and restart the service once more.


Gregoire

On Thursday, August 22, 2013 at 5:31 AM, Gregoire Seux wrote:

Hello,

I’d like to have pre-update notifications which would be the same as
"notifies" but triggered before resource convergence.

For instance, some packages automatically restart a service during
upgrade and I’d like to downtime the host in supervision before
actually starting to upgrade those packages.

Classic notifications would be :

package “cassandra” do
notifies :run, "execute[downtime host]"
end

but notification is triggered after the upgrade so it is not useful
anymore.

I wondered how to do this and came up with a partial solution switching
to why_run temporarily to find wether a given resource (package) will
be updated during convergence.
An example is https://gist.github.com/kamaradclimber/6306398
which would execute the resource to downtime only if the package will be
upgrade later.

Does anyone has already encountered such need? and fixed it?


Grégoire

Your problem here is that Chef resources are declarative, i.e., they say what the state of the system should be, but in this case you’re trying to control the way the system transitions from one state (old packages) to another (up-to-date packages). The best way to accomplish this is to write a LWRP that checks if a new package is available and shuts the service down before upgrading.


Daniel DeLeo

Le 22/08/2013 17:06, Daniel DeLeo a écrit :

Your problem here is that Chef resources are declarative, i.e., they
say what the state of the system should be, but in this case you’re
trying to control the way the system transitions from one state (old
packages) to another (up-to-date packages). The best way to accomplish
this is to write a LWRP that checks if a new package is available and
shuts the service down before upgrading.

I agree with you that I want to go further than simply declare
resources. Allowing notifications and subscription is already a step in
that direction.

I have wrapped the logic in a lwrp
(https://gist.github.com/kamaradclimber/6306398) it gives a not so
complicated way to declare prehooks


Gregoire