jump to navigation

Disable mongrel mod_proxy_balancer workers via Capistrano August 15, 2008

Posted by John Dewey in Capistrano, Configuration, Deployment, Mongrel, Rails, WebServers.
add a comment

I created a Capistrano task for disabling workers inside a given balancer, from Daniel Wharton’s Deploying Rails post.

Here’s the pastie. BTW I really hate linking off to pastie for these things. Any suggestions?

The task disables the worker, and is not specific to Mongrel.

Advertisements

Rails Cron — Craken July 18, 2008

Posted by John Dewey in Capistrano, Code, Command Line, Configuration, Rails, Rake, Ruby.
Tags:
1 comment so far

My good buddy Doug Mciness wrote a rake task to manage and install cronjobs. We have it hooked into our Capistrano deployments, which allows for uber simple cron management. I added a few modifications such as, erb’ed raketab templates, and global/system specific crontabs.

It’s up on GitHubhttp://github.com/latimes/craken/tree/master

In the process of determining if these rakefiles should be yaml instead, would probably be the “more railsy rails way” of doing it.

Giles Bowkett gets props for the groovy name, and improved SEO of this post!

Run a Capistrano task on a single server in a given role February 7, 2008

Posted by John Dewey in Capistrano, Code, Command Line, Deployment, Monkey Patch.
3 comments

There are times I want to run a Capistrano task on a single server, rather than every system in the role. Adding this monkey patch to deploy.rb adds this functionality. To utilize this feature append ‘server=IP_ADDRESS’ to the Cap command. Tasks are defined to run on particular role(s), this feature will target the server inside a particular tasks role. It will not execute a task on an arbitrary server.  CJ Kihlbom filled me in and stated this can be accomplished with `cap deploy HOSTS=IP_ADDRESS`.  See his comments attached to this post.

Rake tasks :through Capistrano January 27, 2008

Posted by John Dewey in Capistrano, Example, Rake.
1 comment so far

Executing Rake tasks on host(s) through Capistrano is nothing new, and there are quite a few ways to do it. Some of the configurations out there, use a common Capistrano task to execute all Rake tasks. This works quite well, but you run into problems when scoping tasks to specific roles. The common Rake exec task is not scoped to a specific role (because it could run any task on any given role), so if you call it from a Cap task scoped to :db, it will still execute across all roles.

This was corrected by creating a Rake exec method instead of a Cap task. The method can pass any arbitrary variables and/or Rakefile to Rake.An example Capistrano task, displays it’s usage. There are a few Cap variables already set, such as rake and rails_env. Using the rakefile variable allows the execution of a specific Rakefile, which comes in handy when wanting to ignore the Rails Rakefile.

Why ignore the Rails Rakefile? In our configuration the Rakefile loads environment.rb, which sets the load_paths to our custom rubygems path – that means loading Rails! What happens when Rails is not installed, and you need a bootstrap task. The ability to pass in a Rakefile all of the sudden becomes useful.

Multi-App Mongrel Cluster Init Script January 22, 2008

Posted by John Dewey in Capistrano, Configuration, Deployment, Mongrel, Rails.
2 comments

I found the mongrel_cluster.sh script, everyone uses — doesn’t quite cut it.   Especially, when a system may host several RoR applications.  Why, you ask?  The ability to easily control, and dynamically discover applications is missing.  In most cases, this doesn’t matter.  Especially when the applications are deployed with Capistrano, since it is leveraged for various tasks (including stop, starts, and restarts).

The SAs on the other hand, usually do not use Capistrano (they should!), or have a recent version of the app checked out.  Having a standard init script across all your applications and servers becomes useful.

You get bonus points for dynamically discovering new application installs.We can make certain assumptions in our environment.

We use Capistrano, apps run as the same user,  live under the same base directory, and link to common Subversion Rake tasks.  That enables the use of a generic Rake task to control all RoR applications. Furthermore, the Rake task can be wrapped by a system init script for use under /etc/init.d/.

Advanced Rails Recipes Contribution January 6, 2008

Posted by John Dewey in Capistrano, Configuration.
2 comments

Giles and I had our contributions selected for the upcoming Advanced Rais Recipes Book — pretty cool!

 

Scrape mongrel status from Apache’s mod_proxy_balancer January 4, 2008

Posted by John Dewey in Apache, Capistrano, Code, Command Line, Configuration, Example, Rails, Rake, WebServers.
1 comment so far

Access to Apache’s load balancer manager (mod_proxy_balancer) is typically protected.  Rather than maintaining an ever changing list of ACLs or configuring HTTP authentication, I wrote a simple scraper Rake task.

This task is bundled with all of our rails applications as a svn external, and included in our common Capistrano tasks.This task is a quick and dirty solution to checking the status of your Mongrels.

Feel free to modify, and provide a pastie.http://pastie.caboo.se/135223

P.S. The SAs can plug this into their monitoring software as well.

Patching Capistrano to use CVS over SSH September 11, 2007

Posted by reidmix in Capistrano, Code, Command Line, CVS, Monkey Patch, Ruby, SSH.
4 comments

At work we still use CVS as our versioning repository and most of our systems rely on CVS to build and deploy into production. Currently there is no effort to transition to SVN, so we need to develop a patch to Capistrano to allow our projects to deploy to our development lab. We needed to extend Capistrano handle SSH logins to CVS and handle CVS repository directories.

Overall, both changes needed to be applied to the checkout method in Capistrano’s Cvs class.

We use SSH as the underlying communication mechanism for CVS but there is a difference in the password prompt: SSH’s is capitalized. We just need to make the prompt check case insensitive with the i switch:

if out =~ %r{password:}i

When setting up Capistrano (v1.4) for use in our development lab, the :application configuration is not sufficient to identify our rails project the CVS tree. We are not cool enough to setup or use modules to map into our repository directories, so our projects are usually in some form of webdev/project/appname. To handle this, i create an additional configuration parameter called :project in the deploy.rb:

set :project, "cvs/dir/to/myproj"

And we no longer use the application name for the CVS path, we use the project variable:

project = configuration[:project] || actor.application
command = <<-CMD
  cd #{configuration.releases_path};
  CVS_RSH="#{cvs_rsh}" #{cvs} -d #{configuration.repository} -Q #{op} -D "#{configuration.revision}" #{branch_option} -d #{File.basename(actor.release_path)} #{project};
CMD

The hardest part is patching Capistrano. Capistrano’s code gets loaded well after any library or environment gets loaded. The trick is to use the method_added hook to wait for the checkout method to get loaded and then alias the method to the patched one, we need to keep a variable around to check if we’ve patched the method so we don’t end up in an infinite loop:

@@checkout_patched = false
def Cvs.method_added(id)
  if id.id2name == "checkout"
    unless @@checkout_patched
      @@checkout_patched = true
      alias_method :checkout, :checkout_patch
    end
  end
end

I’ve not checked to see how these changes work or differ in Capistrano 2. But with all these elements together using Capistrano v1.4, I can drop this file in my lib directory or create a plugin with it. Together, here is the full patch which I have in a file called capistrano_cvs_ext.rb:

module Capistrano
  module SCM
    class Cvs < Base
      @@checkout_patched = false
      def Cvs.method_added(id)
        if id.id2name == "checkout"
          unless @@checkout_patched
            @@checkout_patched = true
            alias_method :checkout, :checkout_patch
          end
        end
      end

      def checkout_patch(actor)
        cvs = configuration[:cvs] || "cvs"
        cvs_rsh = configuration[:cvs_rsh] || ENV['CVS_RSH'] || "ssh"

        if "HEAD" == configuration.branch then
            branch_option = ""
        else
            branch_option = "-r #{configuration.branch}"
        end

        # cvs has a root and repository, repository is not the same as application name as it can be a path
        op = configuration[:checkout] || "co"
        project = configuration[:project] || actor.application

        command = <<-CMD
          cd #{configuration.releases_path};
          CVS_RSH="#{cvs_rsh}" #{cvs} -d #{configuration.repository} -Q #{op} -D "#{configuration.revision}" #{branch_option} -d #{File.basename(actor.release_path)} #{project};
        CMD

        run_checkout(actor, command) do |ch, stream, out|
          prefix = "#{stream} :: #{ch[:host]}"
          actor.logger.info out, prefix
          if out =~ %r{password:}i  # SSH asks for "Password" with a capital P
            actor.logger.info "CVS is asking for a password", prefix
            ch.send_data "#{actor.password}n"
          elsif out =~ %r{^Enter passphrase}
            message = "CVS needs your key's passphrase and cannot proceed"
            actor.logger.info message, prefix
            raise message
          end
        end
      end
    end
  end
end