Search code examples
ruby-on-railschef-inframongrelinit.dmongrel-cluster

Using Chef to restart Mongrel cluster via init.d script


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?


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