Reputation: 1430
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?
Upvotes: 17
Views: 14672
Reputation: 150
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".
Upvotes: 1
Reputation: 11
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.
Upvotes: 1
Reputation: 53
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
Upvotes: 2
Reputation: 1147
You can also do
task :foo do
run "command", :roles => :some_role
upload "source", "destination", :roles => :another_role
end
Upvotes: 3
Reputation: 5554
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.
Upvotes: 5
Reputation: 18484
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.
Upvotes: 17