Capistrano 2.5.0
Posted by Jamis on Friday, August 29
Capistrano 2.5 is now available, with several new additions and a fair helping of bug fixes and general improvements. To install it:
gem install capistrano
Here’s a rundown of what’s new:
parallel() helper
A common question by people learning Capistrano is “how can I tell what the current server is?” There still isn’t a good answer to this (since Capistrano executes each command against all active servers in parallel) but Cap 2.5 introduces the “parallel” helper that might just make the question moot.
An example is worth 1,000 words:
1 2 3 4 5 6 7 |
task :restart_everything do parallel do |session| session.when "in?(:app)", "/path/to/restart/mongrel" session.when "in?(:web)", "/path/to/restart/apache" session.when "in?(:db)", "/path/to/restart/mysql" end end |
When you execute that hypothetical :restart_everything task, the parallel helper compares all active servers against the conditions. All matching conditions for a server indicate which command(s) will be run against that server, and then all those commands (for all matching servers) are run in parallel. (In this case, the mongrels would be restarted on the app servers at the same that apache is being restarted on the web servers, and mysql is being restarted on the db servers.)
The only way to do something similar before 2.5 was to invoke 3 separate run commands, which would run the commands serially, instead of in parallel.
You can pass callback blocks to each condition, as well, to handle output specially for each case:
1 2 3 |
session.when "in?(:app)", "/path/to/restart/mongrel" do |channel, stream, data| # same format of callback as you would give to run() or sudo() end |
You can also specify a fallback condition, to be used when a server fails to match any of the conditions:
1 |
session.else "/execute/something/else"
|
Lastly, the string specifying the condition must evaluate to valid Ruby code. Inside it, you can access the in?() helper (to query whether the current server is included in the given role), as well as a “server” variable that you can use to match specific hosts by name:
1 |
session.when "server.host =~ /app/", "/command/to/execute" |
This should allow some exciting new usage patterns to emerge. Please share what you come up with!
Chained gateways
Prior to 2.5, Capistrano was not easily able to accomodate servers that needed to be accessed via two or more gateway machines. In 2.5, the gateway variable can now be an array of hostnames, and the gateway will tunnel through all of them:
1 |
set :gateway, %w(jamis@gateway.host deeper.host final.host) |
In that example, each server would be connected to via a triply-chained gateway, tunneling from the local server to the final host via gateway.host (using “jamis” as the username), then deeper.host, and then final.host.
“-s” and “-S” infer the types of their arguments
When you set a variable from the command-line (using -s or -S), the type of the value will now be inferred. This allows you to set booleans, integers, floating point values, and nil values from the command-line, as well as strings (the fallback if a type cannot be inferred).
deploy:rollback and mongrel
Prior to 2.5, deploy:rollback would fail with mongrel processes that were spawned via Rails’ script/process/spawner tool. This was because the mongrel processes were restarted after the bad revision was removed, resulting in mongrel dying because it’s current working directory was invalid.
In 2.5, the bad revision is not actually removed until after the restart happens.
Dry-run mode
Prior to 2.5 you could use the "-d" (--debug) switch to step through your recipes. In 2.5, this is expanded with the "-n" (--dry-run) switch, which will run the tasks straight through, but will not actually invoke any of the (remote) commands. (Local commands are still executed.)
Other changes and bug fixes
From the change-log:
- Allow HOSTS spec to override even non-existent roles
- Sort releases via “ls -xt” instead of “ls -x” to allow for custom release names
- Add descriptions of -n and -d to the verbose help text
- Rename deploy:rollback_code to deploy:rollback:code
- Make sure a task only uses the last on_rollback block, once, on rollback
- Add :shared_children variable to customize which subdirectories are created by deploy:setup
- Allow filename globbing in copy_exclude setting for the copy strategy
- Allow remote_cache strategy to use copy_exclude settings (requires rsync)
- Make None SCM module work in Windows
- Recognize mingw as a Windows platform
- Fixed failing tests in Windows
- Made :scm_auth_cache control whether password option is emitted in subversion module
- Fixed timestamp bug in CVS module
Feedback
As ever, please report bugs via the Capistrano issue tracker. If you’d like to submit a patch, please make sure it applies cleanly on the latest version of the source code, and submit it either via the issue tracker above, via email, or via GitHub pull request.
Lastly, the Capistrano mailing list is a great place to ask and answer questions, and to swap tips and tricks. There is also an IRC channel you can use: #capistrano on irc.freenode.net. (The IRC channel requires a bit of patience, since your question might not be noticed right away.)
Thanks!
Comments