複雑な環境下で Capistrano を書いていると様々なシチュエーションに遭遇することがあります。
例えば、特定の Role の時だけタスクを走らせたくて、それも Role A
と Role B
の場合は実行したいが、 それ以外の、例えば Role C
の時は実行したくない! といったなシチュエーションです。
世の中は複雑ですから、こうした問題に直面することもままあります。
普段我々が書いている cap タスクはこんな感じです。
namespace 'test' do
desc 'this is test'
task :foo do
on roles :A do
puts 'hello!'
end
end
end
素直に roles
に :A
を渡していますね。
この場合は Role が A
の場合のみブロック内のタスクを実行してくれます。
ふと素朴な疑問が浮かびます、複数の Role を指定して、それに該当する場合のみタスクを実行することは可能なのでしょうか?
そこでこのような感じで行けるかなーと思いつつ、Role A
と B
で実行できそうな cap タスクを、雰囲気で用意しました。
namespace 'test' do
desc 'this is test'
task :foo do
on roles [:A, :B] do
puts 'hello!'
end
end
end
config/deploy.rb
は素朴にやります。
lock "~> 3.11.0"
stage はこんな感じでローカルで完結させつつ、Role は A
を指定します。
set :deploy_to, '/mypath/sandbox'
set :sshkit_backend, SSHKit::Backend::Local
server(
'localhost',
roles: [:A]
)
test:foo
タスクを実行してみましょう。
$ bundle exec cap local test:foo
hello!
いいですね! Role A
でタスクは想定どおりに処理されているようです。
Role B
も行きましょう。
set :deploy_to, '/mypath/sandbox'
set :sshkit_backend, SSHKit::Backend::Local
server(
'localhost',
roles: [:B]
)
$ bundle exec cap local test:foo
hello!
何もかもが想定どおりです!
当然、 Role A
B
を指定しても実行されます。
set :deploy_to, '/mypath/sandbox'
set :sshkit_backend, SSHKit::Backend::Local
server(
'localhost',
roles: [:A, :B]
)
$ bundle exec cap local test:foo
hello!
そう、これこそが私の求めていたものです!
これで Role C
で実行されなければすべてが完璧に動いていると言えるでしょう。
set :deploy_to, '/mypath/sandbox'
set :sshkit_backend, SSHKit::Backend::Local
server(
'localhost',
roles: [:C]
)
$ bundle exec cap local test:foo
$
ああ! 何もかもが完璧です!
どうやら on roles
にシンボルの配列を渡しても良い感じに解釈してくれるようです!