ContainerSMF Mongrel

From TextUsers

Jump to: navigation, search

This page was created from a [Forum Topic]

SMF Configuration Script

OK, here's my first working cut at an SMF manifest for mongrel (mongrel_cluster, actually.)

Things you'll need to change:

  • everywhere I say mongrel/mcornick, change it to mongrel/yourappname (whatever you want)
  • change <method_context working_directory='/home/mcornick/rails/mcornick.org/current'> to point at your rails app's directory
  • change <method_credential user='mcornick' group='other' /> to the user and group you want

Also, you'll need to have set up your mongrel_cluster.yml file as usual. Once that's done, you can refer to mongrel/yourappname in svcadm. enable, disable and restart all work as expected.

I would suggest doing a separate manifest for each app, rather than trying to do multiple apps from one manifest. When I tried to do multiple apps, sometimes the mongrels wouldn't get restarted when they were killed.

I've tested this and it works for me, but as usual, your mileage may vary. Suggestions and improvements are welcome.

Next up: how to make Capistrano play nice with this setup. Shouldn't be too hard to make it do svcadm calls.

<?xml version='1.0'?>

<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>

<service_bundle type='manifest' name='mongrel/mcornick'>
  <service name='network/mongrel/mcornick' type='service' version='0'>
    <create_default_instance enabled='true'/>
    <single_instance/>
    
    <dependency name='fs' grouping='require_all' restart_on='none' type='service'>
      <service_fmri value='svc:/system/filesystem/local'/>
    </dependency>
    <dependency name='net' grouping='require_all' restart_on='none' type='service'>
      <service_fmri value='svc:/network/loopback'/>
      <!-- need nfs/client because the mongrel stuff is on /home which is nfs mounted -->
      <service_fmri value='svc:/network/nfs/client'/>
    </dependency>
    <dependent name='mongrel_multi-user' restart_on='none' grouping='optional_all'>
      <service_fmri value='svc:/milestone/multi-user'/>
    </dependent>
    
    <exec_method name='start' type='method' exec='/opt/csw/bin/mongrel_rails cluster::start' timeout_seconds='60'>
      <method_context working_directory='/home/mcornick/rails/mcornick.org/current'>
        <method_credential user='mcornick' group='other' />
        <method_environment>
          <envvar name="PATH" value="/usr/bin:/bin:/opt/csw/bin" />
        </method_environment>
      </method_context>
    </exec_method>

    <exec_method name='stop' type='method' exec=':kill' timeout_seconds='60'>
      <method_context/>
    </exec_method>

  </service>

</service_bundle>


Capistrano

Fixing Capistrano was a snap. I'm assuming you already have a working deploy.rb (if you don't, that's another thread.) You just need to redefine the spinner and restart tasks in deploy.rb. The Capistrano::Actor mod was added because I think writing "svcadmin :start, "myservice"" is a bit more clear.

Capistrano::Actor.class_eval do
  def svcadm(action, svc)
    sudo "svcadm #{action} #{svc}"
  end
end

task :spinner, :roles => :app do
  svcadm :start, "mongrel/yourappname"
end

task :restart, :roles => :app do
  svcadm :restart, "mongrel/yourappname"
end

Running More Than One App

I did find a problem in my manifest that would only affect people running more than one app (which, at the time I posted this, I wasn't. Paper bag for head, please.)

<dependent name='mongrel_multi-user' restart_on='none' grouping='optional_all'>
<service_fmri value='svc:/milestone/multi-user'/>
</dependent>

The name of the <dependent> has to be unique; therefore, you should change mongrel_multi-user to something unique per app. Once one app with the <dependent> of mongrel_multi-user is running, another one with the same name won't start.