The maze book for programmers!


DRM-Free Ebook

The Buckblog

assorted ramblings by Jamis Buck

Capistrano 2.1 Preview #1

1 September 2007 — 4-minute read

I had intended to wait until Net::SSH v2 (and friends) were done before making another Capistrano release, but the list of pending tickets was growing and there is still a good-sized pile of work to be done on Net::SFTP v2 before it can be released. So, I sat down this weekend and worked through the tickets, and I’m happy to present Capistrano 2.1 Preview Release #1.

Grab it via RubyGems from the Rails beta gem repository:

gem install -s capistrano

It will install as Capistrano 2.0.100.

Why a preview release? Well, there are a few changes in this release that might have far-reaching consequences, and I wanted to give people a chance to kick the tires and explore what the ramifications are without giving the impression that this is a generally-recommended production release. (I’m using it, but then, I might be a tad mentally unstable. Who knows?)

So, what are these new features and changes that have me so uncertain?

Feature: By default, Capistrano no longer requests that a pty be allocated for each command. This means that your default profile settings will be loaded automatically for every command. Yes! Yes! Your PATH tweaks and other environment variables will all be set as expected! However, because I did not ever document why I was requesting a pty in the first place, I do not know if there was a compelling reason why I was doing so. Thus, there may be unexpected side effects of this change. (I’ve not seen any such side-effects myself, but that doesn’t mean there won’t be.) If, for whatever reason, you do want a pty to be allocated for a particular command, just pass :pty => true to the run or sudo command. You can also use the default_run_options hash as described below to set it globally.

Feature: The subversion SCM module no longer uses the --password option to authenticate. Instead, it waits until the server prompts for the subversion password and send it that way. This is more secure (“ps” won’t show the password anymore), but I’m not entirely sure what the side-effects of this might be, so please report any subversion authentication anomalies.

Feature: If you are embedding Capistrano (in a Rails app or whatever), and you need to instantiate a Capistrano configuration more than once and use “require” to load a third-party recipe file, it should work now for every time you require the file. Please report any wonkiness with loading recipes via require.

Feature: The sudo password prompt is now detected much more reliably, thanks to the “-p” switch. My only concern is that somewhere out there (cough Solaris cough) there might be a sudo implementation that does not implement the -p switch for sudo. In that case, sudo via Capistrano will be utterly broken. Please let me know if you encounter a sudo that is broken this way.

Aside from the above, the following changes have also been made in this release:

Feature: If you use the “capify” script to generate your Capfile, it will now include a line that autoloads any recipe in vendor/plugins/*/recipes/*.rb. If you want this functionality, just delete your Capfile and rerun capify on your project directory.

Feature: If you’re on a shared host that does not let you spawn new shells, you can tell Capistrano to execute all commands directly, rather than via a spawned shell. Just pass :shell => false to the run command, or use the new default_run_options hash to set it globally:

default_run_options[:shell] = false

Note that if you use that setting, your default shell must be POSIX-compatible (and csh and tcsh, among others, are not POSIX-compatible).

Feature: There is a new “match” remote dependency method:

depend :remote, :match, "rake -V", /version 0\.7/

The given command will be executed on all hosts, and if the output does not match the given regular expression, the dependency will fail.

Feature: If you are using Subversion and you want your authorization credentials to be cached on the remote host, set :scm_auth_cache to true. (By default, authorization credentials are not cached on the remote hosts.)

Feature: There are now :version_dir, :current_dir, and :shared_dir variables in the deployment system that let you customize exactly what those deployment directories are called.

Feature: Reads now all open files in windows-safe (binary “rb”) mode.

Feature: Support for the Accurev SCM is now bundled with Capistrano.

Feature: The deploy:restart task honors the :runner variable when it uses sudo.

Feature: There is now a Namespace#top method for accessing the top-level namespace. This is useful when you want to execute a task in another namespace but you have an namespace between you and the top level that is interfering:

load 'deploy'

namespace :custom do
  namespace :deploy do
    task :something do
      # Have to do "top." because otherwise the bare reference to "deploy"
      # would find the current namespace.

Reader Comments

Great work, Jamis. I particularly like the subversion refinements, I will test them right away.

Great stuff, thanks!

I’ve got a combination of two features there causing me a wee problem. In order for Subversion to prompt you for a password, it needs a pty. I seem to have kicked it into working by changing line 29 of lib/capistrano/recipes/deploy/strategy/remote.rb to:

run(command, :pty => true) do |ch,stream,text|

ie just passing in `:pty => true` to the run command just in case it needs a pty.

I guess that’s going to screw up people that don’t have their scm command on their path and are relying on a bashrc to set it up.

And yeah, you are looking at Solaris for the sudo-equivalent without a `p`. On the plus side, it’s called `pfexec` and doesn’t (at least not any way I’ve figured of configuring it!) ever prompt for a password. My deploy has just failed because of it, so I’m sure I’ll have something more to say shortly. :)

Aha, on line 73 of lib/capistrano/configuration/actions/invocation.rb, I’ve changed it to the following:

command = [fetch(:sudo, "sudo"), fetch(:sudo_args, "-p '#{sudo_prompt}' #{user}"), command].compact.join(" ")

That way, I can do:

set :sudo_args, nil

while everybody else in the world ever can remain happy as they are. :-)

@Graeme, ugh, that’s nasty (on both counts). Perhaps I’ll just put the—password switch back for subversion. As for sudo…gah. I’m so sick of solaris doing it’s own thing. Perhaps I’ll tweak so that if sudo_prompt is false it does as you suggested (to avoid adding yet another setting).

To be fair, Solaris can have `sudo` installed too. However, they have a full RBAC implementation (something I think SELinux aspires to?) which does so much more than sudo is capable of, and I have a preference for using the built-in tools as much as possible. I’ve only scratched the surface of its capabilities, but the Solaris RBAC system is incredibly good.

Nice! That single pty change is huge. I should be able to clean up several recipies with that.

Where can I submit a patch for a new feature? I have a module that lets one use Git as their SCM.


Please submit all patches to, and mark them as pertaining to the Capistrano component. Thanks!