5

I'm using chef-solo v10.12.0 to configure an Ubuntu 12.04 VM, and I keep running into an issue where services don't restart or reload as expected when a configuration file is changed.

There are no errors in the log although it's clearly doing everything else in the recipe. As a workaround I've been manually restarting services or forcing a reload/restart each time the recipe executes, but I'd prefer to figure out what's going wrong and have it work as expected.

One example recipe that consistently fails to work as expected:

package "pgbouncer"

cookbook_file "/etc/default/pgbouncer" do
    source "pgbouncer/pgbouncer"
    owner "root"
    group "root"
    mode 0644
end

service "pgbouncer" do
    supports :start => true, :stop => true, :restart => true, :reload => true, :status => true
    action [:enable, :start]
end

cookbook_file "/etc/pgbouncer/userlist.txt" do
    source "pgbouncer/userlist.txt"
    owner "postgres"
    group "postgres"
    mode 0640
    notifies :restart, "service[pgbouncer]"
end

template "/etc/pgbouncer/pgbouncer.ini" do
    source "pgbouncer/pgbouncer.ini"
    owner "postgres"
    group "postgres"
    mode 0640
    variables :postgres_host => node[:postgres_host]
    notifies :restart, "service[pgbouncer]"
end
John Debs
  • 287
  • 1
  • 4
  • 10
  • Is this the entire cookbook and there are no other recipes being included or run? Because this is a very simple case and notifications and subscriptions do work in such simple cases even if more complex ones are known to be problematic. – kgilpin Sep 14 '12 at 20:50
  • @kgilpin This is the entire recipe, although there are ~16 other recipes being run. In the meantime I've changed it to triggering automatically and that seems to have solved the problem, even though it's not ideal. – John Debs Oct 11 '12 at 22:28

4 Answers4

2

The first thing I would check is that the user running chef-client has permissions to start/restart the service (usually not the problem).

Next I would check that there are no other recipes running that are counteracting the logic of this recipe (sometimes the problem, but not often).

What I really think is causing your issue is the way chef handles it's queue of what it needs to execute via the shell. Multiple and somewhat conflicting calls to the same service can lead to unexpected behavior(as you have already seen). By default, all 'shell' calls are handled as the last part of the convergence phase in a chef-client run. Moreover, chef doesn't guarantee any particular order of execution, so things can frequently happen out of order and may produce undesired behavior depending on the software of the service you are manipulating. Usually bucking that with the technique below is all you need.

The quick and dirty answer to your question is to add a :timer argument to your notify calls. DOC: http://docs.opscode.com/resource_common.html#notifications-timers

here's a suggested update to your example code above:

package "pgbouncer"

service "pgbouncer" do
    supports :start => true, :stop => true, :restart => true, :reload => true, :status => true
    action [:enable, :start]
end

cookbook_file "/etc/default/pgbouncer" do
    source "pgbouncer/pgbouncer"
    owner "root"
    group "root"
    mode 0644
end

cookbook_file "/etc/pgbouncer/userlist.txt" do
    source "pgbouncer/userlist.txt"
    owner "postgres"
    group "postgres"
    mode 0640
    notifies :restart, "service[pgbouncer]", :immediately
end

template "/etc/pgbouncer/pgbouncer.ini" do
    source "pgbouncer/pgbouncer.ini"
    owner "postgres"
    group "postgres"
    mode 0640
    variables :postgres_host => node[:postgres_host]
    notifies :restart, "service[pgbouncer]", :immediately
end

This isn't the most efficient way to go as it can cause your daemon to execute too many redundant actions (up to 3 'start like' calls in one run: start,restart,restart). There is another, more OOP friendly way to do this in chef by leveraging a Definition (DOC: http://docs.opscode.com/essentials_cookbook_definitions.html). This would essentially be a custom wrapper for the pgbouncer service resource you define to reduce the inefficiencies of executing redundant calls while ensuring they are executed effectively, but I'll leave it to you to decide what's best for your use case.

1

I would try changing your service definition to the following

service "pgbouncer" do
    supports :start => true, :stop => true, :restart => true, :reload => true, :status => true
    action :enable
end

I think I remember experiencing something similar a while ago and this was the culprit. Let me know if this works for you, but for some reason this is how I've been defining my services for a while now and I haven't had any problems since.

Bjorn248
  • 11
  • 2
0

This seems to be a pretty prevalent problem with resources and notifications in general.

I've poked around the Opscode JIRA ticket tracker, and there's a ticket that discussed a large amount of changes and fixes to the notifications and resource behavior, to be released in 10.14.0

Mike Fiedler
  • 2,152
  • 1
  • 17
  • 33
0

Not sure whether pgbouncer is providing an Upstart or Init (looks to be Init from here: http://packages.ubuntu.com/precise/amd64/pgbouncer/filelist) but I'd give this a shot with your service resource if you still have issues:

service "pgbouncer" do
  provider Chef::Provider::Service::Init
  supports :start => true, :stop => true, :restart => true, :reload => true, :status => true
  action [:enable, :start]
end

Additionally, I'd add the :immediately argument that Gregory Patmore suggested as well.