Question

I'm using Chef to manage deployments of a Rails application running with Mongrel cluster.

My init.d file is very simple. Here's the case for a restart:

restart)
  sudo su -l myuser -c "cd /path/to/myapp/current && mongrel_rails cluster::restart"
  ;;

I can run service myapp restart as root with no issue. I can run mongrel_rails cluster::restart as myuser with no issue.

However, when I do a deployment through Chef, the tmp/pids/mongrel.port.pid files don't get cleaned up (causing all future restarts to fail).

Chef is simply doing the following to perform the restart:

service "myapp" do
  action :restart
end

The init.d script is definitely being called as the logs all have the expected output (with the exception of exploding on the pid files, of course).

What am I missing?

Was it helpful?

Solution

As a work around, I can simply kill the mongrel processes before the init.d script is called. This allows the init.d script to still be used to start/stop the processes on the server directly, but handles the bogus case when mongrel is running and Chef tries to restart the service. Chef handles starting the service correctly as long as the .pid files don't already exist.

To do that, I included the following immediately before the service "myapp" do call:

ruby_block "stop mongrel" do
  block do
    ports = ["10031", "10032", "10033"].each do |port|
      path = "/path/to/myapp/shared/pids/mongrel.#{port}.pid"
      if File.exists?(path)
        file = File.open(path, "r")
        pid = file.read
        file.close
        system("kill #{pid}")
        File.delete(path) if File.exists?(path)
      end
    end
  end
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top