6

I have the following lines in my recipe

service "apache" do
  action :stop
end

# Do something..

service "apache" do
  action :start
end

I found that the 2nd block is not executed. Any reason?

Howard
  • 2,005
  • 11
  • 47
  • 70

5 Answers5

10

Notifications are the right way to handle this.

Suppose you want to do the following:

  • Conditionally download a file
  • If the file is downloaded
    • Stop apache immediately
    • Process the file (e.g. unzip it or move it)
    • Start apache again

You would do it like this:

# Define the apache service but don't do anything with it
service "apache" do
  action :nothing
end

# Define your post-fetch script but don't actually do it
execute "process my file" do
   ... your code here
  action :nothing
  notifies :start, "service[apache]"
end

# Fetch the file. Maybe the file won't be fetched because of not_if or checksum.
# In that case apache won't be stopped or started, it will just keep running.
remote_file "/tmp/myfile" do
  source "http://fileserver/myfile"
  notifies :stop, "service[apache]", :immediately
  notifies :run, execute["process my file"]
end
av501
  • 113
  • 5
kgilpin
  • 291
  • 2
  • 4
  • Oops... My bad. Mistakenly rejected edit. Actually new versions of chef support not only `resources(:service => "apache")` but also `"service[apache]"` syntax. Just verified with `11.4.4`. See docs at: http://docs.opscode.com/resource_common_notifications.html – SaveTheRbtz May 05 '13 at 09:50
9

The problem is that your resources have the same name. service "apache" is not unique, so chef is de-duplicating them. Your options are to give them separate names like this

service "apache stop" do
  service_name "apache"
  action :stop
end

# Do something

service "apache start" do
  service_name "apache"
  action :start
end

you could also use a notification from the "# Do something" block to send a :restart to the service "apache". That's the usual pattern people use, a single service, sending it notifications (or using subscribes). More here:

http://wiki.opscode.com/display/chef/Resources#Resources-Notifications

mray
  • 617
  • 5
  • 4
2

To add to this;

Chef does not start a service unless /etc/init.d/<DAEMON> status returns something other than 0. If it returns 0 then chef assumes that it's running.

1

Mray's and kgilpin's answers are perfect, but I ran into problems recently.

Somehow mysql service didn't stop before I needed to restart it and thus my recipe failed. I used workaround using '''Execute''' resource (I need recipes working on Ubuntu only). Execute is waiting for stop/start, while service could end earlier (init script will finish, while daemon not)

execute "Stop service" do
   command "service  stop"
end

I not proud for this solution, but it is working for me.

Lukino
  • 119
  • 3
-1

The default for service starts and restarts is to save it all up to the end of the chef-client run. If you really want to have two service starts or restarts, then specify that they are to happen immediately:

service "apache" do 
  action :start, :immediately
end

It isn't usually a good idea to do this since multiple restarts can cause unnecessary service interruptions. That's why Chef tries to save up all the service restarts until the end of the run.

Tim Potter
  • 1,754
  • 15
  • 15
  • becuase I am deploying source code using recipe, so i need to stop the apache, unlink the existing directory, link to the new directory and finally start again. i am wondering if there are any better method to do so? – Howard Apr 12 '12 at 04:25
  • 8
    To anyone else looking for this solution "action" on the service resource does not support ":immediately". The immediately flag only exists on chef notifications (http://docs.opscode.com/resource_common_notifications.html). – TrueDuality Apr 12 '13 at 14:52
  • 2
    Just let it restart at the end of the deployment. Do you really need to disable apache during deployment? In doubt you could create a maintenance page, which blocks all traffic. – StephenKing May 06 '13 at 06:43
  • Some times you have a kitchen test that *does* need immediate restart to see the effects of a test during deployment. This answer should not be voted down, as the questioner was not obligated to disclose when or how they want the desired behavior. – Michael Galaxy May 17 '16 at 18:15