Capistrano似乎没有恰当地处理角色 - 至少我是如何理解它们的。我无法使以下简单的Capfile按预期工作:
role :test1, "earzur@beta-app-01"
role :test2, "earzur@beta-app-02"
task :full_test, :roles => [:test1,:test2] do
log_test1
log_test2
end
task :log_test1, :roles => :test1 do
logger.info "TEST1 !!!"
run "echo `hostname`"
end
task :log_test2, :roles => :test2 do
logger.info "TEST2 !!!"
run "echo `hostname`"
end
当我尝试使用ROLES =:test1执行角色限制时,log_test2仍在同一主机上执行,该主机未被声明为角色的一部分:test2!这是Capistrano的预期行为吗?如果是预期的,有没有办法阻止这种情况发生?
ROLES=test1 cap full_test
* executing `full_test'
* executing `log_test1'
** TEST1 !!!
* executing "echo `hostname`"
servers: ["beta-app-01"]
[earzur@beta-app-01] executing command
** [out :: earzur@beta-app-01] ec2-*****.compute-1.amazonaws.com
command finished in 350ms
* executing `log_test2' <<<< shouldn't that be filtered ? because of :roles => :test2 ?
** TEST2 !!!
* executing "echo `hostname`"
servers: ["beta-app-01"]
[earzur@beta-app-01] executing command
** [out :: earzur@beta-app-01] ec2-*****.compute-1.amazonaws.com
command finished in 410ms
先谢谢,相关条目(http://stackoverflow.com/questions/754015/creating-a-capistrano-task-that-performs-different-tasks-based-on-role)我可以找到'don'似乎涵盖了这个问题......
答案 0 :(得分:1)
我从来不明白为什么卡皮斯特拉诺这样做,但卡皮斯特拉诺的原始维护者贾米斯巴克说it has to be the ways it is。
要解决此问题,只需创建一个 xtask 方法,并用以下方法替换所有任务调用:
# Tasks are executed even on servers which do not have the right role
# see http://www.mail-archive.com/capistrano@googlegroups.com/msg01312.html
def xtask(name, options={}, &block)
task(name, options) do
if find_servers_for_task(current_task).empty?
logger.info '... NOT on this role!'
else
block.call
end
end
end
此外,不要在随机位置定义此方法,例如在 Capfile 的开头。它必须在加载路径中存在的文件中定义(谁知道原因)。例如,在新的 helpers / roles.rb 文件中编写 xtask 方法,并将其添加到 Capfile :
# Add the current directory to the load path, it's mandatory
# to load the helpers (especially the +xtask+ method)
$:.unshift File.expand_path(File.dirname(__FILE__))
require 'helpers/roles'
如果你不这样做, cap -T 将显示用 xtask 定义的所有任务都没有任何命名空间,因此它们将覆盖每个其他如果它们在不同的名称空间中具有相同的名称。