Rake & Recipes

Q: Why is there no vlad:restart?

A: It is cleaner!

We don't want to have to think about what state we're in and where. So vlad:start does a restart if necessary. Restart is just “start again” after all… That is what start does.

Q: Why is there no vlad:deploy?

A: Because everyone is a unique beautiful flower.

Everyone's deployment is different. Everyone. Unique scaling requirements. Yadda yadda yadda. So rather than supply something that nobody will use, we decided not to supply anything at all. Here is an example deploy that I stole from the web (and improved) that you may like:

desc "Full deployment cycle"
task "vlad:deploy" => %w[
  vlad:update
  vlad:migrate
  vlad:reset_session
  vlad:start
  vlad:cleanup
]

Just pop that in your config/deploy.rb, tweak it as necessary, and have at it.

Q: Why are there no before_action and after_action hooks?

A: Because we use rake!

Rake don't need no stinkin' hooks! They're too clever. Last I checked before_after_before_start worked in cap… how? why? I dunno…

To extend a task (adding something after), just define it again:

task :action1 do
  puts "one fish, two fish"
end

task :action1 do
  puts "red fish, blue fish"
end

To prepend on a task, add a dependency:

task :action2 do
  puts "red fish, blue fish"
end

task :myaction do
  puts "one fish, two fish"
end

task :action2 => :myaction

Q: How can I replace a rake task instead of just adding to it?

A: Use Rake.clear_tasks str_or_regexp

NOTE: Rake.clear_tasks was moved to Hoe so it could be used more generally.

require 'hoe/rake'

namespace :vlad do
  # Clear existing update task so that we can redefine instead of
  # adding to it.
  Rake.clear_tasks('vlad:update')

  remote_task :update, :roles => :app do
    #custom update stuff
  end
end

Q: How do I invoke another rule?

A: The easiest way is via dependencies.

task :shazam! => [:action1, :action2]

The other way is to look it up and call invoke:

task :shazam! do
  Rake::Task[:action1].invoke
  Rake::Task[:action2].invoke
end

(Or, cheat and call out to rake again: sh “rake action1”)

Using SSH

Q: Is there any way to set the ssh user?

A: Yes, using ~/.ssh/config

Host example.com
  User fluffy_bunny

OR: Alternatively, you can do this within your recipes like so:

set :user, "fluffy_bunny"
set :domain, "#{user}@example.com"

Q: Is there any way to speed up ssh connections?

A: Yes, add to your Host entry in ~/.ssh/config:

ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p
ControlPersist 1h

Q: I'm tired of typing in my password!

A: Me too!

Put a password on your key, distribute your public key to the server and then use ssh-agent.

Check out this tiny tutorial at LBL: A brief ssh-agent tutorial <upc.lbl.gov/docs/user/sshagent.html>

If you're on a mac (on tiger, not leopard), use SSHKeychain, we love it. <www.sshkeychain.org/>. If you are on leopard, you get all of this for free.

Q: How do I use Vlad with a gateway?

A: Add the following to your deploy.rb variables:

set :ssh_flags,   ['-A', mygateway, 'ssh', '-A']
set :rsync_flags, ['--rsh', 'ssh', '-A', mygateway, 'ssh']

Q: OMG subversion is stupid! It keeps asking for “Authentication Realm”

A: Yes, yes it is.

If you're seeing local checkouts work fine but they don't over ssh (even to localhost!) then ssh into that machine (yes, even localhost) and do a checkout there to a temporary directory. From then on, checkout over ssh should work fine.

% svn co https://blah/blah /tmp/happy
  ... works fine ...
% ssh localhost svn co https://blah/blah /tmp/sad
  ... asks for authentication and then hangs ...
% ssh localhost
% svn co https://blah/blah /tmp/sad-no-happy
  ... asks for authentication ...
  ... works fine ...
% ssh localhost svn co https://blah/blah /tmp/happy2
  ... works fine ...

Using Bundler

Q: OMG Bundler is stupid! It requires vlad in my app and that breaks stuff!

A: Yes, yes it is.

As far as we're concerned, that “feature” in bundler is a bug. One workaround is to tell bundler not to require vlad for you.

group :development do
  gem 'vlad', :require => false
end