Sometimes if I hose up a Ruby install it won't have zlib or openssl or readline compiled in, which produces problems later when I try to get a Rails app running on there. But with a little code we can get Capistrano to check for Ruby extensions (or, really, Ruby libraries in general) via the deploy:check task.
Here's the new RemoteDependency implementation; you can just put this in your deploy.rb:
module ::Capistrano
module Deploy
class RemoteDependency
def ruby_extension(extension_name, options={})
output_per_server = {}
try("ruby -r#{extension_name} -e ''", options) do |ch, stream, out|
output_per_server[ch[:server]] ||= ''
output_per_server[ch[:server]] += out
end
@success = true
errored_hosts = []
output_per_server.each_pair do |server, output|
next if output.empty?
errored_hosts << server
end
if errored_hosts.any?
@hosts = errored_hosts.join(', ')
output = output_per_server[errored_hosts.first]
@message = "The Ruby interpreter was unable to load the extension #{extension_name}"
@success = false
end
self
end
end
end
end
Here's how to declare instances of this new dependency type; these go in deploy.rb also. Note that we're only checking for these dependencies on the app server; you may not even have Ruby installed on your web servers:
depend :remote, :ruby_extension, :zlib, :roles => :app
depend :remote, :ruby_extension, :openssl, :roles => :app
depend :remote, :ruby_extension, :readline, :roles => :app
And here's a sample run:
$ cap deploy:check
triggering start callbacks for `deploy:check'
* executing `multistage:ensure'
*** Defaulting to `production'
* executing `production'
* executing `deploy:check'
* executing "test -d /var/www/myapp/releases"
servers: ["myserver.com"]
[myserver.com] executing command
command finished
* executing "test -w /var/www/myapp"
servers: ["myserver.com"]
[myserver.com] executing command
command finished
* executing "test -w /var/www/myapp/releases"
servers: ["myserver.com"]
[myserver.com] executing command
command finished
* executing "which svn"
servers: ["myserver.com"]
[myserver.com] executing command
command finished
* executing "which gem"
servers: ["myserver.com"]
[myserver.com] executing command
command finished
* executing "ruby -rzlib -e ''"
servers: ["myserver.com"]
[myserver.com] executing command
command finished
* executing "ruby -ropenssl -e ''"
servers: ["myserver.com"]
[myserver.com] executing command
command finished
* executing "ruby -rreadline -e ''"
servers: ["myserver.com"]
[myserver.com] executing command
command finished
You appear to have all necessary dependencies installed
Note the boilerplate deploy:check commands up front followed by the custom checks for the libraries. As always, many thanks to Jamis Buck for Capistrano!