Tutorial :Creating a Capistrano task that performs different tasks based on role



Question:

I'm looking for a way to call a single Capistrano task to perform different things to different roles. Is Capistrano able to do this, or do I have write a specific task for each role?


Solution:1

The standard way to do this in Capistrano:

task :whatever, :roles => [:x, :y, :z] do    x_tasks    y_tasks    z_tasks  end    task :x_tasks, :roles => :x do    #...  end    task :y_tasks, :roles => :y do    #...  end    task :z_tasks, :roles => :z do    #...  end  

So yes, you do need to write separate tasks, but you can call them from a parent task and they will filter appropriately.


Solution:2

Actually no:

% cat capfile   server 'localhost', :role2  task :task1, :roles=>:role1 do    puts 'task1'  end  task :task2 do    task1  end    % cap task2      * executing `task2'    * executing `task1'  task1  

The :roles param is passed further to run command etc but does not seem to affect whether the task is actually fired.

Sorry, didn't find the way to put a comment on comment so I've written it here.


Solution:3

You can also do

task :foo do      run "command", :roles => :some_role      upload "source", "destination", :roles => :another_role  end  


Solution:4

Use namespacing: https://github.com/leehambley/capistrano-handbook/blob/master/index.markdown#namespacing-tasks

namespace :backup do      task :default do      web      db    end      task :web, :roles => :web do      puts "Backing Up Web Server"    end      task :db, :roles => :db do      puts "Backing Up DB Server"    end  end  

these tasks show up in a cap -T as

backup:default   backup:web  backup:db  


Solution:5

There is a way, kind of. Check: http://weblog.rubyonrails.org/2006/8/30/capistrano-1-1-9-beta/ and you'll see that you can override the default roles using the ROLES environment variable.

I have a task defined as:

desc "A simple test to show we can ssh into all servers"  task :echo_hello, :roles => :test do     run "echo 'hello, world!'"  end  

The :test role is assigned to one server.

On the command line, I can run:

[james@fluffyninja bin]$ cap echo_hello ROLES=lots_of_servers  

And the task will now run on the lots_of_servers role.

I have not verified that this works inside a ruby script by updating the ENV hash, but this is a good start.


Solution:6

Only for the record, this could be a solution using Capistrano 3:

desc "Do something specific for 3 different servers with 3 different roles"  task :do_something do    on roles(:api_role), in: :sequence do      # do something in api server    end      on roles(:app_role), in: :sequence do      # do something in application server    end      on roles(:another_role), in: :sequence do      # do something in another server    end  end  

The sever definition to perform "do_something" task in a application server would be something like:

server 'application.your.domain', user: 'deploy', roles: %w{app_role}  

Then you can call the task (there are several ways to do it) and the task will execute specific instructions according to the "app_role".


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »