I’ve been knee deep in capistrano lately, and I’ve come across in interesting behavior:
<p>Say you have the following:</p>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
role :app, "app"
role :web, "web"
task :run_on_web, :roles => :web do
do_something_on_server
end
task :run_on_app, :roles => :app do
do_something_on_server
end
task :do_something_on_server do
run "/usr/sbin/something"
end
|
<p>If you run the run_on_web task, it will execute the do_something_on_server task using all roles. This isn’t the behavior you most expected most likely. The secret to making this work is to set <span class="caps">ENV</span>[‘HOSTS’] match your the set of hosts you are interested in. After you are done you’ll want to set <span class="caps">ENV</span>[‘HOSTS’] hosts back to it’s original contents. I’ve whipped up a quick method to make this even easier.</p>
1
2
3
4
5
6
7
8
9
|
def with_role(role, &block)
original, ENV['HOSTS'] = ENV['HOSTS'], find_servers(:roles =>role).map{|d| d.host}.join(",")
begin
yield
ensure
ENV['HOSTS'] = original
end
end
|
<p>You can call it like this:</p>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
role :app, "app"
role :web, "web"
task :run_on_web, :roles => :web do
with_role :web do
do_something_on_server
end
end
task :run_on_app, :roles => :app do
with_role :app do
do_something_on_server
end
end
task :do_something_on_server do
run "/usr/sbin/something"
end
|
<p>Hopefully this helps someone.</p>
Posted in Uncategorized.
By bryanl
– May 6, 2008